【问题标题】:ASP.Net MVC Route to UsernameASP.Net MVC 路由到用户名
【发布时间】:2021-08-08 00:44:52
【问题描述】:

我正在尝试使用用户名创建路由...

所以 URL 将是 mydomain.com/abrudtkhul(abrudtkhul 是用户名)

我的应用程序将具有基于用户名的公共配置文件(例如:http://delicious.com/abrudtkuhl)。我想复制这个 URL 方案。

如何在 ASP.Net MVC 中构建它?我也在使用会员/角色提供者。

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    这是你想要做的,首先定义你的路线图:

    routes.MapRoute(
                 "Users",
                  "{username}", 
                  new { controller = "User", action="index", username=""});
    

    这允许您做的是设置以下约定:

    • 控制器:用户(UserController 类型)
    • Action:Index(映射到 UserController 的 Index 方法)
    • 用户名:这是 Index 方法的参数

    因此,当您请求 URL http://mydomain.com/javier 时,这将被转换为对 UserController.Index(string username) 的调用,其中 username 设置为 javier 的值。

    现在,由于您计划使用 MembershipProvider 类,您想要更多类似的东西:

     public ActionResult Index(MembershipUser usr)
     {
        ViewData["Welcome"] = "Viewing " + usr.UserName;
    
        return View();
     }
    

    为此,您需要使用 ModelBinder 来完成从用户名绑定到 MembershipUser 类型的工作。为此,您需要创建自己的 ModelBinder 类型并将其应用于 Index 方法的用户参数。您的课程可能如下所示:

    public class UserBinder : IModelBinder
    {
       public ModelBinderResult BindModel(ModelBindingContext bindingContext)
       {
          var request = bindingContext.HttpContext.Request;
          var username = request["username"];
          MembershipUser user = Membership.GetUser(username);
    
          return new ModelBinderResult(user);
       }
    }
    

    这允许您将 Index 方法的声明更改为:

    public ActionResult Index([ModelBinder(typeof(UserBinder))] 
        MembershipUser usr)
    {
        ViewData["Welcome"] = "Viewing " + usr.Username;
        return View();
    }
    

    如您所见,我们已将 [ModelBinder(typeof(UserBinder))] 属性应用于方法的参数。这意味着在调用您的方法之前,您的 UserBinder 类型的逻辑将被调用,因此在调用该方法时,您将拥有 MembershipUser 类型的有效实例。

    【讨论】:

    • 这在最近的 MVC 版本中发生了变化,现在应该是:object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    • 我在模型 Binder 为什么得到空用户名?
    • @Keith 一切正常,但 url 路由不工作
    【解决方案2】:

    如果您想拥有一些其他功能控制器,如帐户、管理员、配置文件、设置等,您可能需要考虑不允许某些类型的用户名。此外,您可能希望您的静态内容不触发“用户名”路由。为了实现这种功能(类似于 twitter url 的处理方式),您可以使用以下路由:

    // do not route the following
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("content/{*pathInfo}"); 
    routes.IgnoreRoute("images/{*pathInfo}");
    
    // route the following based on the controller constraints
    routes.MapRoute(
        "Default",                                              // Route name
        "{controller}/{action}/{id}",                           // URL with parameters
        new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        , new { controller = @"(admin|help|profile|settings)" } // Constraints
    );
    
    // this will catch the remaining allowed usernames
    routes.MapRoute(
        "Users",
        "{username}",
        new { controller = "Users", action = "View", username = "" }
    );
    

    然后,您需要为约束字符串中的每个标记(例如 admin、help、profile、settings)拥有一个控制器,以及一个名为 Users 的控制器,当然还有这个示例中的默认控制器 Home .

    如果您有很多不想允许的用户名,那么您可以考虑通过创建自定义路由处理程序来使用更动态的方法。

    【讨论】:

    • 指定约束是正确的方法。没有其他东西对我有用。它将继续无限制地使用默认路由。感谢您分享您的解决方案。
    • 是的,我的也可以在添加约束时工作。你认为为什么会这样?
    • 如何使用 asp.net core 实现这一点?
    【解决方案3】:

    你可以有一个看起来像这样的路线:

    {username}
    

    默认为

    Controller = "Users"
    

    对于成品:

        routes.MapRoute(
                        "Users",
                        "{username}",
                        new { controller = "Users" }
    

    因此,用户名是唯一的 url 参数,MVC 假定它将它传递给用户控制器。

    【讨论】:

    • 好吧,我有那个......但由于某种原因它不起作用。我该如何处理视图?
    • 我认为他们都有相同的观点。只要您调用 View(string) 重载,并且 View 的 aspx 位于 Views 下的 Users 子目录中,您就可以随意调用您的视图。
    • 您还必须指定操作。将新部分更改为:new { controller = "Users", action = "Show" } 或任何你想命名的东西
    【解决方案4】:

    您是否尝试将其作为参数传递给控制器​​?

    理论上你可以这样做:

    routes.MapRoute("name", "{user}/{controller}/{action}", new { controller = "blah", action = "blah", user = "" })

    我对 ASP.NET 路由不太熟悉,但我认为 应该 工作。

    【讨论】:

      【解决方案5】:
      routes.MapRoute(
                   "Users",
                    "{username}", 
                    new { controller = "Users", action="ShowUser", username=""});
      

      好的,这将默认用户名参数为 {username} 的值

      所以即使你写了 username="" 它也会知道传递 {username} 的值 .. 凭借字符串匹配。

      这是预期的

      用于网址形式

      http://website.com/username

      • 用户控制器
      • ShowUser 操作(控制器中的方法)
      • ShowUser 操作(方法)上的用户名参数

      【讨论】:

        猜你喜欢
        • 2016-02-10
        • 1970-01-01
        • 2013-02-14
        • 2014-09-11
        • 1970-01-01
        • 2016-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多