开发者

ASP.NET MVC Ajax Actions results enveloping

I would like to have every result of any AJAX call on ASP.NET MVC to be enveloped to a JSON object which should be like: AjaxResult { status, data }

where status will contain a enumeration value describing if the call was successful, erroneous, authentication expired etc. This will enable client side code to be able to redirect to the login page etc.

I tried catching Ajax Requests by overriding OnActionExecuted, and trying to render the returned by the corresponding action result using the following code, but this solution seems operating slow. Do you have some better idea?

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception == null)
    {
        if (filterContext.Result.GetType() == typeof(ViewResult))
        {
            ViewResult viewResultTemp = (ViewResult)filterContext.Result;
            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewResultTemp.ViewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
开发者_C百科                var ajaxReply = new AjaxReply(AjaxReplyStatus.Success, string.Empty, sw.ToString());
                filterContext.Result = new JsonResult {Data = ajaxReply};
            }
        }
        else if (filterContext.Result.GetType() == typeof(PartialViewResult))
        {
            PartialViewResult partialViewResultTemp = (PartialViewResult)filterContext.Result;
            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, partialViewResultTemp.ViewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                var ajaxReply = new AjaxReply(AjaxReplyStatus.Success, string.Empty, sw.ToString());
                filterContext.Result = new JsonResult { Data = ajaxReply };
            }
        }
        else if (filterContext.Result.GetType() == typeof(JsonResult))
        {
            JsonResult jsonResult = (JsonResult)filterContext.Result;
            JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
            string jsonData = javaScriptSerializer.Serialize(jsonResult.Data);
            var ajaxReply = new AjaxReply(AjaxReplyStatus.Success, string.Empty, jsonData);
            filterContext.Result = new JsonResult { Data = ajaxReply };
        }
    }
}


Why you need this? Create your custom ApplicationController and derive all controllers from this one. In ApplicationController implement the method Json<data>() where data

   public JsonResult Json<TData>(TData data, bool status) where TData : class
    {
        return Json(
            new
                {
                    data,
                    status
                },
            JsonRequestBehavior.AllowGet);
    }


Do you really need to do that at all?

If your ajax call succeeds than HTTP 200 will be returned and your success jQuery callback will be called. If your call fails than just throw an exception and let jQuery call error callback after it received HTTP 500 from the server.

HTTP status codes are the proper way to inform the caller if the call has succeeded or failed for a certain reason.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