我已按照标记为此主题How to change route to username after logged in?的正确答案,我的要求正是问题所在。但是,当我注册一个新用户(我使用用户名而不是电子邮件)时,重定向不遵循我的自定义路由。
例如,当我使用username = Janet注册时,URL看起来像localhost/?username=Janet
并抛出一个错误。但是,如果我手动删除“/?username =”并保留localhost/Janet
,则会显示我的应用程序的登录页面。
我尝试使用我的注册帖法返回RedirectToAction("Index","Home");
,但没有运气。
有人可以帮助我并告诉我我做错了什么吗?
路线配置
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Username_Default",
url: "{username}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { username = new OwinUsernameConstraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
用户名约束
public class OwinUsernameConstraint : IRouteConstraint
{
private object synclock = new object();
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (parameterName == null)
throw new ArgumentNullException("parameterName");
if (values == null)
throw new ArgumentNullException("values");
object value;
if (values.TryGetValue(parameterName, out value) && value != null)
{
string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
return this.GetUsernameList(httpContext).Contains(valueString);
}
return false;
}
private IEnumerable<string> GetUsernameList(HttpContextBase httpContext)
{
string key = "UsernameConstraint.GetUsernameList";
var usernames = httpContext.Cache[key];
if (usernames == null)
{
lock (synclock)
{
usernames = httpContext.Cache[key];
if (usernames == null)
{
// Retrieve the list of usernames from the database
using (var db = ApplicationDbContext.Create())
{
usernames = (from users in db.Users
select users.UserName).ToList();
}
httpContext.Cache.Insert(
key: key,
value: usernames,
dependencies: null,
absoluteExpiration: Cache.NoAbsoluteExpiration,
slidingExpiration: TimeSpan.FromSeconds(15),
priority: CacheItemPriority.NotRemovable,
onRemoveCallback: null);
}
}
}
return (IEnumerable<string>)usernames;
}
}
注册控制器
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
return RedirectToAction("Index","Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
由于