您可以创建一个自定义路由约束来检查用户名是否存在于控制器的可能操作中。如果它找到一个动作匹配,它会失败并使用你的默认路由(例如编辑)。出于性能原因,您可能希望缓存该列表,但我将其留给您。
private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}
public static List<string> GetActionNames(string controllerName)
{
controllerName = controllerName + "Controller";
var controller = GetSubClasses<Controller>().FirstOrDefault(c => c.Name == controllerName);
var names = new List<string>();
if (controller != null)
{
var methods = controller.GetMethods(BindingFlags.Public | BindingFlags.Instance);
foreach (var info in methods)
{
if (info.ReturnType == typeof(ActionResult))
{
names.Add(info.Name);
}
}
}
return names;
}
public class UsernameNotAction : IRouteConstraint
{
public bool Match
(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
)
{
int i = 0;
var username = values["username"];
var actionList = GetActionNames(values["controller"].ToString());
return !actionList.Any(a => a.ToUpper() == username.ToString().ToUpper());
}
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"FooProfile",
"{controller}/{username}",
new { controller = "Home", action = "Index2", username = "" },
new { IsParameterAction = new UsernameNotAction() }
);
// Default route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}