如何在ASP.NET MVC5项目中更换默认JSON转换器
解决ASP.NET MVC5中自定义JSON转换器在模型绑定中不生效的问题
首先纠正你代码中的一个关键错误:MyObjectConverter的CanConvert方法返回值错误,应该匹配MyObject类型而非转换器自身:
public class MyObjectConverter : JsonConverter { // ...其他方法保持不变... public override bool CanConvert(Type objectType) { // 修正为匹配MyObject类型 return objectType == typeof(MyObject); } }
接下来解决MVC5默认JSON处理工具的问题:MVC5的模型绑定(如Save方法的参数绑定)默认使用JavaScriptSerializer,而非Newtonsoft.Json,因此需要全局配置MVC使用Newtonsoft.Json处理JSON序列化和模型绑定。
步骤1:安装Newtonsoft.Json NuGet包
如果项目未安装,在Package Manager Console执行:
Install-Package Newtonsoft.Json
步骤2:替换模型绑定的JSON解析器
MVC默认的JsonValueProviderFactory依赖JavaScriptSerializer,需要替换为基于Newtonsoft.Json的实现:
创建自定义ValueProviderFactory类:
using System; using System.Collections.Generic; using System.IO; using System.Web.Mvc; using Newtonsoft.Json; public class NewtonsoftJsonValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { if (controllerContext == null) throw new ArgumentNullException(nameof(controllerContext)); if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) return null; controllerContext.HttpContext.Request.InputStream.Position = 0; using var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream); var bodyText = reader.ReadToEnd(); if (string.IsNullOrEmpty(bodyText)) return null; var jsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(bodyText); return new DictionaryValueProvider<object>(jsonData, null); } }
然后在Global.asax.cs的Application_Start方法中注册这个工厂,替换默认实现:
using System.Linq; using System.Web.Mvc; protected void Application_Start() { // ...其他初始化代码(如AreaRegistration.RegisterAllAreas()等)... // 移除默认的JsonValueProviderFactory var defaultJsonFactory = ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault(); if (defaultJsonFactory != null) ValueProviderFactories.Factories.Remove(defaultJsonFactory); // 添加自定义的Newtonsoft JsonValueProviderFactory ValueProviderFactories.Factories.Add(new NewtonsoftJsonValueProviderFactory()); }
步骤3:配置MVC的JSON结果序列化使用Newtonsoft.Json
如果你的控制器方法使用return Json(...)返回JSON结果,默认仍会使用JavaScriptSerializer,可以创建自定义JsonResult来替换:
using System; using System.Web.Mvc; using Newtonsoft.Json; public class NewtonsoftJsonResult : JsonResult { public JsonSerializerSettings SerializerSettings { get; set; } public NewtonsoftJsonResult() { SerializerSettings = new JsonSerializerSettings { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, // 可以在这里全局添加自定义转换器 Converters = new List<JsonConverter> { new MyObjectConverter() } }; } public override void ExecuteResult(ControllerContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); var response = context.HttpContext.Response; response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json"; if (ContentEncoding != null) response.ContentEncoding = ContentEncoding; if (Data == null) return; using var writer = new JsonTextWriter(response.Output); var serializer = JsonSerializer.Create(SerializerSettings); serializer.Serialize(writer, Data); writer.Flush(); } }
之后在控制器中可以用这个自定义结果返回JSON,替代手动调用JsonConvert.SerializeObject:
public class MyController : Controller { [HttpPost] public void Save(MyObject Item) { // Save method } [HttpGet] // 建议Get方法用HttpGet特性 public NewtonsoftJsonResult Get() { var Item = new MyObject{ Property1 = "abc", Property2 = "def" }; return new NewtonsoftJsonResult { Data = Item }; } }
验证
完成以上配置后,调用Save方法时,MVC会使用Newtonsoft.Json解析请求体并绑定到MyObject参数,自定义转换器会生效;Get方法返回的JSON也会通过自定义转换器处理。
内容的提问来源于stack exchange,提问作者Omer Harmansa
相关产品推荐
相关产品推荐

