如何在JSON.NET子为ASP.NET MVC控制器模型绑定? [英] How do I sub in JSON.NET as model binder for ASP.NET MVC controllers?

查看:88
本文介绍了如何在JSON.NET子为ASP.NET MVC控制器模型绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已经由ASP.NET的Web API团队决定使用JSON.NET库模型绑定JSON数据。然而,正常的MVC控制器仍然使用劣质JsonDataContractSerializer。这会导致问题进行分析日期,并导致我大为头痛。

有关参考见本:结果
<一href=\"http://www.devcurry.com/2013/04/json-dates-are-different-in-aspnet-mvc.html\">http://www.devcurry.com/2013/04/json-dates-are-different-in-aspnet-mvc.html

作者选择来解决问题,在客户端上的淘汰赛层。不过,我想preFER通过使用MVC控制器相同JSON.NET模型绑定中的Web API控制器解决这个问题。

我如何替换一个不同的JSON模型绑定到ASP.NET MVC?具体地,JSON.NET库。利用网络API相同型号的粘结剂将是理想的,如果可能的。


解决方案

我已经这样做了,而且高度定制的Json.NET是做序列化,方法是:

替换的global.asax.cs默认格式,的Application_Start

<$p$p><$c$c>GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
GlobalConfiguration.Configuration.Formatters.Add(新CustomJsonMediaTypeFormatter());

和我CustomJsonMediaTypeFormatter是:

 公共静态类CustomJsonSettings
{
    私有静态JsonSerializerSettings _settings;    公共静态JsonSerializerSettings实例
    {
        得到
        {
            如果(_settings == NULL)
            {
                VAR设置=新JsonSerializerSettings();                //必须转换时间从客户端(总是UTC)来到当地的 - 需要这两个部分:
                settings.Converters.Add(新IsoDateTimeConverter {DateTimeStyles = System.Globalization.DateTimeStyles.AssumeUniversal}); //关键部分1
                settings.DateTimeZoneHandling = DateTimeZoneHandling.Local; //关键部分2                //跳过循环引用
                settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;                //处理特殊情况的JSON(自引用循环等)
                settings.ContractResolver =新CustomJsonResolver();                _settings =设置;
            }            返回_settings;
        }
    }
}公共类CustomJsonMediaTypeFormatter:MediaTypeFormatter
{
    公共JsonSerializerSettings _jsonSerializerSettings;    公共CustomJsonMediaTypeFormatter()
    {
        _jsonSerializerSettings = CustomJsonSettings.Instance;        //填写我们支持的MediaType和编码
        SupportedMediaTypes.Add(新MediaTypeHeaderValue(应用/ JSON));
        SupportedEncodings.Add(新UTF8Encoding(假,真));
    }    公众覆盖布尔CanReadType(类型类型)
    {
        返回true;
    }    公众覆盖布尔CanWriteType(类型类型)
    {
        返回true;
    }    公共覆盖任务&LT;对象&gt; ReadFromStreamAsync(类型类型,流流,HttpContent内容,IFormatterLogger formatterLogger)
    {
        //创建一个序列化
        JsonSerializer串行= JsonSerializer.Create(_jsonSerializerSettings);        //创建任务阅读内容
        返回Task.Factory.StartNew(()=&GT;
        {
            使用(StreamReader的StreamReader的=新的StreamReader(流SupportedEncodings.First()))
            {
                使用(JsonTextReader jsonTextReader =新JsonTextReader(StreamReader的))
                {
                    返回serializer.Deserialize(jsonTextReader,类型);
                }
            }
        });
    }    公众覆盖任务WriteToStreamAsync(类型类型,对象的值,涧流,HttpContent内容,TransportContext transportContext)
    {
        //创建一个序列化
        JsonSerializer串行= JsonSerializer.Create(_jsonSerializerSettings);        //创建任务写连载内容
        返回Task.Factory.StartNew(()=&GT;
        {
            使用(的StreamWriter的StreamWriter =新的StreamWriter(流SupportedEncodings.First()))
            {
                使用(JsonTextWriter jsonTextWriter =新JsonTextWriter(的StreamWriter))
                {
                    serializer.Serialize(jsonTextWriter,值);
                }
            }
        });
    }
}

最后,CustomJsonResolver:

 公共类CustomJsonResolver:DefaultContractResolver
{
    保护覆盖的IList&LT; JsonProperty&GT; CreateProperties(类型类型,Newtonsoft.Json.MemberSerialization memberSerialization)
    {
        VAR列表= base.CreateProperties(类型,memberSerialization);        //自定义的东西我的应用程序
        如果(类型== typeof运算(富))
        {
            RemoveProperty(名单酒吧);
            RemoveProperty(名单,条2);
        }        返回列表;
    }    私人无效RemoveProperty(IList的&LT; JsonProperty&GT;列表中,字符串propertyName的)
    {
        VAR RMC = list.FirstOrDefault(X =&GT; x.PropertyName == propertyName的);        如果(RMC!= NULL)
        {
            list.Remove(RMC);
        }
    }
}

It has been decided by the ASP.NET Web API team to use the JSON.NET library for model binding JSON data. However, "normal" MVC controllers still use the inferior JsonDataContractSerializer. This causes issues with parsing dates, and is causing me much headache.

See this for reference:
http://www.devcurry.com/2013/04/json-dates-are-different-in-aspnet-mvc.html

The author chooses to solve the issue in the Knockout layer on the client. But I would prefer to solve this by using the same JSON.NET model binder in MVC controllers as in Web API controllers.

How do I substitute a different JSON model binder into ASP.NET MVC? Specifically, the JSON.NET library. Using the same model binder from Web API would be ideal if possible.

解决方案

I have done this, and also heavily customized the serialization that Json.NET is doing, by:

Replace the default formatter in global.asax.cs, Application_Start:

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
GlobalConfiguration.Configuration.Formatters.Add(new CustomJsonMediaTypeFormatter());

And my CustomJsonMediaTypeFormatter is:

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);
                }
            }
        });
    }
}

And finally, the 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);
        }
    }
}

这篇关于如何在JSON.NET子为ASP.NET MVC控制器模型绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