使用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对象的相互转换方式有很多,接下 ...
随机推荐
- svn 更新命令(冲突时使用theirs)
svn cleanup svn revert -R -q ./ svn up --force --accept tc
- ios 抓取真机的网络包
一直被如何从真机上抓包所困扰!今天偶然看到了最简单有效的方法!分享一下: 原地址链接 http://blog.csdn.net/phunxm/article/details/38590561 通过 R ...
- Entity framwork的数据库分页
网上查了很多,原以为多么复杂的事情,其实很简单: list = list.OrderBy(orderBy, ascending).Skip((pageIndex - 1) * pageSize).Ta ...
- 【XLL 框架库函数】 TempActiveRef/TempActiveRef12
[XLL 框架库函数] TempActiveRef/TempActiveRef12 创建一个包含所有激活工作表引用区域 XLOPER/XLOPER12 LPXLOPER TempActiveRef(B ...
- AJAX里,使用XML返回数据类型,实现简单下拉列表
XML:可扩展标记语言 HTML:超文本标记语言 标签:<标签名></标签名> 特点: 1.必须要有一个根 2.标签名自定义 3.对大小写敏感 4.有开始就要有结束 5.同一级 ...
- xampp环境搭建+bugfree
一.xampp安装 1.下载xampp安装文件,下载地址:http://pan.baidu.com/s/1eSp5wVw 2.上传到Linux服务器,执行赋权并安装(我安装在/opt目录下) 3.安装 ...
- 登录oracle数据库提示账户锁定解决方法
问题再现: 由于更改了oracle账户的密码,退出重新连接oracle出现了账户被锁定的情况. 请了百度君出来卸载一下,问题已解决. 在cmd下:sqlplus /nolog 然后:以dba身份登录: ...
- SQL Server Database 维护计划创建完整的备份策略
SQL Server的维护计划Maintenance Plan是一个非常实用的维护工具,可以完成大多数的数据库维护任务,通过对这些功能的封装,可以省去很多的代码编写时间.网络上完整介绍的不是很多,特此 ...
- 【Exception—WebForm】当应用程序不是以 UserInteractive 模式运行时显示模式对话框或窗体是无效操作。请指定 ServiceNotification 或 DefaultDesktopOnly 样式,以显示服务应用程序发出的通知。
最近做的项目现在发布到服务器上开始测试了,本地好好的程序,到服务器上却报异常了: 当应用程序不是以 UserInteractive 模式运行时显示模式对话框或窗体是无效操作.请指定 ServiceNo ...
- Official online document, install svn server in centOS
http://www.krizna.com/centos/install-svn-server-on-centos-6/