Есть ли способ управлять выводом JSON в JsonResult
с помощью атрибутов, подобно тому, как вы можете использовать XmlElementAttribute
и его собратьев для управления выводом XML-сериализации?
Например, дан следующий класс:
public class Foo
{
[SomeJsonSerializationAttribute("bar")]
public String Bar { get; set; }
[SomeJsonSerializationAttribute("oygevalt")]
public String Oygevalt { get; set; }
}
Я хотел бы получить следующий результат:
{ bar: '', oygevalt: '' }
В отличие от:
{ Bar: '', Oygevalt: '' }
Я хотел, чтобы в каркас было заложено нечто большее, чем то, что предложил Джарретт, поэтому вот что у меня получилось:
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, который можно использовать для достижения того же самого.
Вот моя реализация ответа 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 );
}
}
Я знаю, это старый вопрос, но для тех, кто ищет, как избежать свойства могут быть сериализованы с помощью кнопок ScriptIgnoreAttribute в пространстве имен System.Веб.Сценарий.Сериализации. К сожалению, все еще могу'т контролировать имя сериализованные свойства, но кто-то может найти это полезным.
public class MyClass {
[ScriptIgnoreAttribute]
public bool PropertyNotSerialized { get; set; }
public bool AnyProperty { get; set; }
}
Будет выводить в JSON результат следующий:
{"AnyProperty ": false}
Это решение использовать NewtonSoft Json.Net (для производительности) Я'вэ нашел часть решения здесь а так
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]
в пространстве имен System.Runtime.Serialization в BCL.