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