ActionFilterAttribute.OnActionExecuted为带有下划线的json主体中的属性添加前缀

时间:2016-04-23 15:44:22

标签: .net asp.net-web-api

在我的Web Api项目中,我试图将业务逻辑分离到可能在其他应用程序(例如WCF服务)中使用的单独模块中。

出于这个原因,为了创建一个给出异常的常用方法,我创建了一个继承自异常的类,并且我传递了一个包含我的业务错误的对象。

因此应用程序应该处理从业务层抛出的异常。

在这个特定的情况下,我创建了一个全局的过滤器,因此所有控制器的动作都有这个过滤器。过滤器代码为:

Public Class MyCustomActionFilterAttribute
    Inherits System.Web.Http.Filters.ActionFilterAttribute

    Public Overrides Sub OnActionExecuting(actionContext As Http.Controllers.HttpActionContext)
        If Not actionContext.ModelState.IsValid Then

            Dim Errors As New List(Of ErrorResult)

            For Each lError In actionContext.ModelState.Values.SelectMany(Function(x) x.Errors) 
                If Not String.IsNullOrWhiteSpace(lError.ErrorMessage) Then
                    Errors.Add(New ErrorResult(lError.ErrorMessage))
                Else
                    Errors.Add(New ErrorResult With {.Code = ErrorCode.GenericValidationError, .Description = lError.Exception.Message})
                End If
            Next

            actionContext.Response = New HttpResponseMessage(System.Net.HttpStatusCode.BadRequest) With {
               .Content = New ObjectContent(Of List(Of ErrorResult)) _
                   (Errors, New System.Net.Http.Formatting.JsonMediaTypeFormatter)
           }
        End If
    End Sub

    Public Overrides Sub OnActionExecuted(actionExecutedContext As Http.Filters.HttpActionExecutedContext)
        MyBase.OnActionExecuted(actionExecutedContext)
        If Not actionExecutedContext.Exception Is Nothing Then
            Dim Errors As New List(Of ErrorResult)
            If actionExecutedContext.Exception.GetType Is GetType(MyCustomException) Then
                Errors.Add(CType(actionExecutedContext.Exception, MyCustomException).ErrorResult)
            Else
                Errors.Add(New ErrorResult With {.Code = ErrorCode.GenericError, .Description = actionExecutedContext.Exception.Message})
            End If
            actionExecutedContext.Response = New HttpResponseMessage(System.Net.HttpStatusCode.BadRequest) With {
               .Content = New ObjectContent(Of List(Of ErrorResult)) _
                   (Errors, New System.Net.Http.Formatting.JsonMediaTypeFormatter)
           }
        End If
    End Sub

End Class

有了上述内容,我想实现一种常见的异常呈现方式。所以我有一个班级ErrorResult,它只有两个属性CodeDescription

当我遇到ModelState的问题时,我会得到一个很好的json数组,如下所示:

[{Code: -1001, Description: "Error Description"}]

我想看到的是什么。这是由OnActionExecuting方法创建的。

我的问题是,当OnActionExecuted方法中存在错误时,我得到的回复是:

[{_Code: -1001, _Description: "Error Description"}]

为什么我会得到这些下划线,我怎么能摆脱它们?

1 个答案:

答案 0 :(得分:0)

似乎不知道问题何时出现,导致你提出错误的问题。当然,如果你知道正确的问题,那么你可能会知道答案。

在我的情况下,问题不在OnActionExecuted方法中,而是在使用Serializable属性装饰类时序列化json的方式。

在我的问题MyCustomException中发布的代码中,类被装饰为Serializable,似乎JsonMediaTypeFormatter的行为方式(asp-net-web-api-is-serializing-with-underscore)。

所以我所要做的就是定义Json.Net DefaultContractResolver

actionExecutedContext.Response = New HttpResponseMessage(System.Net.HttpStatusCode.BadRequest) With {
    .Content = New ObjectContent(Of List(Of ErrorResult)) _
        (Errors, New System.Net.Http.Formatting.JsonMediaTypeFormatter With
    {
        .SerializerSettings = New Newtonsoft.Json.JsonSerializerSettings With
        {
            .NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
            .ContractResolver = New DefaultContractResolver
        }
    })
}