【发布时间】:2021-08-08 00:44:52
【问题描述】:
我正在尝试使用用户名创建路由...
所以 URL 将是 mydomain.com/abrudtkhul(abrudtkhul 是用户名)
我的应用程序将具有基于用户名的公共配置文件(例如:http://delicious.com/abrudtkuhl)。我想复制这个 URL 方案。
如何在 ASP.Net MVC 中构建它?我也在使用会员/角色提供者。
【问题讨论】:
标签: asp.net-mvc
我正在尝试使用用户名创建路由...
所以 URL 将是 mydomain.com/abrudtkhul(abrudtkhul 是用户名)
我的应用程序将具有基于用户名的公共配置文件(例如:http://delicious.com/abrudtkuhl)。我想复制这个 URL 方案。
如何在 ASP.Net MVC 中构建它?我也在使用会员/角色提供者。
【问题讨论】:
标签: asp.net-mvc
这是你想要做的,首先定义你的路线图:
routes.MapRoute(
"Users",
"{username}",
new { controller = "User", action="index", username=""});
这允许您做的是设置以下约定:
因此,当您请求 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 类型的有效实例。
【讨论】:
如果您想拥有一些其他功能控制器,如帐户、管理员、配置文件、设置等,您可能需要考虑不允许某些类型的用户名。此外,您可能希望您的静态内容不触发“用户名”路由。为了实现这种功能(类似于 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 .
如果您有很多不想允许的用户名,那么您可以考虑通过创建自定义路由处理程序来使用更动态的方法。
【讨论】:
你可以有一个看起来像这样的路线:
{username}
默认为
Controller = "Users"
对于成品:
routes.MapRoute(
"Users",
"{username}",
new { controller = "Users" }
因此,用户名是唯一的 url 参数,MVC 假定它将它传递给用户控制器。
【讨论】:
您是否尝试将其作为参数传递给控制器?
理论上你可以这样做:
routes.MapRoute("name", "{user}/{controller}/{action}", new { controller = "blah", action = "blah", user = "" })
我对 ASP.NET 路由不太熟悉,但我认为 应该 工作。
【讨论】:
routes.MapRoute(
"Users",
"{username}",
new { controller = "Users", action="ShowUser", username=""});
好的,这将默认用户名参数为 {username} 的值
所以即使你写了 username="" 它也会知道传递 {username} 的值 .. 凭借字符串匹配。
这是预期的
用于网址形式
【讨论】: