MVC4 自定义路由 - 验证个性化网址
MVC4 Custom Routing - Validating Personalized Urls
我有一个正在开发的 MVC4 网站需要一些自定义路由。这是一个只有几页的简单网站。例如:
/index
/plan
/investing
... etc.. a few others
站点管理员可以通过管理面板创建 "branded" 站点,这些站点基本上反映了上述内容,但交换了一些内容,例如品牌公司名称、徽标等。创建后,URL 看起来像
/{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,因为它认为这是一个动作,但没有找到。当我取消评论时,索引页面可以工作,但是个别操作不会 /plan 例如因为它认为它是一个 pUrl 并且无法在数据库中找到它。
无论如何,很抱歉问了这么长的问题。非常感谢任何有关如何设置的帮助或建议。
詹姆斯
问题是 MVC 将使用第一个匹配 url 并且因为第二个路由是:
routes.MapRoute(
name: "Default",
url: "{action}",
defaults: new { controller = "Default", action = "Index" }
);
并且匹配您的 /{personalizedurl}/ 它将路由到 Default/{action}。
你想要的有点棘手!我假设个性化是动态的,而不是一些静态的品牌公司列表,并且您不希望每次 add/remove 一个新公司时都重新编译和部署。
我想你需要在控制器中处理这个,它在路由中不会很好地工作;除非它是个性化公司的静态列表。您将需要能够检查第一部分是否是您的操作之一,并检查它是否是一家有效的公司,我会给您一个简单的字符串数组示例。我相信您将通过为您的个性化公司查询某种数据存储来构建数组。我还创建了一个名为 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);
}
}
我有一个正在开发的 MVC4 网站需要一些自定义路由。这是一个只有几页的简单网站。例如:
/index
/plan
/investing
... etc.. a few others
站点管理员可以通过管理面板创建 "branded" 站点,这些站点基本上反映了上述内容,但交换了一些内容,例如品牌公司名称、徽标等。创建后,URL 看起来像
/{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,因为它认为这是一个动作,但没有找到。当我取消评论时,索引页面可以工作,但是个别操作不会 /plan 例如因为它认为它是一个 pUrl 并且无法在数据库中找到它。
无论如何,很抱歉问了这么长的问题。非常感谢任何有关如何设置的帮助或建议。
詹姆斯
问题是 MVC 将使用第一个匹配 url 并且因为第二个路由是:
routes.MapRoute(
name: "Default",
url: "{action}",
defaults: new { controller = "Default", action = "Index" }
);
并且匹配您的 /{personalizedurl}/ 它将路由到 Default/{action}。
你想要的有点棘手!我假设个性化是动态的,而不是一些静态的品牌公司列表,并且您不希望每次 add/remove 一个新公司时都重新编译和部署。
我想你需要在控制器中处理这个,它在路由中不会很好地工作;除非它是个性化公司的静态列表。您将需要能够检查第一部分是否是您的操作之一,并检查它是否是一家有效的公司,我会给您一个简单的字符串数组示例。我相信您将通过为您的个性化公司查询某种数据存储来构建数组。我还创建了一个名为 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);
}
}