Rat*_*eek 12 asp.net-mvc json model-binding
ASP.NET Web API团队已决定将JSON.NET库用于模型绑定JSON数据.但是,"普通"MVC控制器仍然使用劣质JsonDataContractSerializer.这会导致解析日期的问题,并且让我很头疼.
请参阅此参考:http:
//www.devcurry.com/2013/04/json-dates-are-different-in-aspnet-mvc.html
作者选择在客户端的Knockout层中解决问题.但我更愿意通过在MVC控制器中使用与Web API控制器中相同的JSON.NET模型绑定器来解决此问题.
如何将不同的JSON模型绑定器替换为ASP.NET MVC?具体来说,就是JSON.NET库.如果可能,使用Web API中的相同模型绑定器将是理想的.
我已经完成了这个,并且还通过以下方式大量定制了Json.NET正在进行的序列化:
替换global.asax.cs中的默认格式化程序,Application_Start:
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
GlobalConfiguration.Configuration.Formatters.Add(new CustomJsonMediaTypeFormatter());
Run Code Online (Sandbox Code Playgroud)
我的CustomJsonMediaTypeFormatter是:
public static class CustomJsonSettings
{
private static JsonSerializerSettings _settings;
public static JsonSerializerSettings Instance
{
get
{
if (_settings == null)
{
var settings = new JsonSerializerSettings();
// Must convert times coming from the client (always in UTC) to local - need both these parts:
settings.Converters.Add(new IsoDateTimeConverter { DateTimeStyles = System.Globalization.DateTimeStyles.AssumeUniversal }); // Critical part 1
settings.DateTimeZoneHandling = DateTimeZoneHandling.Local; // Critical part 2
// Skip circular references
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
// Handle special cases in json (self-referencing loops, etc)
settings.ContractResolver = new CustomJsonResolver();
_settings = settings;
}
return _settings;
}
}
}
public class CustomJsonMediaTypeFormatter : MediaTypeFormatter
{
public JsonSerializerSettings _jsonSerializerSettings;
public CustomJsonMediaTypeFormatter()
{
_jsonSerializerSettings = CustomJsonSettings.Instance;
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (StreamReader streamReader = new StreamReader(stream, SupportedEncodings.First()))
{
using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (StreamWriter streamWriter = new StreamWriter(stream, SupportedEncodings.First()))
{
using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter))
{
serializer.Serialize(jsonTextWriter, value);
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
最后,CustomJsonResolver:
public class CustomJsonResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var list = base.CreateProperties(type, memberSerialization);
// Custom stuff for my app
if (type == typeof(Foo))
{
RemoveProperty(list, "Bar");
RemoveProperty(list, "Bar2");
}
return list;
}
private void RemoveProperty(IList<JsonProperty> list, string propertyName)
{
var rmc = list.FirstOrDefault(x => x.PropertyName == propertyName);
if (rmc != null)
{
list.Remove(rmc);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4981 次 |
| 最近记录: |