网站启动后如何更新区域路由?

How can I update an area route after the website is started?

我正在尝试在应用程序启动后更新路线 table。我在一个名为 "Pages" 的 MVC 区域中执行此操作。该网站有每个客户的自定义 URL:www.mydomain.com/Pages/CompanyName/

启动网站时它工作正常。它会选择所有现有客户 url,您可以导航到他们:

    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() }
        );

    }

但是,当创建新客户时,您无法访问该客户的 url,"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 错误。看来我破坏了路由 table.

Server Error in '/' Application.

The view 'BlankView' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/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。但是从这个post,我只能通过反射访问它? Get Areas associated with an MVC project

我得到了这个工作,并想与任何可能正在做同样或类似事情的人分享。我不确定这是否是最好的方法,但我很高兴它有效。

我做了两件事。第一,我将 AreaRegistrationContext 保存到静态成员以备后用。二、我没有尝试 add/remove 现有的映射。相反,我只是添加了一个新的。

就我而言,添加新客户的频率不高,因此该区域的映射不会太多。

这是我的决赛class。

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 区域路由完成这样的事情,祝您好运!