我已经设法使用稍微修改的解决方案解决了我的问题:http ://erraticdev.blogspot.com/2011/03/removing-route-values-from-linksurls-in.html
罗伯特的解决方案不包括命名空间,所以我在下面做了一些调整:
public static class CustomRouteExtensions
{
public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults)
{
return MapRoute(routes, name, url, excludeRouteValueNames, defaults, null, null);
}
public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults, string[] namespaces)
{
return MapRoute(routes, name, url, excludeRouteValueNames, defaults, null, namespaces);
}
public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults, object constraints)
{
return MapRoute(routes, name, url, excludeRouteValueNames, defaults, constraints, null);
}
public static Route MapRoute(this RouteCollection routes, string name, string url, string excludeRouteValueNames, object defaults, object constraints, string[] namespaces)
{
if (routes == null)
throw new ArgumentNullException("routes");
if (url == null)
throw new ArgumentNullException("url");
Route item = new CustomRoute(url, new MvcRouteHandler(), excludeRouteValueNames)
{
Defaults = new RouteValueDictionary(defaults),
Constraints = new RouteValueDictionary(constraints),
DataTokens = new RouteValueDictionary()
};
if ((namespaces != null) && (namespaces.Length > 0))
item.DataTokens["Namespaces"] = namespaces;
routes.Add(name, item);
return item;
}
}
我的自定义Route
看起来像这样:
public class CustomRoute : Route
{
#region Properties
public ReadOnlyCollection<string> ExcludedRouteValuesNames { get; private set; }
#endregion
#region Constructor
public CustomRoute(string url, IRouteHandler routeHandler, string commaSeparatedRouteValueNames)
: this(url, routeHandler, (commaSeparatedRouteValueNames ?? string.Empty).Split(','))
{
}
public CustomRoute(string url, IRouteHandler routeHandler, params string[] excludeRouteValuesNames)
: base(url, routeHandler)
{
ExcludedRouteValuesNames = new ReadOnlyCollection<string>(excludeRouteValuesNames.Select(val => val.Trim()).ToList());
}
#endregion
#region Route overrides
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
if (requestContext == null)
throw new ArgumentNullException("requestContext");
// create new route data and include only non-excluded values
var excludedRouteData = new RouteData(this, this.RouteHandler);
// add route values
requestContext.RouteData.Values
.Where(pair => !this.ExcludedRouteValuesNames.Contains(pair.Key, StringComparer.OrdinalIgnoreCase))
.ToList()
.ForEach(pair => excludedRouteData.Values.Add(pair.Key, pair.Value));
// add data tokens
requestContext.RouteData.DataTokens
.ToList()
.ForEach(pair => excludedRouteData.DataTokens.Add(pair.Key, pair.Value));
// intermediary request context
var currentContext = new RequestContext(new HttpContextWrapper(HttpContext.Current), excludedRouteData);
// create new URL route values and include only none-excluded values
var excludedRouteValues = new RouteValueDictionary(
values
.Where(v => !this.ExcludedRouteValuesNames.Contains(v.Key, StringComparer.OrdinalIgnoreCase))
.ToDictionary(pair => pair.Key, pair => pair.Value)
);
var result = base.GetVirtualPath(currentContext, excludedRouteValues);
return result;
}
#endregion
}
我的新Route.MapRoute
外观是这样的:
routes.MapRoute("Product",
"{SeName}",
"productIdd",
new { controller = "Catalog", action = "UrlType" },
new[] { "Nop.Plugin.FreshEgg.Seo.Controllers" });