Asp.net mvc 带有特定JsonConverter的MVC3控制器

Asp.net mvc 带有特定JsonConverter的MVC3控制器,asp.net-mvc,json,serialization,Asp.net Mvc,Json,Serialization,以下是设置: 我有一些MVC控制器,打算由jQueryAjax请求使用。一个普通的请求看起来有点像这样: $.ajax("/Solicitor/AddSolicitorToApplication", { data: putData, type: "POST", contentType: "application/json", success: function (result) { //My success callback } }

以下是设置:

我有一些MVC控制器,打算由jQueryAjax请求使用。一个普通的请求看起来有点像这样:

$.ajax("/Solicitor/AddSolicitorToApplication", {
    data: putData,
    type: "POST", contentType: "application/json",
    success: function (result) {
       //My success callback
        }
    }
});
[HttpPost]
public ActionResult InsertLoanApplication(MortgageLoanApplicationViewModel vm)
{
   var mortgageLoanDTO = vm.MapToDTO();
   return Json(_mortgageLoanService.UpdateMortgageLoanApplication(mortgageLoanDTO),   JsonRequestBehavior.DenyGet);
}
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new GrizlyStringConverter());
我的控制器如下所示:

$.ajax("/Solicitor/AddSolicitorToApplication", {
    data: putData,
    type: "POST", contentType: "application/json",
    success: function (result) {
       //My success callback
        }
    }
});
[HttpPost]
public ActionResult InsertLoanApplication(MortgageLoanApplicationViewModel vm)
{
   var mortgageLoanDTO = vm.MapToDTO();
   return Json(_mortgageLoanService.UpdateMortgageLoanApplication(mortgageLoanDTO),   JsonRequestBehavior.DenyGet);
}
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new GrizlyStringConverter());
这对于大多数传递给控制器的对象都非常有效,除了在这种特定情况下,需要以特定的方式反序列化所传递对象的属性之一

我添加了一个JsonConverter,我以前在MVC4WebAPI中使用过它,但在本例中,我需要将它应用于常规mvc控制器

我尝试在我的global.asax中注册JsonConverter,如下所示:

$.ajax("/Solicitor/AddSolicitorToApplication", {
    data: putData,
    type: "POST", contentType: "application/json",
    success: function (result) {
       //My success callback
        }
    }
});
[HttpPost]
public ActionResult InsertLoanApplication(MortgageLoanApplicationViewModel vm)
{
   var mortgageLoanDTO = vm.MapToDTO();
   return Json(_mortgageLoanService.UpdateMortgageLoanApplication(mortgageLoanDTO),   JsonRequestBehavior.DenyGet);
}
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new GrizlyStringConverter());

但到目前为止,我们还无法对对象进行反序列化

如果要在将Json请求绑定到视图模型时使用
Json.NET
,则应将内置类替换为自定义类

您可以编写一个,如所示:


就这样。现在,您正在使用Json.Net而不是JavaScriptSerializer来处理传入的Json请求。

如果您想在将Json请求绑定到视图模型时使用
Json.Net
,则应该将内置类替换为自定义类

您可以编写一个,如所示:

就这样。现在,您正在使用Json.Net而不是JavaScriptSerializer来处理传入的Json请求。

