Cyb*_*cop 1 ajax asp.net-mvc json asp.net-mvc-4
我正在关注一本名为"Asp.Net MVC4 in Action"的书.现在,在某些时候,他们说,我们可以使用操作方法选择器来区分它,而不是依赖于我们的代码中的if语句来检查请求是否是Ajax.他们所做的是创建一个AcceptAjaxAttribute包含以下代码的类
using System;
using System.Reflection;
using System.Web.Mvc;
namespace CustomAjax
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AcceptAjaxAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
return controllerContext.HttpContext.Request.IsAjaxRequest();
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及之前看起来像这样的控制器中的功能
var speaker = _repository.FindSpeaker(id);
if(Request.IsAjaxRequest())
{
return Json(speaker, JsonRequestBehaviour.AllowGet);
}
return View();
Run Code Online (Sandbox Code Playgroud)
已经改变了这样的事情
[AcceptAjax]
public ActionResult Details(int id)
{
var speaker = _repository.FindId(id);
return Json(speaker, JsonRequestBehavior.AllowGet);
}
[ActionName("Details")]
public ActionResult Details_NonAjax(int id)
{
var speaker = _repository.FindId(id);
return View();
}
Run Code Online (Sandbox Code Playgroud)
说实话,我不知道正在做什么或为什么我们创建了新类并使用了[AcceptAjax]的东西.有人可以向我解释一下.
在对if内部执行一个操作之前,在重构之后,您有两个操作,每个操作返回不同类型的结果.在ActionMethodSelectorAttribute用于选择基于某些条件下采取适当的行动.由于2个动作具有相同的名称(详细信息),因此ASP.NET MVC将使用此属性根据是否正在使用AJAX请求来选择其中一个.
但说实话,我根本不喜欢这种方法.你现在有2个动作并重复了var speaker = _repository.FindId(id);两次不太干的呼叫.如果你有这个不是更好吗?
[AcceptAjax]
public ActionResult Details(int id)
{
var speaker = _repository.FindId(id);
return View(speaker);
}
Run Code Online (Sandbox Code Playgroud)
如果你像我一样认为这更好,那么只需用AcceptAjaxAttribute动作过滤器替换你从书中得到的:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AcceptAjaxAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
var result = filterContext.Result as ViewResultBase;
if (result != null && result.Model != null)
{
filterContext.Result = new JsonResult
{
Data = result.Model,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
OnActionExecuted控制器操作完成运行后将调用该方法并返回一些结果.在此方法中,我们验证控制器操作是否返回ViewResultBase(ViewResult或PartialViewResult)以及是否已传递模型.如果是这种情况,我们只需用JsonResult替换这个结果.
如果您想避免使用此[AcceptAjax]属性装饰所有控制器操作,可以将其注册为以下内容中的全局操作过滤器~/App_Start/FilterConfig.cs:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new AcceptAjaxAttribute());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1700 次 |
| 最近记录: |