【问题标题】:ActionFilterAttribute.OnActionExecuted prefixes properties in json body with underscoreActionFilterAttribute.OnActionExecuted 为 json 正文中的属性添加下划线前缀
【发布时间】:2016-04-23 15:44:21
【问题描述】:

在我的 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"}]

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

【问题讨论】:

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


    【解决方案1】:

    似乎不知道问题出在什么时候,会导致你问错问题。当然,如果您知道正确的问题,那么您可能会知道答案。

    在我的例子中,问题不在于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
            }
        })
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-17
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2011-09-03
      • 2017-07-26
      相关资源
      最近更新 更多