3.自定义返回json格式的数据给前台(自定义Controller类中的Json方法)

在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));
            }
        }
    }
}
View Code

前面先不过,我们可以看到里面有一个方法 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, "删除失败");
    }
            
}

最后总结:

所有的扩展都是看源码出来的,而不是百度出来的

所以一定要多看源码,一定要多看源码,一定要多看源码,一定要多看源码,一定要多看源码........

原文地址:https://www.cnblogs.com/zjdbk/p/10610254.html