ASP.Net MVC默认的JSON序列化使用的是微软自己的JavaScriptSerializer。性能低不说,最让人受不了的是Dictionary<,>和Hashtable类型居然对应的json是[{"Key":"a","Value":1}]而不是{"a":1}。真是奇葩到家了,跟前端根本没法集成!

决定还是用JSON.Net来做吧!查了各种资料,网上的要么代码太复杂,要么没法完全实现。又在ILSpy分析了MVC源码,然后调试了半天,终于有了初步的解决办法:

1、反序列化,首先建立下面的类:

原理基本上就是替换系统自带的ValueProviderFactory和DefaultModelBinder,然后改用自己的类来调用JSON.Net实现。

public class JsonNetValueProviderFactory : ValueProviderFactory
{
public override IValueProvider GetValueProvider(ControllerContext ctlContext)
{
//if (!controllerContext.HttpContext.Request.ContentType.
// StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
//{
// return null;
//} var reader = new StreamReader(ctlContext.HttpContext.Request.InputStream);
reader.BaseStream.Position = ;
var json = reader.ReadToEnd()?.TrimStart(' ', '\r', '\n', '\t');
if (string.IsNullOrEmpty(json))
return null; var jtoken = json.StartsWith("[")
? JArray.Parse(json) as JContainer
: JObject.Parse(json) as JContainer;
return new JsonNetValueProvider(jtoken);
}
} public class JsonNetValueProvider : IValueProvider
{
private JContainer _jValue; public JsonNetValueProvider(JContainer jval)
{
_jValue = jval;
} public bool ContainsPrefix(string prefix)
{
return true;
} public ValueProviderResult GetValue(string key)
{
var jtoken = _jValue.SelectToken(key);
if (jtoken == null)
{
jtoken = _jValue;
}
return new JsonNetValueProviderResult(jtoken, key, null);
}
} public class JsonNetValueProviderResult : ValueProviderResult
{
private JToken _jtoken;
public JsonNetValueProviderResult(JToken valueRaw, string key, CultureInfo info)
{
_jtoken = valueRaw;
}
[System.Diagnostics.DebuggerHidden]
public override object ConvertTo(Type type, CultureInfo culture)
{
return _jtoken?.ToObject(type);
}
} public class JsonNetModelBinder : DefaultModelBinder
{
[System.Diagnostics.DebuggerHidden]
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var provider = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (provider != null)
{
try
{
return provider.ConvertTo(bindingContext.ModelType);
}
catch { }
}
return base.BindModel(controllerContext, bindingContext);
}
}

2、然后再Application_Start或者Router初始化时调用下面代码:

            //重置Json序列化方式,改用JSON.Net
ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.
OfType<JsonValueProviderFactory>().FirstOrDefault());
ValueProviderFactories.Factories.Add(new JsonNetValueProviderFactory()); //重置系统的Binder,使Dictionary可以正常json
ModelBinders.Binders.DefaultBinder = new JsonNetModelBinder();

3、序列化的过程比较简单,建立一个JsonNetResult类,然后mvc方法返回这个类型就可以了。

 public class JsonNetResult : JsonResult
{
public JsonSerializerSettings Settings { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
//if (context == null)
// throw new ArgumentNullException("context");
//if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
// throw new InvalidOperationException("JSON GET is not allowed"); HttpResponseBase response = context.HttpContext.Response;
response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType; if (this.ContentEncoding != null)
response.ContentEncoding = this.ContentEncoding;
if (this.Data == null)
return; var scriptSerializer = JsonSerializer.Create(this.Settings); using (var sw = new StringWriter())
{
scriptSerializer.Serialize(sw, this.Data);
response.Write(sw.ToString());
}
}
}

