繁体   English   中英

如果不存在操作,则在ASP MVC中进行回退路由

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM