2016-08-03 70 views
1

我有一個網站在MVC4,我正在開發,需要一些自定義路由。這是一個簡單的網頁,只有幾頁。例如:MVC4自定義路由 - 驗證個性化網址

/index 
/plan 
/investing 
... etc.. a few others 

通過管理員面板站點管理員可以創建「品牌」的網站,基本上反映了上述內容,但換出像品牌公司名稱的幾件事情,標誌等。一旦創建,網址看起來像

/{personalizedurl}/index 
/{personalizedurl}/plan 
/{personalizedurl}/investing 

...等...(完全相同的頁面作爲非品牌網頁。

我與控制器方法的行爲過濾器屬性驗證個性化的網址,並返回404如果沒有在數據庫中找到。

這裏是我的行動的一個示例:

[ValidatePersonalizedUrl] 
[ActionName("plan")] 
public ActionResult Plan(string url) 
{ 
    return View("Plan", GetSite(url)); 
} 

易peasy到目前爲止和工作得很好,有以下途徑:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
     name: "Admin", 
     url: "Admin/{action}/{id}", 
     defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional } 
    ); 

    routes.MapRoute(
     name: "Default", 
     url: "{action}", 
     defaults: new { controller = "Default", action = "Index" } 
    ); 

    routes.MapRoute(
     "Branded", // Route name 
     "{url}/{action}", // URL with parameters 
     new { controller = "Default", action = "Index" } // Parameter defaults 
    ); 

/* 
    routes.MapRoute(
     "BrandedHome", // Route name 
     "{url}/", // URL with parameters 
     new { controller = "Default", action = "Index" } // Parameter defaults 
    ); 
*/ 
} 

我現在的問題是與底部註釋掉了路線。我希望能夠到/ {individualurl} /並找到正確的操作(默認控制器中的索引操作)。現在底線被註釋掉了,我得到了一個404,因爲它認爲它是一個行爲,並沒有找到它。當我對它進行取消註釋時,索引頁面可以正常工作,但是單個操作不會/因爲它認爲它是pUrl而無法在數據庫中找到它。

無論如何,對於長期的問題抱歉。任何幫助或建議如何設置這將不勝感激。

詹姆斯

回答

0

的問題是,MVC將使用第一個匹配的URL,自第二條路線是:

routes.MapRoute(
    name: "Default", 
    url: "{action}", 
    defaults: new { controller = "Default", action = "Index" } 
); 

,並符合你/{personalizedurl}/它將路由默認/{行動}。

你想要什麼變得有點棘手!我假設個性化是動態的,而不是某些品牌公司的靜態列表,並且您不希望每次添加/刪除新的時重新編譯和部署。

我想你將需要在控制器中處理這個,它將不能很好地路由;除非它是個性化公司的靜態列表。你將需要能夠檢查第一部分是否是你的行爲之一,並檢查它是否是一個有效的公司,我會給你一個簡單的字符串數組的例子。我相信你會通過查詢某種數據存儲爲你的個性化公司建立數組。我還創建了一個名爲PersonalizedViewModel的快速視圖模型,該模型接受名稱的字符串。

你的路由將被簡化:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

    routes.MapRoute(
    name: "Admin", 
    url: "Admin/{action}/{id}", 
    defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional } 
); 

    routes.MapRoute(
    name: "Default", 
    url: "{url}/{action}", 
    defaults: new { controller = "Default", action = "Index", url = UrlParameter.Optional } 
); 
} 

這裏是我的示例使用視圖模型:

public class PersonalizedViewModel 
{ 
    public string Name { get; private set; } 
    public PersonalizedViewModel(string name) 
    { 
    Name = name; 
    } 
} 

和默認控制器:

public class DefaultController : Controller 
{ 
    private static readonly IEnumerable<string> personalizedSites = new[] { "companyA", "companyB" }; 
    private static readonly IEnumerable<string> actions = new[] { "index", "plan", "investing", "etc" }; 

    public ActionResult Index(string url) 
    { 
    string view; 
    PersonalizedViewModel viewModel; 
    if (string.IsNullOrWhiteSpace(url) || actions.Any(a => a.Equals(url, StringComparison.CurrentCultureIgnoreCase))) 
    { 
     view = url; 
     viewModel = new PersonalizedViewModel("Default"); 
    } 
    else if (personalizedSites.Any(s => s.Equals(url, StringComparison.CurrentCultureIgnoreCase))) 
    { 
     view = "index"; 
     viewModel = new PersonalizedViewModel(url); 
    } 
    else 
    { 
     return View("Error404"); 
    } 

    return View(view, viewModel); 
    } 

    public ActionResult Plan(string url) 
    { 
    PersonalizedViewModel viewModel; 
    if (string.IsNullOrWhiteSpace(url)) 
    { 
     viewModel = new PersonalizedViewModel("Default"); 
    } 
    else if (personalizedSites.Any(s => s.Equals(url, StringComparison.CurrentCultureIgnoreCase))) 
    { 
     viewModel = new PersonalizedViewModel(url); 
    } 
    else 
    { 
     return View("Error404"); 
    } 

    return View(viewModel); 
    } 
}