2

ASP.NET MVC での AJAX 呼び出しのすべての結果を、AjaxResult { status, data } のような JSON オブジェクトにエンベロープしたいと考えています。

status には、呼び出しが成功したか、エラーが発生したか、認証が期限切れになったかなどを示す列挙値が含まれます。これにより、クライアント側のコードがログイン ページなどにリダイレクトできるようになります。

OnActionExecuted をオーバーライドして Ajax リクエストをキャッチし、次のコードを使用して対応するアクションの結果によって返されたものをレンダリングしようとしましたが、このソリューションは動作が遅いようです。もっと良いアイデアはありますか?

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);
                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 };
        }
    }
}
4

2 に答える 2

0

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.

于 2011-06-24T22:36:37.020 に答える
0

なぜこれが必要なのですか?カスタム ApplicationController を作成し、このコントローラーからすべてのコントローラーを派生させます。ApplicationController でメソッドを実装しJson<data>()ます。

   public JsonResult Json<TData>(TData data, bool status) where TData : class
    {
        return Json(
            new
                {
                    data,
                    status
                },
            JsonRequestBehavior.AllowGet);
    }
于 2011-06-24T08:22:48.683 に答える