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:
Application_Start
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter); GlobalConfiguration.Configuration.Formatters.Add(new CustomJsonMediaTypeFormatter());
我的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); } } }); } }
最后,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); } } }