MVC3 JSON Serialization: How to control the property names?

后端 未结 2 605
天涯浪人
天涯浪人 2020-12-10 03:41

I want to serialize a simple object to JSON:

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

    [DataM         


        
相关标签:
2条回答
  • 2020-12-10 04:12

    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

    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; }
    }
    
    0 讨论(0)
  • 2020-12-10 04:28

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

    I've found part of the solution here and on 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 JsonPropertyAttribute to every property you want to serialize.

    0 讨论(0)
提交回复
热议问题