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
MVC3 JSON Serialization: How to control the property names?
提问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要序列化的每个属性。

