簡體   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