ASP.NET MVC:使用 JsonResult 控制属性名称的序列化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1302946/
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
ASP.NET MVC: Controlling serialization of property names with JsonResult
提问by Daniel Schaffer
Is there a way to control the JSON output of JsonResultwith attributes, similar to how you can use XmlElementAttributeand its bretheren to control the output of XML serialization?
有没有办法控制JsonResult带有属性的JSON输出,类似于您如何使用XmlElementAttribute及其兄弟来控制XML序列化的输出?
For example, given the following class:
例如,给定以下类:
public class Foo
{
[SomeJsonSerializationAttribute("bar")]
public String Bar { get; set; }
[SomeJsonSerializationAttribute("oygevalt")]
public String Oygevalt { get; set; }
}
I'd like to then get the following output:
我想然后得到以下输出:
{ bar: '', oygevalt: '' }
As opposed to:
与之相反:
{ Bar: '', Oygevalt: '' }
回答by Daniel Schaffer
I wanted something a bit more baked into the framework than what Jarrett suggested, so here's what I did:
我想要一些比 Jarrett 建议的更深入框架的东西,所以这就是我所做的:
JsonDataContractActionResult:
JsonDataContractActionResult:
public class JsonDataContractActionResult : ActionResult
{
public JsonDataContractActionResult(Object data)
{
this.Data = data;
}
public Object Data { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
var serializer = new DataContractJsonSerializer(this.Data.GetType());
String output = String.Empty;
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, this.Data);
output = Encoding.Default.GetString(ms.ToArray());
}
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.Write(output);
}
}
JsonContract() method, added to my base controller class:
JsonContract() 方法,添加到我的基本控制器类中:
public ActionResult JsonContract(Object data)
{
return new JsonDataContractActionResult(data);
}
Sample Usage:
示例用法:
public ActionResult Update(String id, [Bind(Exclude="Id")] Advertiser advertiser)
{
Int32 advertiserId;
if (Int32.TryParse(id, out advertiserId))
{
// update
}
else
{
// insert
}
return JsonContract(advertiser);
}
Note:If you're looking for something more performant than JsonDataContractSerializer, you can do the same thing using JSON.NET instead. While JSON.NET doesn't appear to utilize DataMemberAttribute, it does have its own JsonPropertyAttribute which can be used to accomplish the same thing.
注意:如果您正在寻找比 JsonDataContractSerializer 性能更高的东西,您可以使用 JSON.NET 来做同样的事情。虽然 JSON.NET 似乎没有使用 DataMemberAttribute,但它确实有自己的 JsonPropertyAttribute 可用于完成相同的事情。
回答by Charlie Kilian
Here's my implementation of Daniel Schaffer's answer, with the suggested improvements by Justin Rusbatch and Daniel incorporated.
这是我对 Daniel Schaffer 的回答的实现,其中包含了 Justin Rusbatch 和 Daniel 提出的改进建议。
using System;
using System.Runtime.Serialization.Json;
using System.Web.Mvc;
public class JsonDataContractActionResult : JsonResult
{
public JsonDataContractActionResult( Object data )
{
this.Data = data;
}
public override void ExecuteResult( ControllerContext context )
{
var serializer = new DataContractJsonSerializer( this.Data.GetType() );
context.HttpContext.Response.ContentType = "application/json";
serializer.WriteObject( context.HttpContext.Response.OutputStream,
this.Data );
}
}
回答by Danny Pérez
I know this is an old question but for those looking for just how to avoid properties from being serialized use the ScriptIgnoreAttributein the namespace System.Web.Script.Serialization. Sadly still can't controll the name of the serialized properties but somebody might find this helpfull.
我知道这是一个老问题,但对于那些正在寻找如何避免属性被序列化的人,请使用命名空间 System.Web.Script.Serialization 中的ScriptIgnoreAttribute。遗憾的是仍然无法控制序列化属性的名称,但有人可能会发现这很有帮助。
public class MyClass {
[ScriptIgnoreAttribute]
public bool PropertyNotSerialized { get; set; }
public bool AnyProperty { get; set; }
}
Will output as Json result the following:
将输出为 Json 结果如下:
{"AnyProperty ": false}
回答by Daniel
This is the solution to use NewtonSoft Json.Net (for performance) I've found part of the solution hereand on SO
这是使用 NewtonSoft Json.Net(为了性能)的解决方案,我在这里和 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要序列化的每个属性。
回答by Nate Kohari
Easy answer: the DataContractJsonSerializershould respect the [DataContract]and [DataMember]attributes in the System.Runtime.Serialization namespace of the BCL.
简单回答:DataContractJsonSerializer应该尊重BCL 的 System.Runtime.Serialization 命名空间中的[DataContract]和[DataMember]属性。

