使用JSON.Net(Newtonsoft.Json)作为ASP.Net MVC的json序列化和反序列化工具
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序列化和反序列化工具的更多相关文章
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展
Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...
- ArcGIS Server 10.2 实战(一)Asp.net MVC与JSON数据妙用实现动态生成要素图层
今年7月刚刚发布的ArcGIS 10.2为GIS的web开发带来了一个很实在的功能,JSON转要素.以往GIS图层外部数据(如文本数据,数据库数据)动态地写入地图服务中的图层是一件不可想象的事情,如今 ...
- ASP.Net MVC中JSON处理。
实体数据Model [Serializable] public class UserModel { //public UserModel(string name, string classname, ...
- Asp.Net MVC以 JSON传值扩展方法
Asp.Net在客户端和服务器端,以JSON形式相互传值,可写扩展方法,用到的类型如下: DataContractJsonSerializer类: 该类在System.Runtime.Serializ ...
- Asp.Net MVC以JSON传值扩展方法
Asp.Net在客户端和服务器端,以JSON形式相互传值,可写扩展方法,用到的类型如下: DataContractJsonSerializer类: 该类在System.Runtime.Serializ ...
- C# Json 序列化和反序列化 工具类 Newtonsoft.Json.dll
引用: Newtonsoft.Json.dll // 引用: using Newtonsoft.Json; using Newtonsoft.Json.Converters; // 定义 实体测试类 ...
- megajson 高性能的json序列化、反序列化工具
go 自带的 encoding/json 支持json的序列化和反序列化, 然而它是基于反射的,有下面几个缺点: 反射是性能差的代名词, 并且无法在编译时进行优化. 只有 Public 字段才可以,反 ...
- 几种常用的json序列化和反序列化工具介绍
一.前言 Json序列化和反序列化工作中会时常用到,也是目前数据交互的常用格式,Rest风格的接口加上json格式的数据交互,真的是天作之合. 目前Json字符与Json对象的相互转换方式有很多,接下 ...
随机推荐
- html中表格元素的相关总结
表格元素相关总结: 1.在CSS中,内部表元素(如td.tr.col等)生成矩形框,这些矩形框包含内容.内边距和边框,但没有外边距,因此如果定义外边距,浏览器将忽略该定义:对于table元素,外边距有 ...
- 《linux命令》ps -aux详细解释
本文转载自http://blog.chinaunix.net/uid-21516619-id-1824945.html 显示其他用户启动的进程(a) 查看系统中属于自己的进程(x) 启动这个进程的用户 ...
- [Android Pro] listView和GridView的item设置的高度和宽度不起作用
referece to : http://blog.csdn.net/beibeixiao/article/details/9032569 1. 在Android开发中会发现,有时listVi ...
- 【数据结构初学】(java实现篇)——队列(转)
原文地址:http://www.cnblogs.com/skywang12345/p/3603935.html 原文地址:http://www.cnblogs.com/skywang12345/p/3 ...
- 常用shell命令中你所不熟悉的参数
1. ls: 类似于dos下的dir命令 ls最常用的参数有三个: -a -l -F. ls –a Linux上的文件以.开头的文件被系统视为隐藏文件,仅用ls命令是看不到他们的,而用ls -a除 ...
- windows下编译及使用libevent
Libevent官网:http://libevent.org/ windows 7下编译: 编译环境: windows 7 + VS2010 (1)解压libevent到F:\libevent\lib ...
- [C++][数据结构][算法]单链式结构的深拷贝
深拷贝(deep-copy),区别于浅拷贝,表示复制所有数据,而不是像浅拷贝一般只复制指针.深拷贝的数据不会因原始数据被delete后而消失. 单链式结构可以实现单链表,栈,队列,树等数据结构.掌握了 ...
- ubuntu下配置jdk
1.首先下载jdk-7u51-linux-i586.tar.gz.并将它放在例如/home目录. 2.解压安装 sudo tar zxvf ./jdk-7u51-linux-i586.tar.gz ...
- Python学习笔记(四)——编码和字符串
一.编码 1.编码类别: (1)ASCII码:127个字母被编码到计算机里,也就是大小写英文字母.数字和一些符号 (2)GB2312码:中国制定的用于加入中文汉字的编码 (3)Unicode:防止由于 ...
- apache配置多个版本php
参看链接:http://my.oschina.net/u/2366984/blog/543148?p={{page}} 主要虚拟主机配置信息 FcgidInitialEnv PHPRC "D ...