ASP.NET MVC 3 控制器 .Json 方法序列化不查看 DataMember Name 属性

Posted

技术标签:

【中文标题】ASP.NET MVC 3 控制器 .Json 方法序列化不查看 DataMember Name 属性【英文标题】:ASP.NET MVC 3 controller .Json method serialization doesn't look at DataMember Name attribure 【发布时间】:2011-05-16 17:13:04 【问题描述】:

在我的课堂上我有:

[DataMember(Name = "jsonMemberName", EmitDefaultValue = false, 
    IsRequired = false)]
public List<string> Member  get; set; 

通过控制器的 Json(obj) 传递对象后返回 System.Web.Mvc.JsonResult: 我有序列化的 json: Member:... 但没有 jsonMemberName:...,所以它没有'不要看 DataMember(Name = "jsonMemberName")。

如果我使用 System.Runtime.Serialization.Json 中的序列化,一切都可以正常工作。

有什么问题?

【问题讨论】:

ASP.NET MVC: Controlling serialization of property names with JsonResult 的可能重复项 【参考方案1】:

您从控制器操作(使用return Json(...))返回的JsonResult 操作在内部依赖于javascriptSerializer 类。此类不考虑模型上的任何 DataMember 属性。

您可以编写一个自定义 ActionResult,它使用 System.Runtime.Serialization.Json 命名空间中的序列化程序。

例如:

public class MyJsonResult : JsonResult

    public override void ExecuteResult(ControllerContext context)
    
        var response = context.HttpContext.Response;
        if (!string.IsNullOrEmpty(ContentType))
        
            response.ContentType = ContentType;
        
        else
        
            response.ContentType = "application/json";
        
        if (ContentEncoding != null)
        
            response.ContentEncoding = this.ContentEncoding;
        
        if (Data != null)
        
            var serializer = new DataContractJsonSerializer(Data.GetType());
            serializer.WriteObject(response.OutputStream, Data);
        
    

然后在你的控制器动作中:

public ActionResult Foo()

    var model = ...
    return new MyJsonResult  Data = model ;

【讨论】:

那么有解决办法吗?不重命名班级成员,因为它很丑。 @WHITECOLOR,当然,写一个自定义的ActionResult 在 MVC 中投票支持更改请求或类似内容会很好。如果默认 JSONResult 使用 DataContractJsonSerializer 会有什么缺点。它会破坏什么吗?【参考方案2】:

System.Web.Mvc.JsonResult 使用旧的 JavaScriptSerializer 类,它对 DataAnnotiations 程序集一无所知。您需要改用DataContractJsonSerializer。

如果你愿意,你可以在 JsonResult 上使用它:

public class DataContractJsonResult : JsonResult

    public DataContractJsonResult(object data)
    
        Data = data;
    

    public DataContractJsonResult()
    
    

    public override void ExecuteResult(ControllerContext context)
    
        if (context == null)
        
            throw new ArgumentNullException("context");
        
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
            String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        

        HttpResponseBase response = context.HttpContext.Response;

        if (!string.IsNullOrEmpty(ContentType))
        
            response.ContentType = ContentType;
        
        else
        
            response.ContentType = "application/json";
        
        if (ContentEncoding != null)
        
            response.ContentEncoding = ContentEncoding;
        
        if (Data != null)
        
            var serializer = new DataContractJsonSerializer(Data.GetType());
            var ms = new MemoryStream();
            serializer.WriteObject(ms, Data);
            string json = Encoding.UTF8.GetString(ms.ToArray());
            response.Write(json);
        
    

(我参考了 ASP.NET MVC 源代码来创建它。不确定我是否必须以某种方式归功于它。好吧,除了这个之外,已经有更多了。:))

您还可以将其添加到控制器继承的基类中:

protected JsonResult DataContractJson(object data)

    return new DataContractJsonResult(data);

【讨论】:

以上是关于ASP.NET MVC 3 控制器 .Json 方法序列化不查看 DataMember Name 属性的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET 中使用 WebAPI 或 MVC 返回 JSON

如何在 ASP.NET MVC 3 razor ViewStart 文件中指定不同的布局?

返回 JSON 或部分 html 的 ASP.NET MVC 控制器操作

如何在 ASP.NET MVC/Web 控制器中返回 JSON?

无法让 ASP.NET MVC 6 控制器返回 JSON

将 JSON 从视图发送到控制器 ASP.NET MVC 会给出空值