修改后的版本:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace MvcJsonNetTests.Utils
{
    public class JsonNetValueProviderFactory : ValueProviderFactory
    {
        public JsonNetValueProviderFactory()
        {
            Settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Error,
                Converters = { new ExpandoObjectConverter() }
            };
        }

        public JsonSerializerSettings Settings { get; set; }

        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");

            if (controllerContext.HttpContext == null ||
                controllerContext.HttpContext.Request == null ||
                controllerContext.HttpContext.Request.ContentType == null)
            {
                return null;
            }

            if (!controllerContext.HttpContext.Request.ContentType.StartsWith(
                    "application/json", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }

            if (!controllerContext.HttpContext.Request.IsAjaxRequest())
            {
                return null;
            }

            using (var streamReader = new StreamReader(controllerContext.HttpContext.Request.InputStream))
            {
                using (var jsonReader = new JsonTextReader(streamReader))
                {
                    if (!jsonReader.Read())
                        return null;

                    var jsonSerializer = JsonSerializer.Create(this.Settings);

                    Object jsonObject;
                    switch (jsonReader.TokenType)
                    {
                        case JsonToken.StartArray:
                            jsonObject = jsonSerializer.Deserialize<List<ExpandoObject>>(jsonReader);
                            break;
                        default:
                            jsonObject = jsonSerializer.Deserialize<ExpandoObject>(jsonReader);
                            break;
                    }

                    var backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    addToBackingStore(backingStore, String.Empty, jsonObject);
                    return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
                }
            }
        }

        private static void addToBackingStore(IDictionary<string, object> backingStore, string prefix, object value)
        {
            var dictionary = value as IDictionary<string, object>;
            if (dictionary != null)
            {
                foreach (var entry in dictionary)
                {
                    addToBackingStore(backingStore, makePropertyKey(prefix, entry.Key), entry.Value);
                }
                return;
            }

            var list = value as IList;
            if (list != null)
            {
                for (var index = 0; index < list.Count; index++)
                {
                    addToBackingStore(backingStore, makeArrayKey(prefix, index), list[index]);
                }
                return;
            }

            backingStore[prefix] = value;
        }

        private static string makeArrayKey(string prefix, int index)
        {
            return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
        }

        private static string makePropertyKey(string prefix, string propertyName)
        {
            return (string.IsNullOrWhiteSpace(prefix)) ? propertyName : prefix + "." + propertyName;
        }
    }
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
运用系统动力学;
利用制度全球化;
使用System.IO;
使用System.Web.Mvc;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Converters;
命名空间MvcJsonNetTests.Utils
{
公共类JsonNetValueProviderFactory:ValueProviderFactory
{
公共JsonNetValueProviderFactory()
{
设置=新JsonSerializerSettings
{
ReferenceLoopHandling=ReferenceLoopHandling.Error,
转换器={new ExpandoObjectConverter()}
};
}
公共JsonSerializerSettings设置{get;set;}
公共覆盖IValueProvider GetValueProvider(ControllerContext ControllerContext)
{
如果(controllerContext==null)
抛出新ArgumentNullException(“controllerContext”);
if(controllerContext.HttpContext==null||
controllerContext.HttpContext.Request==null||
controllerContext.HttpContext.Request.ContentType==null)
{
返回null;
}
如果(!controllerContext.HttpContext.Request.ContentType.StartWith(
“application/json”,StringComparison.ordinallingorecase)
{
返回null;
}
如果(!controllerContext.HttpContext.Request.IsAjaxRequest())
{
返回null;
}
使用(var streamReader=newstreamreader(controllerContext.HttpContext.Request.InputStream))
{
使用(var jsonReader=newjsontextreader(streamReader))
{
如果(!jsonReader.Read())
返回null;
var jsonSerializer=jsonSerializer.Create(this.Settings);
对象jsonObject;
开关(jsonReader.TokenType)
{
案例JsonToken.StartArray:
jsonObject=jsonSerializer.Deserialize(jsonReader);
打破
违约:
jsonObject=jsonSerializer.Deserialize(jsonReader);
打破
}
var backingStore=新字典(StringComparer.OrdinalIgnoreCase);
AddToBackStore(backingStore,String.Empty,jsonObject);
返回新的DictionaryValueProvider(backingStore,CultureInfo.CurrentCulture);
}
}
}
私有静态void addToBackStore(IDictionary backingStore、字符串前缀、对象值)
{
var dictionary=作为IDictionary的值;
如果(字典!=null)
{
foreach(字典中的var条目)
{
AddToBackStore(backingStore,makePropertyKey(前缀,entry.Key),entry.Value);
}
回来
}
var list=作为IList的值;
如果(列表!=null)
{
对于(变量索引=0;索引
还要将其注册到正确的索引:

public static void RegisterFactory()
{
    var defaultJsonFactory = ValueProviderFactories.Factories
        .OfType<JsonValueProviderFactory>().FirstOrDefault();
    var index = ValueProviderFactories.Factories.IndexOf(defaultJsonFactory);
    ValueProviderFactories.Factories.Remove(defaultJsonFactory);
    ValueProviderFactories.Factories.Insert(index, new JsonNetValueProviderFactory());
}
publicstaticvoidregisterfactory()
{
var defaultJsonFactory=valueProviderFactorys.Factories
.OfType().FirstOrDefault();
var索引=ValueProviderFactorys.Factorys.IndexOf(defaultJsonFactory);
ValueProviderFactorys.Factorys.Remove(默认JSONFactory);
valueProviderFactorys.Factories.Insert(索引,新的JsonNetValueProviderFactory());
}
修改后的版本:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace MvcJsonNetTests.Utils
{
    public class JsonNetValueProviderFactory : ValueProviderFactory
    {
        public JsonNetValueProviderFactory()
        {
            Settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Error,
                Converters = { new ExpandoObjectConverter() }
            };
        }

        public JsonSerializerSettings Settings { get; set; }

        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");

            if (controllerContext.HttpContext == null ||
                controllerContext.HttpContext.Request == null ||
                controllerContext.HttpContext.Request.ContentType == null)
            {
                return null;
            }

            if (!controllerContext.HttpContext.Request.ContentType.StartsWith(
                    "application/json", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }

            if (!controllerContext.HttpContext.Request.IsAjaxRequest())
            {
                return null;
            }

            using (var streamReader = new StreamReader(controllerContext.HttpContext.Request.InputStream))
            {
                using (var jsonReader = new JsonTextReader(streamReader))
                {
                    if (!jsonReader.Read())
                        return null;

                    var jsonSerializer = JsonSerializer.Create(this.Settings);

                    Object jsonObject;
                    switch (jsonReader.TokenType)
                    {
                        case JsonToken.StartArray:
                            jsonObject = jsonSerializer.Deserialize<List<ExpandoObject>>(jsonReader);
                            break;
                        default:
                            jsonObject = jsonSerializer.Deserialize<ExpandoObject>(jsonReader);
                            break;
                    }

                    var backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    addToBackingStore(backingStore, String.Empty, jsonObject);
                    return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
                }
            }
        }

        private static void addToBackingStore(IDictionary<string, object> backingStore, string prefix, object value)
        {
            var dictionary = value as IDictionary<string, object>;
            if (dictionary != null)
            {
                foreach (var entry in dictionary)
                {
                    addToBackingStore(backingStore, makePropertyKey(prefix, entry.Key), entry.Value);
                }
                return;
            }

            var list = value as IList;
            if (list != null)
            {
                for (var index = 0; index < list.Count; index++)
                {
                    addToBackingStore(backingStore, makeArrayKey(prefix, index), list[index]);
                }
                return;
            }

            backingStore[prefix] = value;
        }

        private static string makeArrayKey(string prefix, int index)
        {
            return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
        }

        private static string makePropertyKey(string prefix, string propertyName)
        {
            return (string.IsNullOrWhiteSpace(prefix)) ? propertyName : prefix + "." + propertyName;
        }
    }
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
运用系统动力学;
利用制度全球化;
使用System.IO;
使用System.Web.Mvc;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Converters;
命名空间MvcJsonNetTests.Utils
{
公共类JsonNetValueProviderFactory:ValueProviderFactory
{
公共JsonNetValu