Asp.Net MVC默认是使用JavaScriptSerializer做Json序列化的,不好用。而且JavaScriptSerializer无法处理循环引用,对日期的格式化不友好。例如对当前日期序列化后的效果是这样的:【CreateTime: "/Date(1521983727837)/"】 这样的日期我们很难看懂
而且JavaScriptSerializer对一个对象的序列化,序列化后的json对象属性与C#中的对象的属性名称一致。因为我们在javascript中习惯将对象属性的第一个字母是以小写开头的,不习惯属性的第一个字母是大写开头的,比如:,比如 id,name,createTime举列:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreateTime { get; set; }
}
如果使用JavaScriptSerializer对这个对象序列化,序列化后的效果是这样的:
{Id: 1, Name: "张三", CreateTime: "/Date(1521983727837)/"}
那什么现在使用newtonjs 对这个对象进行序列化就能达到我们想要的效果:
{id: 1, name: "张三", createTime: "2018-03-25 22:26:07"}
或者执行PM>Install-Package Newtonsoft.Json -Version 11.0.2
namespace MvcApp.Controllers
{
public class JsonNetResult : JsonResult
{
public JsonNetResult()
{
Settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,//忽略循环引用,如果设置为Error,则遇到循环引用的时候报错(建议设置为Error,这样更规范)
DateFormatString = "yyyy-MM-dd HH:mm:ss",//日期格式化,默认的格式也不好看
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()//json中属性开头字母小写的驼峰命名
};
}
public JsonSerializerSettings Settings { get; private set; }
public override void ExecuteResult(ControllerContext context)//重写JsonResult类的ExecuteResult方法
{
if (context == null)
throw new ArgumentNullException("context");
//判断是否运行Get请求
if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet
&& string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("JSON GET is not allowed");
//设定响应数据格式。默认为json
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);
scriptSerializer.Serialize(response.Output, this.Data);
}
}
namespace MvcApp.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonNetResult TestJson()
{
Person person = new Person() { Id = 1, Name = "张三", CreateTime = DateTime.Now };
//直接这样使用就可以啦
return new JsonNetResult() { Data = person };
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreateTime { get; set; }
}
}
{id: 1, name: "张三", createTime: "2018-03-25 22:26:07"}
由于直接return new JsonNetResult(){Data=person} 对MVC框架侵入式比较强,用起来还是不是很方便,那么如何尽量保持原来的使用方式不变的情况下来使用我们自定义的JsonNetResult呢?方法很简单,就是使用ActionFilterAttribute过滤器
namespace MvcApp.Filters
{
using MvcApp.Controllers;
using System.Web.Mvc;
public class JsonNetResultAttritube : IActionFilter
{
///
/// 注意:OnActionExecuted是在Action方法执行之后被执行
/// 在这里我们将JsonResult替换成我们的JsonNetResult
///
///
public void OnActionExecuted(ActionExecutedContext filterContext)
{
ActionResult result = filterContext.Result;
if (result is JsonResult && !(result is JsonNetResult))
{
JsonResult jsonResult = (JsonResult)result;
JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.ContentEncoding = jsonResult.ContentEncoding;
jsonNetResult.ContentType = jsonResult.ContentType;
jsonNetResult.JsonRequestBehavior = jsonResult.JsonRequestBehavior;
jsonNetResult.Data = jsonResult.Data;
jsonNetResult.MaxJsonLength = jsonResult.MaxJsonLength;
jsonNetResult.RecursionLimit = jsonResult.RecursionLimit;
filterContext.Result = jsonNetResult;
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
}
}
namespace MvcApp.App_Start
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new JsonNetResultAttritube());
}
}
}
namespace MvcApp.Controllers
{
using System.Web.Mvc;
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult TestJson()
{
Person person = new Person() { Id = 1, Name = "张三", CreateTime = DateTime.Now };
//原来该怎么用还是怎么用(只是通过过滤器,我们将这个Json(person)替换成我们自己的JsonNetResult了)
return Json(person);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreateTime { get; set; }
}
}
{id: 1, name: "张三", createTime: "2018-03-25 22:26:07"}
public static class ControllerExpand
{
public static JsonNetResult JsonNet(this Controller JsonNet, object data)
{
return new JsonNetResult() { Data = data };
}
public static JsonNetResult JsonNet(this Controller JonsNet, object data, JsonRequestBehavior behavior)
{
return new JsonNetResult()
{
Data = data,
JsonRequestBehavior = behavior
};
}
public static JsonNetResult JsonNet(this Controller JonsNet,object data, string contentType, Encoding contentEncoding)
{
return new JsonNetResult()
{
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding
};
}
public static JsonNetResult JsonNet(this System.Web.Mvc.Controller JonsNet, object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
return new JsonNetResult()
{
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior
};
}
}
namespace MvcApp.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonNetResult TestJson()
{
Person person = new Person() { Id = 1, Name = "张三", CreateTime = DateTime.Now };
//直接这样使用就可以啦
//return new JsonNetResult() { Data = person };
//这样使用是不是更加方便了呢?哈哈
return this.JsonNet(person);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreateTime { get; set; }
}
}
{id: 1, name: "张三", createTime: "2018-03-25 22:26:07"}