asp.net-mvc - ASP.NET MVC 4 路由用户名/操作问题

标签 asp.net-mvc asp.net-mvc-4 routes asp.net-mvc-routing

我目前正在开发一个 asp.net mvc 4 应用程序,我需要以下类型的 url:

需要路由的url

  1. http://www.mysite.com/foo/user1 <------- {username}
  2. http://www.mysite.com/foo/edit
  3. http://www.mysite.com/foo/delete/1
  4. http://www.mysite.com/bar/user1 <------- {username}
  5. http://www.mysite.com/bar/edit
  6. http://www.mysite.com/bar/delete/1


我遇到的问题是,当前 {username} 被视为一个 Action ,因此为了解决这个问题,我实现了以下路由,但这意味着每次我想要实现一个新 Action ,或者有一个需要的 Controller {username},我必须更新我的路线:

仅显示 Foo 路线
routes.MapRoute("FooSomeAction", "foo/someaction", new { controller = "Food", action = "SomeAction" });            
routes.MapRoute("FooDelete", "foo/delete/{id}", new { controller = "Food", action = "Delete" });            


routes.MapRoute(
    "FooProfile",
    "foo/{username}",
    new { controller = "Foo", action = "Index", username = "" }
);


// Default route
routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

2 个问题

1)有什么方法可以在不硬编码所有路由的情况下实现上述网址?

2) 处理某人使用的用户名恰好与 Controller 或操作名称同名的情况的最佳方法是什么?

网络阴影

最佳答案

您可以创建一个自定义路由约束,以检查用户名是否存在于 Controller 的可能操作中。如果它找到一个 Action 匹配,它就会失败并使用你的默认路由(例如编辑)。出于性能原因,您可能希望缓存该列表,但我将其留给您。

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

关于asp.net-mvc - ASP.NET MVC 4 路由用户名/操作问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15135854/

相关文章:

asp.net-mvc - TDD 工作单元模式 Moq 无法实例化类错误代理

javascript - 如何在Asp.Net Mvc4中检查验证码后传递Email Id值?

asp.net 4.5 自定义成员(member)提供程序配置抛出奇怪的异常

java - 使用 Java 的 Akka 远程路由

c# - MVC 如何防止通过名称调用 Action Method 而只允许通过路由调用它

javascript - 资源解释为样式表但使用 MIME 类型文本/javascript 传输

c# - 异常过滤器在 web api 中不起作用

javascript - 不推荐使用 Vue 路由器 addRoutes,但我想向 Vue 路由器添加路由数组

json - JavaScriptSerializer 和 Controller Method Json 之间的区别

c# - 如何在 MVC 中托管多个 IoC 驱动的 WCF 服务?