ASP.NET MVC:用JsonResult控制属性名的序列化。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET MVC:用JsonResult控制属性名的序列化。相关的知识,希望对你有一定的参考价值。
有什么方法可以控制 JsonResult
属性,类似于你如何使用 XmlElementAttribute
及其兄弟类来控制XML序列化的输出?
例如,给定以下类。
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);
}
示例用法:"JsonContract() "方法,添加到我的基础控制器类中
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,可以用来完成同样的事情。
这是我对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 );
}
}
我知道这是一个老问题,但对于那些正在寻找如何避免属性被序列化的人来说,可以使用 脚本IgnoreAttribute 在System.Web.Script.Serialization. 遗憾的是,仍然无法控制序列化属性的名称,但有人可能会觉得这很有帮助。
public class MyClass {
[ScriptIgnoreAttribute]
public bool PropertyNotSerialized { get; set; }
public bool AnyProperty { get; set; }
}
将输出Json结果如下。
{"AnyProperty ": false}
这是使用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();
}
}
所以,在我的控制器中,我可以做到这一点。
return new JsonNetResult(result);
在我的模型中,我现在可以有。
[JsonProperty(PropertyName = "n")]
public string Name { get; set; }
注意,现在,你必须设置 JsonPropertyAttribute
到你想序列化的每个属性。
简单的答案: DataContractJsonSerializer
应尊重 [DataContract]
和 [DataMember]
属性在BCL的System.Runtime.Serialization命名空间中。
这些答案对我很有帮助,但比大家晚几年来解决这个问题,我发现这段代码在当前的框架版本下无法使用。 这个版本适用于Newtonsoft.Json和ASP NET Core 3.1。
/*
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
*/
public class JsonDataContractActionResult : IActionResult
{
public JsonDataContractActionResult(object data)
{
this.Data = data;
}
public object Data { get; private set; }
public async Task ExecuteResultAsync(ActionContext context)
{
context.HttpContext.Response.ContentType = "application/json";
JsonSerializer serializer = new JsonSerializer();
serializer.NullValueHandling = NullValueHandling.Ignore;
using (MemoryStream ms = new MemoryStream()) {
using (StreamWriter sw = new StreamWriter(ms))
{
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, Data);
}
}
byte[] b = ms.ToArray();
await context.HttpContext.Response.Body.WriteAsync(b);
}
}
}
以上是关于ASP.NET MVC:用JsonResult控制属性名的序列化。的主要内容,如果未能解决你的问题,请参考以下文章
加载 ASP.Net MVC JSONResult jQuery DataTables
csharp C#:JsonResult替代ASP.NET MVC。
ASP.NET MVC 下自定义 JsonResult,使用 Json.NET 序列化 JSON