情况就是这样......
站点1)ASP.NET MVC应用程序,供客户登录,查看和支付账单等。该站点使用无cookie的ASP会话,允许多个会话在选项卡式浏览器中运行。
网站2)具有标准静态内容的公司网站。这将在每个页面的顶部有一个小表单,其中包含将发布到MVC应用程序的用户名/密码表单。
发布到MVC应用程序时,正在生成一个新会话,并且该站点返回302重定向,其中URL中包含会话ID(如预期的那样)。控制器有两个Login方法,一个用于处理GET,一个用于处理POST。由于重定向,它正在点击GET方法并且它丢失了表单值。
通过更改公司站点上的方法来执行表单GET而不是POST,用户名和密码在重定向后保存在查询字符串中,我可以通过这种方式处理请求,但我宁愿做一个POST并且不会在URL中传递该数据。
我的直觉说实现某种自定义HttpHandler会允许我这样做,但我不确定我能在哪里与会话创建联系起来。 global.asax中Session_Start的断点显示会话ID已经被创建,并且重定向已经在该点发生。
答案 0 :(得分:2)
我相信我找到了重定向发生的位置以及可能的解决方案。 ISessionIDManager接口具有SaveSessionID方法,其上包含“out bool重定向”参数。看来,当创建新会话时,默认会话管理器会重写此方法中的URL并执行重定向。我开始实现自己的ISessionIDManager并且我能够抑制重定向,但是没有办法(我可以告诉)将会话ID插入到无cookie会话的URL中而不进行重定向。在请求生命周期中的那个点上不允许Server.Transfer。我试过了,但收到了“Error Executing Child Request”消息。
后来,我在Enabling POST in cookieless ASP.NET Applications找到了这篇文章。基本上,通过绑定Application_EndRequest事件,您可以检测重定向,清除响应并将表单发布到包含会话ID的新URL。
void MvcApplication_EndRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
if (application.Request.Form["CorpLogin"] == "1"
&& application.Response.RedirectLocation != null
&& application.Response.IsRequestBeingRedirected)
{
StringBuilder build = new StringBuilder();
build.Append("<html>\n<body>\n<form name='Redirect' method='post' action='");
build.Append(application.Response.RedirectLocation);
build.Append("' id='Redirect' >");
foreach (string key in application.Request.Form)
{
if (key != "CorpLogin")
build.Append(string.Format("\n<input type='hidden' name='{0}' value = '{1}'>", (string)key, application.Request.Form[(string)key]));
}
build.Append("\n<noscript><h2>Object moved <input type='submit' value='here'></h2></noscript>");
build.Append(@"</form>
<script language='javascript'>
<!--
document.Redirect.submit();
// -->
</script>
");
build.Append("</body></html>");
application.Response.Clear();
application.Response.ClearHeaders();
application.Response.Output.Flush();
application.Response.Write(build.ToString());
}
}
这不是理想的解决方案恕我直言,但它可能足以满足要求。
答案 1 :(得分:0)
当MVC网站发出重定向时,您是自己使用控制器处理还是由会员提供商自动路由?
如果您可以在重定向之前拦截请求,则可以将用户名和密码放在TempData变量中,并在重定向后对其进行处理。
答案 2 :(得分:0)
您正在寻找Server.Transfer equivalent in MVC(请参阅Simon的回答。)
它就像Request.Redirect,但只是将.NET处理转移到另一个页面。它还允许在传输之间的POST上保持表单变量(在本例中为RouteValueDictionary)。
编辑:(回复您的评论#1)
以下是Forms Authentication with MVC的示例。在不了解授权机制的内部情况的情况下,我并不完全确定。在“DoLogin”流程的任何时候,您都可以进行转移而不是重定向。