ASP.NET MVC:使用JsonResult控制属性名称的序列化
有没有一种方法可以控制具有属性的JsonResult
的JSON输出,类似于您可以如何使用XmlElementAttribute
及其brethren来控制XML序列化的输出?ASP.NET MVC:使用JsonResult控制属性名称的序列化
例如,给定下面的类:
public class Foo
{
[SomeJsonSerializationAttribute("bar")]
public String Bar { get; set; }
[SomeJsonSerializationAttribute("oygevalt")]
public String Oygevalt { get; set; }
}
我想,然后得到以下的输出:
{ bar: '', oygevalt: '' }
至于反对:
{ Bar: '', Oygevalt: '' }
我想有些东西比Jarrett建议的要多一点,所以这就是我所做的:
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()方法,添加到我的基本控制器类:
public ActionResult JsonContract(Object data)
{
return new JsonDataContractActionResult(data);
}
示例用法:
public ActionResult Update(String id, [Bind(Exclude="Id")] Advertiser advertiser)
{
Int32 advertiserId;
if (Int32.TryParse(id, out advertiserId))
{
// update
}
else
{
// insert
}
return JsonContract(advertiser);
}
注意:如果您正在寻找比JsonDataContractSerializer更高性能的东西,那么您可以使用JSON.NET来做同样的事情。虽然JSON.NET似乎没有使用DataMemberAttribute,但它有自己的JsonPropertyAttribute,可以用来完成同样的事情。
关于MVC的真棒部分是这些东西是多么容易写。你可以很快把一些非常复杂的解决方案放在一起! – 2009-08-20 00:24:03
事实确实如此!我不打算回头看WebForms。 – 2009-08-20 01:27:43
非常好的解决方案!如果从'JsonResult'继承而不是''ActionResult''基类,'JsonDataContractActionResult'类可以进一步简化 - 那么您只需要重写'ExecuteResult'方法! – 2011-03-03 15:52:46
简单回答:DataContractJsonSerializer
应该尊重BCL的System.Runtime.Serialization命名空间中的[DataContract]
和[DataMember]
属性。
对于那些不知情的人来说,Nate表达了MVC的-desired-行为,而不是今天MVC的实际行为。从MVC2开始,MVC使用JavaScriptSerializer,它不支持WCF DataContract序列化器支持的DataMember属性。今天需要一个自定义的ActionResult来使MVC使用DataContract/DataMember属性。 – Todd 2010-12-08 23:15:38
下面是我对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);
}
}
+1 - 尽我所知,DataContractJsonSerializer仍然不是直接受支持的MVC 4,所以这是一个优雅的解决方案。 – 2012-08-06 04:00:34
我知道这是一个老问题,但对于那些寻找只是如何避免被命名空间中的System.Web.Script.Serialization系列化使用ScriptIgnoreAttribute性能。遗憾的是仍然无法控制序列化属性的名称,但有人可能会发现这个有用的。
public class MyClass {
[ScriptIgnoreAttribute]
public bool PropertyNotSerialized { get; set; }
public bool AnyProperty { get; set; }
}
威尔输出作为JSON结果如下:
{"AnyProperty ": false}
我可以证实这一点。该名称空间位于System.Web.Extensions程序集中。 – 2013-07-29 16:10:45
完美... Tanx很多,它工作正常... – 2015-01-26 13:45:52
这是使用NewtonSoft的Json该溶液中。NET(性能) 我已经找到了解决方案的一部分here和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();
}
}
所以,在我的控制,我可以做到这一点
return new JsonNetResult(result);
在我的模型,我现在可以有:
[JsonProperty(PropertyName = "n")]
public string Name { get; set; }
请注意,现在您必须将JsonPropertyAttribute
设置为您要序列化的每个属性。
谢谢万元 – 2017-02-21 09:53:50
检查出新发布的Sierra:http://kohari.org/2009/08/10/siesta-painless-rest-via-asp-net-mvc/ – 2009-08-19 22:28:29
这看起来很有前途(也很有趣!),但是我希望获得已经出炉的东西。任何方式让现有的序列化器尊重DataContract属性? – 2009-08-19 22:34:52