在C#中使用泛型的类,用于未知的异常类型。

20 浏览
0 Comments

在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 {
    public E myException { get; set; }
}

如果我在我的“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

}

0
0 Comments

在C#中使用泛型的原因是因为无法确定异常类型。如果可以更改RestErrorResponse类,则可以将其修改为非泛型类,并在其中添加一个名为Exception的属性。这样,可以直接实例化RestErrorResponse类,并将异常对象赋值给Exception属性。

如果无法更改RestErrorResponse类,则需要使用反射来创建RestErrorResponse实例。首先,使用typeof关键字获取RestErrorResponse的类型,然后使用MakeGenericType方法将其转换为泛型类型。接下来,使用Activator.CreateInstance方法创建RestErrorResponse实例,并将相关属性赋值。

但是,如果只是将异常对象的类型更改为Exception,那么在反序列化时将无法将其重新抛出为原始的InvalidLoginException类型。如果有关于反序列化的问题,请提出另一个问题。在这里提供了一个链接,可以解决有关JObject反序列化的问题。

需要注意的是,序列化和反序列化异常可能存在一些问题,特别是在使用第三方库时。因此,在进行异常处理时应该谨慎对待。

0