如何将JSON.NET作为ASP.NET MVC控制器的模型绑定器?

 mhq3022863 发布于 2023-02-05 12:58

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中的相同模型绑定器将是理想的.

1 个回答
  • 我已经完成了这个,并且还通过以下方式大量定制了Json.NET正在进行的序列化:

    替换global.asax.cs中的默认格式化程序,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);
            }
        }
    }
    

    2023-02-05 13:01 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有