这个问题似乎与地区路线登记的顺序有关。由于我没有找到有关区域路线如何映射的确凿文档,也不认为依赖任何特定顺序是安全的,我继续创建一个新类来封装我可以从不同的路径调用的路由路线文件。这基本上“模块化”了一个区域,以便它可以用作一组路由来附加到其他一些URL前缀。
的基本思想是仿效Django's ability to include other urlconfs,这样我可以做类似下面的内FooAreaRegistration
:
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});
}
,并拥有所有的路线获得注册以有序的方式,使foo/bar
没有得到混淆``foo_default“路线。
以下是AreaModule类的全部源代码,任何人这是兴趣:
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
}
}
菲尔哈克有很大的[路线调试器(http://haacked.com/archive/2008/03/ 13/url-routing-debugger.aspx),让你知道你的路线在哪里。 – 2012-03-30 16:08:27
您可以粘贴到目前为止创建的路线列表吗? – mfanto 2012-03-30 16:11:32