在尝试重新登录站点时,在ASP.NET MVC中使用表单身份验证,它会在查询字符串中放置一个ReturnUrl参数 . 我的登录操作方法接受“returnUrl”字符串 . 但是,似乎returnUrl字符串始终为null,即使它明显位于查询字符串中 . 有关为什么会出现这种情况或可能的解决方案的任何想法?
也许您没有将 ReturnURL 参数包含在登录表单的操作属性中,从而发布到没有该参数的URL?
ReturnURL
当您使用一个通用登录表单时,这往往会发生,但您明确指定了Controller和ActionMethod(导致表单发布,但丢失了查询字符串)
只是为了澄清,这是您的代码应该在您的BeginForm中的样子:
Html.BeginForm("LogOn", "Account", new { ReturnUrl = Request.QueryString["ReturnUrl"] })
编辑:这是设计为Rick并在下面的评论中提及 . 但是,它不允许UI模式在网站深处,单击LogOn,然后返回到之前的页面,如果它允许匿名用户 . 这是一种常见的模式 . 大卫艾伦的LogOff方法也可以很好地用于LogOn的干净重定向 .
基本上,Asp.net MVC有一些隐藏的功能 . 例如,当您将变量'id'传递给控制器操作时,它会将'id'解释为默认标识符并将其置于带有前斜杠的浏览器查询中 . 使用其他名称而不是'id',我们将看到'?'而不是前斜杠 . 因为在global.asax文件上的 RegisterRoutes 方法上设置'id'名称 .
RegisterRoutes
在本问题中,您已使用以下代码为控制器创建了自定义数据传递:
using(Html.BeginForm("LogOn", "Account", FormMethod.Post)) { //form fields }
所以Asp.net MVC忽略了传递给控制器动作的其他有用数据,我们将看到 returnUrl 总是 null .
returnUrl
null
虽然,通过使用它,Asp.net MVC正确行为和 returnUrl 已安装:
using(Html.BeginForm()) { //form fields in LogOn View }
顺便说一句,当我们使用自定义数据传递器来控制器操作时,必须传递另一个数据 manually ,如下所示:
using(Html.BeginForm("LogOn", "Account", new {ReturnUrl = Request.QueryString["ReturnUrl"] })) { //form fields }
我可以通过两种方式来处理登录和注销方案 . 戴夫啤酒概述了一种方式,上面 . 还有另一种方法适用于许多情况 . 我在编写NerdDinner教程时使用过它 . 本教程为我们提供了一个注销功能,可以将您注销并带您回家 . 我不想那样 . 我想在退出之前返回我所在的页面 . 所以我修改了我的帐户控制器注销操作,看起来像这样
public ActionResult LogOff() { FormsService.SignOut(); return Redirect(Request.UrlReferrer.ToString()); }
您可以获得更好的功能并传入returnUrl并测试它,以防您想要覆盖此行为 . 但我不需要那个 . 这实现了期望的结果 . 登录可以类似地工作 . 也许有方法可以使用MVC框架为我做这个,但在我学习它们之前,这非常简单且可靠 .
请尝试以下方法:
public static MvcForm BeginForm(this HtmlHelper htmlHelper, string id) { string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl; TagBuilder tagBuilder = new TagBuilder("form"); tagBuilder.MergeAttribute("id", id); tagBuilder.MergeAttribute("action", formAction); tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(FormMethod.Post), true); HttpResponseBase httpResponse = htmlHelper.ViewContext.HttpContext.Response; httpResponse.Write(tagBuilder.ToString(TagRenderMode.StartTag)); return new MvcForm(htmlHelper.ViewContext.HttpContext.Response); }
首先确保您已在web.config中设置登录URL,接下来,确保您的登录表单不包含任何类似操作,例如:
如果指定操作,则返回URL将始终为null:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult SignIn(string userName, string password, bool? rememberMe, string returnUrl) { }
5 回答
也许您没有将
ReturnURL
参数包含在登录表单的操作属性中,从而发布到没有该参数的URL?当您使用一个通用登录表单时,这往往会发生,但您明确指定了Controller和ActionMethod(导致表单发布,但丢失了查询字符串)
只是为了澄清,这是您的代码应该在您的BeginForm中的样子:
基本上,Asp.net MVC有一些隐藏的功能 . 例如,当您将变量'id'传递给控制器操作时,它会将'id'解释为默认标识符并将其置于带有前斜杠的浏览器查询中 . 使用其他名称而不是'id',我们将看到'?'而不是前斜杠 . 因为在global.asax文件上的
RegisterRoutes
方法上设置'id'名称 .在本问题中,您已使用以下代码为控制器创建了自定义数据传递:
所以Asp.net MVC忽略了传递给控制器动作的其他有用数据,我们将看到
returnUrl
总是null
.虽然,通过使用它,Asp.net MVC正确行为和
returnUrl
已安装:顺便说一句,当我们使用自定义数据传递器来控制器操作时,必须传递另一个数据 manually ,如下所示:
我可以通过两种方式来处理登录和注销方案 . 戴夫啤酒概述了一种方式,上面 . 还有另一种方法适用于许多情况 . 我在编写NerdDinner教程时使用过它 . 本教程为我们提供了一个注销功能,可以将您注销并带您回家 . 我不想那样 . 我想在退出之前返回我所在的页面 . 所以我修改了我的帐户控制器注销操作,看起来像这样
您可以获得更好的功能并传入returnUrl并测试它,以防您想要覆盖此行为 . 但我不需要那个 . 这实现了期望的结果 . 登录可以类似地工作 . 也许有方法可以使用MVC框架为我做这个,但在我学习它们之前,这非常简单且可靠 .
请尝试以下方法:
首先确保您已在web.config中设置登录URL,接下来,确保您的登录表单不包含任何类似操作,例如:
查看:
如果指定操作,则返回URL将始终为null:
控制器: