簡體   English   中英

MVC4自定義路由 - 驗證個性化URL

[英]MVC4 Custom Routing - Validating Personalized Urls

我在MVC4中有一個網站,我正在開發,需要一些自定義路由。 這是一個有幾頁的簡單網站。 例如:

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

通過管理面板,網站管理員可以創建“品牌”網站,基本上反映上述內容,但交換一些東西,如品牌公司名稱,徽標等。一旦創建,網址將看起來像

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

......等...(與非品牌頁面完全相同的頁面。

我正在使用控制器方法上的操作過濾器屬性驗證個性化URL,如果在數據庫中找不到則返回404。

以下是我的一個行動示例:

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

到目前為止易於使用,並與以下路線很好地工作:

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
    );
*/
}

我目前遇到的問題是底部注釋掉的路線。 我希望能夠轉到/ {personalizedurl} /並讓它找到正確的操作(默認控制器中的索引操作)。 現在,底線被注釋掉了,我得到了404因為它認為它是一個動作並且沒有找到它。 當我取消注釋它時,索引頁面,然而單個操作沒有/計划,例如因為它認為它是一個pUrl而無法在數據庫中找到它。

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

詹姆士

問題是MVC將使用第一個匹配的URL,因為第二個路由是:

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

並且匹配您的/ {personalizedurl} /它將路由到Default / {action}。

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

我認為你需要在控制器中處理它,它在路由中不能很好地工作; 除非它是個性化公司的靜態列表。 您需要能夠檢查第一部分是否是您的某個操作,並檢查它是否是一個有效的公司,我將為您舉例說明簡單的字符串數組。 我相信您將通過為您的個性化公司查詢某種數據存儲來構建陣列。 我還創建了一個名為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);
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM