[英]Fallback Route in ASP MVC if action doesn't exist
MVC {controller}/{action}/{id}
的默认路由在很大程度上很有帮助,因为如果传入的url不包含参数但可以设置默认值,则可以设置默认值控制器上不存在动作时的默认动作?
我要实现的目标是能够使控制器执行几个特定的操作,然后使它具有自己的包包,该包包使用url从基本CMS中获取内容。
例如,产品控制器将类似于:
public class ProductsController: Controller{
public ActionResult ProductInfo(int id){...}
public ActionResult AddProduct(){...}
public ActionResult ContentFromCms(string url){...}
}
默认路由将处理/Products/ProductInfo/54
等,但是/Products/Suppliers/Acme
的请求网址将返回ContentFromCms("Suppliers/Acme");
(将url作为参数发送会更好,但不需要,而从Request中获取它的无参数方法会很好)。
目前,我可以想到两种实现此目的的方法:
创建一个反映控制器的新约束,以查看它是否确实具有给定名称的动作,并在{controller}/{action}/{id}
路由中使用该约束,从而使我可以使用更通用的包罗万象的内容,例如{controller}/{*url}
。
在控制器上覆盖HandleUnknownAction
。
第一种方法似乎是检查此问题的一种round回方式,而第二种方法我不太了解MVC和路由的内部知识,无法知道如何进行。
更新资料
没有任何回复,但我想我会离开解决方案的情况下,以防将来有人发现此问题或有人建议改进/更好的方法
对于想要拥有自己的功能包的控制器,我给他们提供了一个界面
interface IHasDefaultController
{
public string DefaultRouteName { get; }
System.Web.Mvc.ActionResult DefaultAction();
}
然后,我从ControllerActionInvoker派生并覆盖FindAction。 这将调用基本的FindAction,然后,如果基本返回null,并且控制器隐含使用默认操作名再次调用FindAction的接口。
protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
{
ActionDescriptor foundAction = base.FindAction(controllerContext, controllerDescriptor, actionName);
if (foundAction == null && controllerDescriptor.ControllerType.GetInterface("Kingsweb.Controllers.IWikiController") != null)
{
foundAction = base.FindAction(controllerContext, controllerDescriptor, "WikiPage");
}
return foundAction;
}
因为我也希望从路由中获取参数,所以我还在控制器上默认Actionresult的开头替换了RouteData。
ControllerContext.RouteData = Url.RouteCollection[DefaultRouteName].GetRouteData(HttpContext);
您的方法还不错。 作为旁注:
更换
controllerDescriptor.ControllerType.GetInterface("Kingsweb.Controllers.IWikiController") != null
与
typeof(Kingsweb.Controllers.IWikiController).IsAssignableFrom(controllerDescriptor.ControllerType)
这是一种更强类型的方式,然后通过字符串传递接口名称:如果明天更改名称空间该怎么办?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.