在用EasyUI的时候为了返回Datagrid能够展现出来的Json数据格式,都要这样写
public JsonResult GetAllSchoolsJson() { var result = IStudentLogic.GetAllStudent();//result 返回自定义的InvokeWebResult<T> 这里是分页返回的就是InvokeWebResult<PagedList<T>> return Json(new { total = result.Data.Count, rows = result.Data.Items }, JsonRequestBehavior.AllowGet);
} //或者 public JsonResult GetAllSchoolsJson() { var result = IStudentLogic.GetAllStudent(); new JsonResult { Data = new { total = result.Data.Count, rows = result.Data.Items } }; }
//InvokeWebResult<T> InvokeWebResult<PagedList<T>>
namespace WebSeat.Core { /// <summary> /// Class PagedList /// </summary> /// <typeparam name="T"></typeparam> [Serializable] public class PagedList<T> { /// <summary> /// Gets or sets the index. /// </summary> /// <value>The index.</value> public int Index { get; set; } /// <summary> /// Gets or sets the size. /// </summary> /// <value>The size.</value> public int Size { get; set; } /// <summary> /// Gets or sets the count. /// </summary> /// <value>The count.</value> public int Count { get; set; } /// <summary> /// Gets or sets the items. /// </summary> /// <value>The items.</value> public IList<T> Items { get; set; } /// <summary> /// 总页数 /// </summary> public int TotalPageCount { get { return (int)Math.Ceiling(Count / (double)Size); } } } } namespace WebSeat.Web.Core { /// <summary> /// 操作结果 /// </summary> /// <typeparam name="T">附加数据类型</typeparam> [Serializable] public class InvokeWebResult<T> { /// <summary> /// 操作是否成功 /// </summary> /// <value><c>true</c> if success; otherwise, <c>false</c>.</value> public bool Success { get; set; } /// <summary> /// 操作结果信息 /// </summary> /// <value>The message.</value> public string Message { get; set; } /// <summary> /// 附加数据 /// </summary> /// <value>The data.</value> public T Data { get; set; } public InvokeWebResult() { Success = false; } } }
每次都Return Json(…………),或者 new JsonResult{……}, 它们内部实现我们不能控制,但是底层返回来的都是统一的InvokeWebResult<T> ,我们在Controller里把返回的数据格式都统一转换成
new { total = …………, rows = ………… },,感觉这是一个重复的工作,满篇的total=…… rows=…… ,于是想自己专门定义一个针对EasyUI Datagrid的Result,MVC是个开源的框架,可以自己下载源码然后研究,我看了下在Controller里的实现,其实 Json 也就是调用的JsonResult代码如下
protected internal JsonResult Json(object data, string contentType) { return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet); } protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) { return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet); } protected internal JsonResult Json(object data, JsonRequestBehavior behavior) { return Json(data, null /* contentType */, null /* contentEncoding */, behavior); } protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) { return Json(data, contentType, null /* contentEncoding */, behavior); } protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { return new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior }; }
再查看了MVC内部JsonResult 的实现,其实很简单,就是继承ActionResult 然后重写ExecuteResult方法
namespace System.Web.Mvc { public class JsonResult : ActionResult { public JsonResult() { JsonRequestBehavior = JsonRequestBehavior.DenyGet; } public Encoding ContentEncoding { get; set; } public string ContentType { get; set; } public object Data { get; set; } public JsonRequestBehavior JsonRequestBehavior { get; set; } /// <summary> /// When set MaxJsonLength passed to the JavaScriptSerializer. /// </summary> public int? MaxJsonLength { get; set; } /// <summary> /// When set RecursionLimit passed to the JavaScriptSerializer. /// </summary> public int? RecursionLimit { get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed); } HttpResponseBase response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) { response.ContentType = ContentType; } else { response.ContentType = "application/json"; } if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } if (Data != null) { JavaScriptSerializer serializer = new JavaScriptSerializer(); if (MaxJsonLength.HasValue) { serializer.MaxJsonLength = MaxJsonLength.Value; } if (RecursionLimit.HasValue) { serializer.RecursionLimit = RecursionLimit.Value; } response.Write(serializer.Serialize(Data)); } } } }
于是我想到,自己也写一个类,来继承JsonResult,然后重写ExecuteResult方法,以后每次处理从下层返回来的数据的时候只需要调用自己的实现,进行统一的转换,不再是满篇的 total=…… rows=……,万一客户端不是EasyUi Datagrid了就哭了,满篇改,不能有重复的代码,我有强迫症,见到这种就看不惯。
namespace WebSeat.Web.Core.EasyUi { // public class JsonDataGridResult<T> : JsonResult where T : class //{ //自己也继承JsonResult方法 重写ExecuteResult方法 public class JsonDataGridResult : JsonResult { public JsonDataGridResult(dynamic obj) { JsonRequestBehavior = JsonRequestBehavior.AllowGet; Data = new DataGrid { rows = obj == null ? null : obj.Items, total = obj == null ? 0 : obj.Count }; } #region Temp Methods public JsonDataGridResult(IEnumerable<object> obj) { JsonRequestBehavior = JsonRequestBehavior.AllowGet; Data = new DataGrid { rows = obj, total = obj == null ? 0 : obj.Count() }; } public JsonDataGridResult(IEnumerable<object> obj, int total) { JsonRequestBehavior = JsonRequestBehavior.AllowGet; Data = new DataGrid { rows = obj, total = total }; } #endregion //public JsonDataGridResult(PagedList<T> obj) //{ // JsonRequestBehavior = JsonRequestBehavior.AllowGet; // Data = new DataGrid // { // rows = obj.Items, // total = obj.Count // }; //} public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } //这个不要了 /*if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(WebCoreMessages.JsonRequest_GetNotAllowed); }*/ HttpResponseBase response = context.HttpContext.Response; response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json"; if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } if (Data != null) { var serializer = new JavaScriptSerializer(); if (MaxJsonLength.HasValue) { serializer.MaxJsonLength = MaxJsonLength.Value; } if (RecursionLimit.HasValue) { serializer.RecursionLimit = RecursionLimit.Value; } response.Write(serializer.Serialize(Data)); } } } }
以后每次返回给Datagrid数据的时候都这样写了,
public JsonResult GetAllSchoolsJson() { var result = IStudentLogic.GetAllStudent();//result 返回自定义的InvokeWebResult<T> 这里是分页返回的就是InvokeWebResult<PagedList<T>> return new JsonDataGridResult(result.Data);//没有了total 没有了 rows } //result 是 InvokeWebResult<PagedList<T>> 具体的转换有JsonDataGridResult,内部实现。
//其实有MVC源码,里面有很多值得学习的