在C#中使用泛型的类,用于未知的异常类型。
在C#中使用泛型的类,用于未知的异常类型。
在我的应用程序中,我有一个异常过滤器Web API
,它应该捕获任何异常并将其传输到客户端,使用一个响应封装类。
我的目标是使异常传输带有正确的类型,这样客户端就可以重构并重新抛出它。
以下是异常捕获器的代码:
public override void OnException(HttpActionExecutedContext actionExecutedContext) { HttpStatusCode OutputHttpCode = HttpStatusCode.InternalServerError; var exceptionType = actionExecutedContext.Exception.GetType(); if (exceptionType == typeof(InvalidIDException)) { OutputHttpCode = HttpStatusCode.Unauthorized; } //这种获取类型的方式对我也没有用 //var exceptionType = typeof(RestErrorResponse<>).MakeGenericType(actionExecutedContext.Exception.GetType()); actionExecutedContext.Response = new HttpResponseMessage() { Content = new StringContent(JsonConvert.SerializeObject( //这里将无法编译,显示t是一个变量但被用作类型 //如果我使用通用的“Exception”,一切都正常工作, //但它将被解释为通用异常在客户端,并且 //如果我直接重新抛出它,可能无法正确处理 new RestErrorResponse() //Exception将编译 { Content = null, Status = RestStatus.Error, Exception = actionExecutedContext.Exception } ), System.Text.Encoding.UTF8, "application/json"), StatusCode = OutputHttpCode }; base.OnException(actionExecutedContext); }
这是一个带有通用类型的类,我想将我的异常放入其中:
public class RestErrorResponse:RestResponse
如果我在我的“RestErrorResponse”类中使用一个通用异常,将创建以下JSON:
{
"Exception": {
"ClassName": "InvalidLoginException",
"Message": "Invalid User Name",
"Data": {},
"InnerException": null,
"HelpURL": null,
"StackTraceString": "....",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": "....",
"HResult": -2147024809,
"Source": "DB",
"WatsonBuckets": null,
"ParamName": null
},
"Status": {
"Verbal": "Error",
"Code": 1074
},
"Content": null
}
我的目标是获得:
{
"InvalidLoginException": {
"ClassName": "InvalidLoginException",
"Message": "Invalid User Name",
"Data": {},
"InnerException": null,
"HelpURL": null,
"StackTraceString": "....",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": "....",
"HResult": -2147024809,
"Source": "DB",
"WatsonBuckets": null,
"ParamName": null
},
"Status": {
"Verbal": "Error",
"Code": 1074
},
"Content": null
}
在C#中使用泛型的原因是因为无法确定异常类型。如果可以更改RestErrorResponse类,则可以将其修改为非泛型类,并在其中添加一个名为Exception的属性。这样,可以直接实例化RestErrorResponse类,并将异常对象赋值给Exception属性。
如果无法更改RestErrorResponse类,则需要使用反射来创建RestErrorResponse实例。首先,使用typeof关键字获取RestErrorResponse的类型,然后使用MakeGenericType方法将其转换为泛型类型。接下来,使用Activator.CreateInstance方法创建RestErrorResponse实例,并将相关属性赋值。
但是,如果只是将异常对象的类型更改为Exception,那么在反序列化时将无法将其重新抛出为原始的InvalidLoginException类型。如果有关于反序列化的问题,请提出另一个问题。在这里提供了一个链接,可以解决有关JObject反序列化的问题。
需要注意的是,序列化和反序列化异常可能存在一些问题,特别是在使用第三方库时。因此,在进行异常处理时应该谨慎对待。