Das Problem scheint mit der Reihenfolge in Verbindung zu stehen, in der Bereichsrouten registriert werden. Da ich keine schlüssige Dokumentation darüber gefunden habe, wie Gebietsrouten abgebildet werden, und nicht sicher bin, dass man sich auf eine bestimmte Reihenfolge verlassen kann, habe ich eine neue Klasse erstellt, um das Routing, das ich aufrufen kann, in ein anderes zu kapseln Routen-Datei. Dies "modularisiert" im Grunde einen Bereich, so dass er als eine Reihe von Routen verwendet werden kann, die an ein anderes URL-Präfix angehängt werden.
Die Grundidee ist Django's ability to include other urlconfs zu emulieren, so dass ich etwas wie die folgenden innerhalb FooAreaRegistration
tun könnte:
public override void RegisterArea(AreaRegistrationContext context)
{
new BarAreaModule().RegisterRoutes(namePrefix:"bar", urlPrefix:"foo/", context.Routes);
context.MapRoute("foo_default", "foo/{controller}/{action}/{id}", new{controller="Default", action="Index", id=UrlParameter.Optional});
}
und habe alle Routen in einer geordneten Art und Weise registrieren lassen, so dass foo/bar
nicht verwirrt bekommen mit die Route "foo_default".
Hier finden Sie die gesamte Quelle der AreaModule Klasse, für jeden, der interessiert ist:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
namespace Gov.Wa.Hecb.UI.Portal.Areas
{
/// <summary>
/// Allows a group of functionality to be registered to any given url prefix. This is to be used to replace an Area in cases
/// where an Area is either a sub-module to another area, or if an area's functionality is to be parameterized and reused in
/// multiple urls.
/// </summary>
public abstract class AreaModule
{
public abstract string AreaName { get; }
/// <summary>
/// Registers all routes necessary for this Module to function with the given url prefix
/// </summary>
/// <param name="namePrefix"></param>
/// <param name="urlPrefix">a slash-appended string representing the url to match up to the module</param>
/// <param name="routes"></param>
public void RegisterRoutes(string namePrefix, string urlPrefix, RouteCollection routes)
{
if (string.IsNullOrEmpty(namePrefix))
throw new ArgumentException("namePrefix cannot be null or empty", "namePrefix");
if (string.IsNullOrEmpty(urlPrefix))
throw new ArgumentException("urlPrefix cannot be null or empty", "urlPrefix");
if (routes == null)
throw new ArgumentNullException("routes");
var context = new AreaModuleContext(AreaName, namePrefix, urlPrefix, routes);
var thisNamespace = GetType().Namespace;
if (thisNamespace != null)
context.Namespaces.Add(thisNamespace + ".*");
RegisterRoutes(context);
}
protected abstract void RegisterRoutes(AreaModuleContext context);
}
public class AreaModuleContext
{
#region Private
private readonly HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
#endregion
#region Constructors
public AreaModuleContext(string areaName, string namePrefix, string urlPrefix, RouteCollection routes, object state = null)
{
if (String.IsNullOrEmpty(areaName))
throw new ArgumentException("areaName cannot be null or empty", "areaName");
if (string.IsNullOrEmpty(namePrefix))
throw new ArgumentException("namePrefix cannot be null or empty", "namePrefix");
if (string.IsNullOrEmpty(urlPrefix))
throw new ArgumentException("urlPrefix cannot be null or empty", "urlPrefix");
if (routes == null)
throw new ArgumentNullException("routes");
AreaName = areaName;
NamePrefix = namePrefix;
UrlPrefix = urlPrefix;
Routes = routes;
State = state;
}
#endregion
#region Properties
public string AreaName { get; private set; }
public string NamePrefix { get; private set; }
public string UrlPrefix { get; private set; }
public ICollection<string> Namespaces
{
get { return _namespaces; }
}
public RouteCollection Routes { get; private set; }
public object State { get; private set; }
#endregion
#region Route Mapping
public Route MapRoute(string name, string url)
{
return MapRoute(name, url, (object) null /* defaults */);
}
public Route MapRoute(string name, string url, object defaults)
{
return MapRoute(name, url, defaults, (object) null /* constraints */);
}
public Route MapRoute(string name, string url, object defaults, object constraints)
{
return MapRoute(name, url, defaults, constraints, null /* namespaces */);
}
public Route MapRoute(string name, string url, string[] namespaces)
{
return MapRoute(name, url, null /* defaults */, namespaces);
}
public Route MapRoute(string name, string url, object defaults, string[] namespaces)
{
return MapRoute(name, url, defaults, null /* constraints */, namespaces);
}
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces)
{
if (namespaces == null && Namespaces != null)
namespaces = Namespaces.ToArray();
var route = Routes.MapRoute(NamePrefix + name, UrlPrefix + url, defaults, constraints, namespaces);
route.DataTokens["area"] = AreaName;
// disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
// controllers belonging to other areas
var useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;
return route;
}
#endregion
}
}
Phil Haack hat eine große [Routen Debugger] (http://haacked.com/archive/2008/03/ 13/url-routing-debugger.aspx), damit Sie wissen, wohin Ihre Routen gehen. –
Können Sie die Liste der Routen einfügen, die Sie bisher erstellt haben? – mfanto