我正在尝试在应用程序启动后更新路由表。我在名为“Pages”的MVC区域中这样做。该网站为每位客户提供自定义URL:www.mydomain.com/Pages/CompanyName/
启动网站时,它可以正常工作。它会获取所有现有客户的网址,您可以导航到它们:
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
List<Customer> custs = new CustBLL().getActiveCustomers();
string urlList = string.Join("|", custs.Select(c => c.UrlIdentifier).ToArray());
context.MapRoute(
"Pages_CUSTURL", // Route name
"Pages/{CUSTURL}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
constraints: new { CUSTURL = urlList }
);
context.MapRoute(
"Pages_default",
"Pages/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = new ControllerConstraint() }
);
}
但是,当创建新客户时,您无法访问该客户的网址,“www.mydomain.com/Pages/NewCompany/”,因为404会发生。
所以我尝试添加一个新功能“UpdateRouteRegistration()”,该功能在创建新客户后调用。
public static void UpdateRouteRegistration()
{
RouteCollection routes = RouteTable.Routes;
using (routes.GetWriteLock())
{
routes.Remove(RouteTable.Routes["Pages_CUSTURL"]);
List<Customer> custs = new CustBLL().getActiveCustomers();
string urlList = string.Join("|", custs.Select(c => c.UrlIdentifier).ToArray());
routes.MapRoute(
"Pages_CUSTURL", // Route name
"Pages/{CUSTURL}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
constraints: new { CUSTURL = urlList }
);
}
}
新功能不起作用。运行时没有错误,但之后我无法导航到任何地方。我收到一个BlankView错误。好像我破坏了路由表。
>应用程序中的服务器错误。未找到“BlankView”视图或其主视图,或者没有视图引擎支持搜索的位置。搜索了以下位置:
〜/ Views / Home / BlankView.aspx
〜/ Views / Home / BlankView.ascx
〜/ Views / Shared / BlankView.aspx
〜/ Views / Shared / BlankView.ascx
〜/ Views / Home / BlankView.cshtml
〜/ Views / Home / BlankView.vbhtml
〜/ Views / Shared / BlankView.cshtml
〜/ Views / Shared / BlankView.vbhtml
〜/ __ MVCSITEMAPPROVIDER / BlankView.ascx
我正在使用MVC 5.2.3。非常感谢任何帮助。
编辑:我想知道是否需要使用AreaRegistraitionContext。但是从这篇文章中,我只能使用反射访问它? Get Areas associated with an MVC project
答案 0 :(得分:1)
我得到了这个工作,并希望与任何可能做同样或类似事情的人分享。我不确定这是不是最好的方式,但我很高兴它有效。
我做了两件事。一,我将AreaRegistrationContext保存到静态成员以供以后使用。二,我没有尝试添加/删除现有的映射。相反,我刚刚添加了一个新的。
在我的情况下,新客户不会经常添加,因此该区域的映射不会太多。
这是我的最后一堂课。
public class PagesAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Pages";
}
}
public static AreaRegistrationContext AreaContext { get; set; }
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// save context to static for later use
AreaContext = context;
// get customers
List<Customer> custs = new CustBLL().getActiveCustomers();
// get list of domain urls
string urlList = string.Join("|", custs.Select(c => c.UrlIdentifier).ToArray());
// map customer URLs
context.MapRoute(
"Pages_CUSTURL", // Route name
"Pages/{CUSTURL}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
constraints: new { CUSTURL = urlList }
);
// general area mapping
context.MapRoute(
"Pages_default",
"Pages/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = new ControllerConstraint() }
);
}
public static void UpdateRouteRegistration(string newURLID)
{
// get context from static member
RouteCollection routes = AreaContext.Routes;
// get write lock to avoid threading issues
using (routes.GetWriteLock())
{
// add new company url to route table
AreaContext.MapRoute(
"Pages_CUSTURL_" + newURLID, // Route name
"Pages/{CUSTURL}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
constraints: new { CUSTURL = newURLID }
);
}
}
}
祝你好运,如果你想通过MVC区域路由来完成这样的事情!