Перенаправить на возврат URL-адреса после входа в систему
У меня есть ссылка на моем бритве, например:
<a href="Home/Login?ReturnUrl=Disputes/Index"> disputes</a>
внутри моего метода действия входа, я использую это:
public ActionResult Login(string returnUrl) {
if (string.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null)
returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery);
if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl))
{
ViewBag.ReturnURL = returnUrl;
}
return View();
}
Я использую это:
@Html.Hidden("returnUrl",@Request.QueryString)
а затем в методе post action:
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (membershipService.ValidateUser(model.UserName, model.Password, model.Type))
{
formsAuthenticationService.SignIn(model.UserName, model.RememberMe);
SetUserInfo(model.UserName);
string decodedUrl = "";
if (!string.IsNullOrEmpty(returnUrl))
decodedUrl = Server.UrlDecode(returnUrl);
if (Url.IsLocalUrl(decodedUrl))
return Redirect(decodedUrl);
else
return Redirect("Home", Index);
}
}
}
он перенаправляется на: /Disputes/Index
, но он должен перейти к myApp/Disputes/Index
, где URL-адрес с querystring выглядит так. /myApp/Home/Login?ReturnUrl=/Disputes/Index
Как я могу решить эту проблему?
Ответы
Ответ 1
Я использую комбинацию вышеуказанного предложения и Request.UrlReferrer
, чтобы получить предыдущее местоположение:
public ActionResult LogOn(string returnUrl)
{
//So that the user can be referred back to where they were when they click logon
if (string.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null)
returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery);
if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl))
{
ViewBag.ReturnURL = returnUrl;
}
return View();
}
Таким образом, мне не нужно указывать местоположение в ActionLink
.
Я заполняю скрытое поле на странице входа с помощью ViewBag.ReturnURL
. Затем в Login HTTPPost ActionResult
я перенаправляю пользователя в местоположение в скрытом поле (если оно есть):
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
//returnURL needs to be decoded
string decodedUrl = "";
if (!string.IsNullOrEmpty(returnUrl))
decodedUrl = Server.UrlDecode(returnUrl);
//Login logic...
if (Url.IsLocalUrl(decodedUrl))
{
return Redirect(decodedUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
Ответ 2
В этом случае вы можете заставить ваше действие LogOn принять параметр returnUrl, и если он не пуст, вместо перенаправления на Home/Index вы можете вернуть Redirect(returnUrl);
. Посмотрите на AccountController по умолчанию, сгенерированный VS, когда вы создаете новый проект. Он делает именно это.
Ответ 3
Если ReturnURL
- null
, убедитесь, что вы вызываете метод действия из представления следующим образом:
// FormMethod.post is optional
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post))
{
// login view html
}
Контроллер учетной записи:
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
Ответ 4
//Utilities
public static ReturnUrl GetReturnUrlValues(string returnUrl)
{
//0:Action,1:Controller,2:Area:,3:Id
ReturnUrl vm = new ReturnUrl();
using (TBBSEntities context = new TBBSEntities())
{
if (returnUrl != null && returnUrl.Length > 10)
{
var counterValue = returnUrl.Split('/');
vm.Action = counterValue[0];
vm.Controller = counterValue[1];
vm.Area = counterValue[2] == "0" ? "" : counterValue[2] ;
vm.Id = Convert.ToInt32(counterValue[3]);
vm.NullStatus = true;
return vm;
}
vm.NullStatus = false;
return vm;
}
}
//Controller
var transformUrl = Utilities.GetReturnUrlValues(returnUrl);
if (transformUrl.NullStatus)
{
return RedirectToAction(transformUrl.Action, transformUrl.Controller,
new { area = transformUrl.Area, id = transformUrl.Id });
}
return RedirectToAction("Action", "Controller", new { area = "Area", Id});
//View
var returnUrl = "Action/Controller/Area/" + @Model.Id;