有没有办法用属性控制JsonResult
的JSON输出,类似于如何使用XmlElementAttribute
及其用来控制XML序列化的输出?
例如,给定以下类:
public class Foo
{
[SomeJsonSerializationAttribute("bar")]
public String Bar { get; set; }
[SomeJsonSerializationAttribute("oygevalt")]
public String Oygevalt { get; set; }
}
我想得到以下输出:
{ bar: '', oygevalt: '' }
相反:
{ Bar: '', Oygevalt: '' }
答案 0 :(得分:38)
我希望框架能比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,它可以用来完成同样的事情。
答案 1 :(得分:16)
这是我对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 );
}
}
答案 2 :(得分:5)
我知道这是一个老问题,但对于那些寻求如何避免序列化属性的人,请使用命名空间System.Web.Script.Serialization中的ScriptIgnoreAttribute。遗憾的是仍然无法控制序列化属性的名称,但有人可能会发现这有用。
public class MyClass {
[ScriptIgnoreAttribute]
public bool PropertyNotSerialized { get; set; }
public bool AnyProperty { get; set; }
}
将以Json结果输出以下结果:
{"AnyProperty ": false}
答案 3 :(得分:4)
这是使用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
设置为要序列化的每个属性。
答案 4 :(得分:1)
简单回答:DataContractJsonSerializer
应该尊重BCL的System.Runtime.Serialization命名空间中的[DataContract]
和[DataMember]
属性。
答案 5 :(得分:0)
这些答案对我很有帮助,但是比其他所有人迟了几年,我发现此代码不适用于当前框架版本。此版本可与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);
}
}
}