使用APS.NET路由,您如何根据请求是否作为AJAX调用发出有条件路由到单独的操作?
例如在控制器上我可能有两个动作:
public ActionResult List() { return View(); }
和
public ActionResult ListJSON() { return Content(...); }
我希望这两个操作具有相同的URL,但如果请求作为AJAX调用发起,则应调用ListJSON()。
答案 0 :(得分:2)
为什么在代码相同时使用2个单独的操作?视图结果不同。
怎么样:
public ActionResult List()
{
var model = ...
if (Request.IsAjaxRequest())
{
return View(model);
}
return Json(model);
}
显然,如果你必须在每一个控制器动作中都这样做,这很快就会变成一场彻头彻尾的噩梦。
因此,您可以将此逻辑外部化为自定义操作过滤器:
[MyFilter]
public ActionResult List()
{
var model = ...
return View(model);
}
你可以像这样定义MyFilterAttribute
:
public class MyFilterAttribute: ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var result = filterContext.Result as ViewResultBase;
if (result != null)
{
filterContext.Result = new JsonResult
{
Data = result.Model,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
}
您还可以将此操作过滤器注册为全局操作过滤器,以避免将其置于每个控制器和需要它的操作上。
更新:
如评论部分所述,OP似乎需要2个不同的操作。为此,您可以使用自定义路线:
public class MyRoute : Route
{
public MyRoute(string url, object defaults) :
base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var rd = base.GetRouteData(httpContext);
if (rd == null)
{
return null;
}
if (httpContext.Request.IsAjaxRequest())
{
rd.Values["action"] = rd.GetRequiredString("action") + "json";
}
return rd;
}
}
将在Application_Start
注册:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(
"Default",
new MyRoute(
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
)
);
}
答案 1 :(得分:0)
事实证明,您可以通过实施IRouteConstraint
轻松定义自己的路线限制。
这样的事情:
public class AjaxRouteConstraint : IRouteConstraint {
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
return httpContext.Request.IsAjaxRequest();
}
}
然后在路线上使用此约束。诀窍是具有此约束的路径必须在没有约束的路径之前,否则永远不会调用ajax路由(非-ajax路由将始终匹配)。
在URL生成方面,这可能会产生一些后果。但我没有对这些进行过大量测试。