MVC3 JSON 序列化:如何控制属性名称?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7260924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:58:29  来源:igfitidea点击:

MVC3 JSON Serialization: How to control the property names?

jsonasp.net-mvc-3serializationproperties

提问by xsl

I want to serialize a simple object to JSON:

我想将一个简单的对象序列化为 JSON:

public class JsonTreeNode
{
    [DataMember(Name = "title")]
    public string Title { get; set; }

    [DataMember(Name = "isFolder")]
    public bool IsFolder { get; set; }

    [DataMember(Name = "key")]
    public string Key { get; set; }

    [DataMember(Name = "children")]
    public IEnumerable<JsonTreeNode> Children { get; set; }

    [DataMember(Name = "select")]
    public bool SelectedOnInit { get; set; }
}

But whenever I do it:

但是每当我这样做时:

return Json(tree, JsonRequestBehavior.AllowGet);

The property names are not as specified in the [DataMember]section, but similar to the ones defined directly in the class e.g. in the case of SelectOnInitit is not selectbut SelectOnInit.

属性名称不作为指定[DataMember]部分,但类似于那些直接定义在类如的情况下SelectOnInit它不是select,但SelectOnInit

What am I doing wrong?

我究竟做错了什么?

回答by xsl

I solved the problem by using the technique provided in the answer in this question:

我通过使用这个问题的答案中提供的技术解决了这个问题:

ASP.NET MVC: Controlling serialization of property names with JsonResult

ASP.NET MVC:使用 JsonResult 控制属性名称的序列化

Here is the class I made:

这是我制作的课程:

/// <summary>
/// Similiar to <see cref="JsonResult"/>, with
/// the exception that the <see cref="DataContract"/> attributes are
/// respected.
/// </summary>
/// <remarks>
/// Based on the excellent stackoverflow answer:
/// https://stackoverflow.com/a/263416/1039947
/// </remarks>
public class JsonDataContractActionResult : ActionResult
{
    /// <summary>
    /// Initializes a new instance of the class.
    /// </summary>
    /// <param name="data">Data to parse.</param>
    public JsonDataContractActionResult(Object data)
    {
        Data = data;
    }

    /// <summary>
    /// Gets or sets the data.
    /// </summary>
    public Object Data { get; private set; }

    /// <summary>
    /// Enables processing of the result of an action method by a 
    /// custom type that inherits from the ActionResult class. 
    /// </summary>
    /// <param name="context">The controller context.</param>
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var serializer = new DataContractJsonSerializer(Data.GetType());

        string output;
        using (var ms = new MemoryStream())
        {
            serializer.WriteObject(ms, Data);
            output = Encoding.UTF8.GetString(ms.ToArray());
        }

        context.HttpContext.Response.ContentType = "application/json";
        context.HttpContext.Response.Write(output);
    }
}

Usage:

用法:

    public ActionResult TestFunction()
    {
        var testObject = new TestClass();
        return new JsonDataContractActionResult(testObject);
    }

I also had to modify the initial class:

我还必须修改初始类:

// -- The DataContract property was added --
[DataContract]
public class JsonTreeNode
{
    [DataMember(Name = "title")]
    public string Title { get; set; }

    [DataMember(Name = "isFolder")]
    public bool IsFolder { get; set; }

    [DataMember(Name = "key")]
    public string Key { get; set; }

    [DataMember(Name = "children")]
    public IEnumerable<JsonTreeNode> Children { get; set; }

    [DataMember(Name = "select")]
    public bool SelectedOnInit { get; set; }
}

回答by Daniel

This is a solution that uses newtonsoft Json.net (for performance concerned)

这是一个使用 newtonsoft Json.net 的解决方案(出于性能考虑)

I've found part of the solution hereand on SO

我在这里和 SO 上找到了部分解决方案

public class JsonNetResult : ActionResult
    {
        public Encoding ContentEncoding { get; set; }
        public string ContentType { get; set; }
        public object Data { get; set; }

        public JsonSerializerSettings SerializerSettings { get; set; }
        public Formatting Formatting { get; set; }

        public JsonNetResult(object data, Formatting formatting)
            : this(data)
        {
            Formatting = formatting;
        }

        public JsonNetResult(object data):this()
        {
            Data = data;
        }

        public JsonNetResult()
        {
            Formatting = Formatting.None;
            SerializerSettings = new JsonSerializerSettings();
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            var response = context.HttpContext.Response;
            response.ContentType = !string.IsNullOrEmpty(ContentType)
              ? ContentType
              : "application/json";
            if (ContentEncoding != null)
                response.ContentEncoding = ContentEncoding;

            if (Data == null) return;

            var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };
            var serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Data);
            writer.Flush();
        }
    }

So that in my controller, I can do that

所以在我的控制器中,我可以做到这一点

        return new JsonNetResult(result);

In my model, I can now have:

在我的模型中,我现在可以拥有:

    [JsonProperty(PropertyName = "n")]
    public string Name { get; set; }

Note that now, you have to set the JsonPropertyAttributeto every property you want to serialize.

请注意,现在,您必须将 设置为JsonPropertyAttribute要序列化的每个属性。