代码之家  ›  专栏  ›  技术社区  ›  Pete Nelson

无烹饪课程和跨网站表单帖子

  •  5
  • Pete Nelson  · 技术社区  · 16 年前

    情况是这样的…

    站点1)ASP.NET MVC应用程序,用于客户登录、查看和支付账单等。此站点使用无cookieASP会话,允许在选项卡式浏览器中运行多个会话。

    站点2)具有标准静态内容的公司网站。这将在每个页面的顶部有一个小表单,其中包含一个将发布到MVC应用程序的用户名/密码表单。

    当发布到MVC应用程序时,将生成一个新的会话,并且该站点将返回一个302重定向,其会话ID位于URL中(如预期)。控制器有两种登录方法,一种用于处理get,另一种用于处理post。因为重定向,它正在命中get方法,并且会丢失表单值。

    通过更改公司网站上的方法来执行表单获取而不是发布,在重定向之后用户名和密码将保留在查询字符串中,我可以用这种方式处理请求,但我宁愿执行发布,而不在URL中传递这些数据。

    我的直觉告诉我,实现某种定制的httphandler可以让我做到这一点,但是我不确定在哪里可以连接到会话创建。global.asax中session_start处的断点显示会话ID已装箱,并且重定向已在该点发生。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Pete Nelson    16 年前

    我相信我找到了重定向发生的地方以及可能的解决方法。ISessionIDManager接口有一个saveSessionID方法,该方法上有一个“out bool redirected”参数。当创建新会话时,默认会话管理器会重写此方法中的URL并执行重定向。我尝试过实现自己的isessionidManager,并且能够抑制重定向,但是没有办法(我可以说)在不执行重定向的情况下将会话ID插入到无烹饪会话的URL中。在请求生命周期的该点不允许进行server.transfer。我尝试过,但收到了“执行儿童请求时出错”的消息。

    稍后,我在上找到了这篇文章 Enabling POST in cookieless ASP.NET Applications . 基本上,通过连接到应用程序的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());
    
        }
    }
    

    这不是一个理想的解决方案imho,但它可能是可行的,足以满足要求。

        2
  •  0
  •   Nathan Taylor    16 年前

    当MVC站点发出重定向时,您是用控制器自己处理还是由成员资格提供程序自动路由?

    如果可以在重定向之前截获请求,那么可以将用户名和密码放在tempdata变量中,并在重定向之后对其进行处理。

        3
  •  0
  •   Community Mohan Dere    9 年前

    你在找一个 Server.Transfer equivalent in MVC (见西蒙的回答。)

    这类似于request.redirect,但只需将.NET处理转移到另一个页面。它还允许在传输之间(在本例中是RouteValueDictionary)甚至在POST上维护表单变量。

    编辑: (回复您的意见1)

    下面是一个例子 Forms Authentication with MVC . 不知道您的授权机制的内部结构,我不完全确定。在“Dologin”过程的任何一点上,您都可以进行传输而不是重定向。