在我的MVC3应用中通常AccountController
,如果设置了returnUrl
(在我的情况下,我手动设置),它会调用Redirect(returnUrl)
。
假设我的返回网址为/Admin/HealthCheck
(确实如此)。当我调试时,我从重定向调用中获得了http://localhost:3279/Admin/HealthCheck
这样的URL。
然后,我将我的应用部署到http://localhost/Test
。在这种情况下,Redirect(returnUrl)
会将我重定向到http://localhost/Admin/HealthCheck
而不会预期的http://localhost/Test/Admin/HealthCheck
。
这里发生了什么?我该如何解决这个问题(如果可以修复的话)?
以下是(标准)MVC3 AccountController的片段;你可以看到我从查询字符串中获取返回URL的位置(例如http://localhost/Test/LogOn?ReturnUrl=/Admin/HealthCheck
,尽管是URL编码的)。
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
returnUrl = Request.Params["ReturnUrl"];
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
答案 0 :(得分:2)
(在我的情况下,我手动设置)
您实际上并未显示此手动设置的实现方式,但如果您使用/Admin/HealthCheck
这样的网址硬编码而不是使用网址助手来生成此网址,例如Url.Action("HealthCheck", "Admin")
,则不要指望奇迹发生。
您的LogOn
没问题。它做了它应该做的事情=>它重定向到作为参数传递的url。您的问题在于您设置此网址的方式。
结论:在ASP.NET MVC应用程序中,在处理url时总是使用url帮助程序。永远不要硬编码。
答案 1 :(得分:1)
对于您的Test
网址,您必须将ReturnUrl
设置为Test/Admin/HealthCheck
。
请注意MSDN Reference on Controller.Redirect()
:
创建一个重定向到指定URL的
RedirectResult
对象。
换句话说,如果您将"/Admin/HealthCheck"
作为参数,那么这就是重定向的确切位置。
答案 2 :(得分:1)
您需要使用Request.UrlReferrer.AbsoluteUri
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
string refUri = Request.UrlReferrer.AbsoluteUri;
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return Redirect(refUri + "#/account/login");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
答案 3 :(得分:0)
如果您的结束域将是www.domain.com/Test/Admin/HealthCheck
,您可能需要更改项目的虚拟目录,以便在localhost和实际服务器之间切换时不必更改URL。
如果您使用的是Visual Studio,则可以通过单击解决方案资源管理器中的项目并按F4来更改分配给项目的虚拟路径。这将显示项目属性窗口,其中包含更改虚拟路径的选项。在您的情况下,您可能希望将其更改为/Test
。您仍然需要更改您的网址以包含/Test
。
尽管Darin指出,你应该使用网址助手。