在mvc的項目中,我們前台做一些操作時,后台要返回一些結果給前台,這個時候我們就需要有一個狀態來標識到底是什么類型的錯誤,
例如:
執行刪除的時候,如果操作成功(1行受影響),我們需要返回狀態為1並輸出返回 “ 刪除成功 ” 等提示語
執行刪除的時候,如果沒有做任何操作(0行受影響),我們需要返回狀態為2並輸出返回 “ 刪除失敗 ”等提示語
執行刪除的時候,如果直接拋異常,我們需要返回狀態為3並輸出返回 “ 執行sql異常 ”等提示語
代碼如下:
[HttpPost] public ActionResult DelRequest(int id) { try { if (proBLL.Delete(id)) { return Json("{\"status\":\"1\",\"msg\":\"刪除成功\"}", JsonRequestBehavior.AllowGet); } else { return Content("{\"status\":\"2\",\"msg\":\"刪除失敗\"}"); } } catch { return Content("{\"status\":\"3\",\"msg\":\"刪除失敗\"}"); } }
但是這樣寫是不是很麻煩(雖然可以賦值粘貼),而且也不是很好控制容易出錯,所以漸漸的想寫自定義返回json格式數據的方法給前台
我們來看看源碼:
在通過反編譯工具我在System.Web.Mvc程序集中看到有一個類叫JsonResult
JsonResult(class JsonResult : ActionResult) 類源碼如下:

namespace System.Web.Mvc { public class JsonResult : ActionResult { public Encoding ContentEncoding { get; set; } public string ContentType { get; set; } public object Data { get; set; } public JsonRequestBehavior JsonRequestBehavior { get; set; } public int? MaxJsonLength { get; set; } public int? RecursionLimit { get; set; } public JsonResult() { this.JsonRequestBehavior = JsonRequestBehavior.DenyGet; } 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(MvcResources.JsonRequest_GetNotAllowed); } HttpResponseBase response = context.HttpContext.Response; if (!string.IsNullOrEmpty(this.ContentType)) { response.ContentType = this.ContentType; } else { response.ContentType = "application/json"; } if (this.ContentEncoding != null) { response.ContentEncoding = this.ContentEncoding; } if (this.Data != null) { JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); if (this.MaxJsonLength.HasValue) { javaScriptSerializer.MaxJsonLength = this.MaxJsonLength.Value; } if (this.RecursionLimit.HasValue) { javaScriptSerializer.RecursionLimit = this.RecursionLimit.Value; } response.Write(javaScriptSerializer.Serialize(this.Data)); } } } }
前面先不過,我們可以看到里面有一個方法 public override void ExecuteResult(ControllerContext context),首先接受一個控制器上下文,后面判斷是否允許GET請求什么的等,最后通過 response.Write(javaScriptSerializer.Serialize(this.Data)); 把我們傳入的數據序列化給前台
既然我們找到了核心類,但是我們如何使用它了?,其實我們可以看到在Controller類中有幾個重載的Json方法:
protected internal JsonResult Json(object data); protected internal JsonResult Json(object data, string contentType); protected internal JsonResult Json(object data, JsonRequestBehavior behavior); protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding); protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior); protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior);
我們看源碼可以很清楚直到前面的幾個重載都是調用的最后一個重載方法
protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior 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 }; }
哦,原來直接返回了一個JsonResult方法,那么我們是不是也可以寫一個Json的重載,或則自定義一個方法,並調用此方法了?
修改如下:
首先我們可以定義一個枚舉
public enum ReturnStatus { SUCCESS = 1, FAIL = 2, EXCEPTION = 3 }
錯誤消息類:
public class Message { public int Status { get; set; } public string Mes { get; set; } }
然后我們寫一個BaseController繼承Controller類,並添加一個方法JsonResult
/// <summary> /// 返回json格式的數據給前台 /// </summary> /// <param name="status">錯誤標識</param> /// <param name="message">錯誤消息</param> /// <param name="behavior">是否允許</param> /// <returns></returns> protected internal JsonResult JsonResult(ReturnStatus status,string message , JsonRequestBehavior behavior = JsonRequestBehavior.DenyGet) {
return this.Json(new Message
{
Status = Convert.ToInt32(status),
Mes = message
},"application/json", Encoding.UTF8, behavior);
}
使用:
[HttpPost] public ActionResult DelRequest(int id) { try { if (proBLL.Delete(id)) { return JsonResult(ReturnStatus.SUCCESS, "刪除成功"); } else { return JsonResult(ReturnStatus.FAIL, "刪除失敗"); } } catch { return JsonResult(ReturnStatus.EXCEPTION, "刪除失敗"); } }
最后總結:
所有的擴展都是看源碼出來的,而不是百度出來的
所以一定要多看源碼,一定要多看源碼,一定要多看源碼,一定要多看源碼,一定要多看源碼........