ASP.NET MVC Ajax Actions 结果封装
我希望将 ASP.NET MVC 上的任何 AJAX 调用的每个结果封装到一个 JSON 对象中,该对象应该类似于: AjaxResult { status, data }
其中 status 将包含一个枚举值,描述调用是否成功、错误、身份验证过期等。这将使客户端代码能够重定向到登录页面等。
我尝试通过重写来捕获 Ajax 请求OnActionExecuted,并尝试使用以下代码渲染相应操作返回的结果,但此解决方案似乎运行缓慢。你有更好的主意吗?
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 };
}
}
}
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);
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 };
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么你需要这个?
创建您的自定义 ApplicationController 并从此派生所有控制器。
在 ApplicationController 中实现方法
Json()
其中 dataWhy you need this?
Create your custom ApplicationController and derive all controllers from this one.
In ApplicationController implement the method
Json<data>()
where data你真的需要这样做吗?
如果您的 ajax 调用成功,将返回 HTTP 200,并且将调用您的成功 jQuery 回调。如果您的调用失败,则只需抛出异常并让 jQuery 在从服务器收到 HTTP 500 后调用错误回调。
HTTP 状态代码是通知调用者调用是否因某种原因成功或失败的正确方法。
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.