使用JSON.Net(Newtonsoft.Json)作为ASP.Net MVC的json序列化和反序列化工具的更多相关文章

  1. Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

  2. Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展

    Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...

  3. ArcGIS Server 10.2 实战(一)Asp.net MVC与JSON数据妙用实现动态生成要素图层

    今年7月刚刚发布的ArcGIS 10.2为GIS的web开发带来了一个很实在的功能,JSON转要素.以往GIS图层外部数据(如文本数据,数据库数据)动态地写入地图服务中的图层是一件不可想象的事情,如今 ...

  4. ASP.Net MVC中JSON处理。

    实体数据Model [Serializable] public class UserModel { //public UserModel(string name, string classname, ...

  5. Asp.Net MVC以 JSON传值扩展方法

    Asp.Net在客户端和服务器端,以JSON形式相互传值,可写扩展方法,用到的类型如下: DataContractJsonSerializer类: 该类在System.Runtime.Serializ ...

  6. Asp.Net MVC以JSON传值扩展方法

    Asp.Net在客户端和服务器端,以JSON形式相互传值,可写扩展方法,用到的类型如下: DataContractJsonSerializer类: 该类在System.Runtime.Serializ ...

  7. C# Json 序列化和反序列化 工具类 Newtonsoft.Json.dll

    引用: Newtonsoft.Json.dll // 引用: using Newtonsoft.Json; using Newtonsoft.Json.Converters; // 定义 实体测试类 ...

  8. megajson 高性能的json序列化、反序列化工具

    go 自带的 encoding/json 支持json的序列化和反序列化, 然而它是基于反射的,有下面几个缺点: 反射是性能差的代名词, 并且无法在编译时进行优化. 只有 Public 字段才可以,反 ...

  9. 几种常用的json序列化和反序列化工具介绍

    一.前言 Json序列化和反序列化工作中会时常用到,也是目前数据交互的常用格式,Rest风格的接口加上json格式的数据交互,真的是天作之合. 目前Json字符与Json对象的相互转换方式有很多,接下 ...

随机推荐

  1. linux编程问题记录

    1.程序中需要用到字符串的时候,尽可能选择string类型,这种类型的字符串有很多比较容易的功能,如字符串之间可以直接拷贝赋值 string a; string b="123"; ...

  2. Win10 Build9926 更新问题解决

    将Dns 改为 4.2.2.2 备用 4.2.2.1

  3. 使用 lsyncd 本地目录实时备份

    转自 https://segmentfault.com/a/1190000002737213 2.1安装lsyncd # rpm -ivh http://dl.fedoraproject.org/pu ...

  4. MyEclipse2015配置Tomcat方法----》myeclipse2015

    1.打开Myeclipse2015,进入偏好设置window-perference,找到下图箭头指向的地方 2.点击Add按钮进入下面界面 3.点击next进入下面界面 4.选择tomat  选择JR ...

  5. iOS - 使用自定义字体-苹方字体

    苹方提供了六个字重,font-family 定义如下:苹方-简 常规体font-family: PingFangSC-Regular, sans-serif;苹方-简 极细体font-family: ...

  6. 学习微信小程序之css2

    一:伪类的使用 .class-btn:active{ color: red;} <button class="class-btn">并集选择器</button&g ...

  7. YARN-MR 大数据第二天

    大数据第二天 1.YARN(管理和调度集群中的各类资源) 1.1 产生的背景: 1.直接源于MR版本1的缺陷(如:单点故障.难以支持MR之外的计算框架等) 2.多计算框架各自为站,数据共享困难(如:M ...

  8. wenbenfenlei

    ICTCLAS: 该分词系统的主要思想是先通过CHMM(层叠形马尔可夫模型)进行分词,通过分层,既增加了分词的准确性,又保证了分词的效率.基本思路是:先进行原子切分,然后在此基础上进行N-最短路径粗切 ...

  9. 如何使用PL/SQL Developer查看和杀掉session

    http://jingyan.baidu.com/article/3ea51489eb65b152e61bba8b.html

  10. keyCode,charCode,which

    1.触发顺序keydown keypress keyup,但keypress事件只有输入相关按键才会触发,功能按键不会触发keypress事件(keypress事件有个额外的charCode属性) 2 ...