ASP MVC + IIS7,POST表单数据在服务器端丢失

时间:2013-12-11 16:33:19

标签: asp.net asp.net-mvc asp.net-mvc-4 iis postback

我遇到了我的ASP.NET MVC 4.0应用程序的奇怪行为。在用户登录期间,似乎POST请求表单数据随机丢失。应用程序使用表单身份验证和本地用户数据库我有一个简单的登录屏幕,其形式定义如下:

@using (Html.BeginForm("LogOn" ,"Account", FormMethod.Post))
{
    <div>
        <table class="editor">
            <tr>
                <td class="editor-label">
                    @Html.LabelFor(m => m.UserName)
                </td>
                <td class="editor-field">
                    @Html.TextBoxFor(m => m.UserName)
                    @Html.ValidationMessageFor(m => m.UserName)
                </td>
            </tr>
            <tr>
                <td class="editor-label">
                    @Html.LabelFor(m => m.Password)
                </td>
                <td class="editor-field">
                    @Html.PasswordFor(m => m.Password)
                    @Html.ValidationMessageFor(m => m.Password)
                </td>
            </tr>
            <tr>
                <td class="editor-label">
                    @Html.LabelFor(m => m.RememberMe)
                </td>
                <td class="editor-field">
                    @Html.CheckBoxFor(m => m.RememberMe)
                </td>
            </tr>
        </table>
    </div>
  <input type="submit" value="Přihlásit" />
}

控制器操作:

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            CoreServices.Logger.Info("Loggin attemp for user '{0}'. Request UserName: {1}", model.UserName, HttpContext.Request["UserName"]);

            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.UserName, model.Password))
                {
                    CoreServices.Logger.Info("User '{0}' enter valid password.", model.UserName);

                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/", StringComparison.Ordinal)
                        && !returnUrl.StartsWith("//", StringComparison.Ordinal) && !returnUrl.StartsWith("/\\", StringComparison.Ordinal))
                    {
                        CoreServices.Logger.Info("User '{0}' logged in. Redirecting to URL: {1}", model.UserName, returnUrl);
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        CoreServices.Logger.Info("User '{0}' logged in. Redirecting to home.", model.UserName);
                        return RedirectHome();
                    }
                }
                else
                {
                    CoreServices.Logger.Info("User '{0}' entered incorrect password. Membership.ValidateUser() returns false.", model.UserName);
                    ModelState.AddModelError("", "Zadané jméno nebo heslo jsou nesprávné.");
                }
            }
            else
            {
                CoreServices.Logger.Info("User '{0}' entered invalid password.", model.UserName);
            }


            // If we got this far, something failed, redisplay form
            return View(model);
        }

如果用户发布登录表单,则会在请求中显示已发布的表单值-UserName和Password。我使用Fiddler验证了这一点。但是在服务器上,如果我在Account控制器中检查HttpContext.Request [“UserName”],则该值为null,尽管请求中存在UserName值。

此行为随机发生,并且不依赖于浏览器(在IE9,FF 25,Chrome 24上报告)。该应用程序托管在IIS7上,集成管道模式,SSL与自签名证书一起使用(但即使不使用SSL也会发生)。在开发环境中重现它几乎是不可能的(它在我们的DEV服务器上看到了这种行为两次),但它在生产环境中很常见(遗憾的是我无法访问它)。

你知道如何解决这个问题吗?我可以以某种方式监控,缺少值的原因是什么?

谢谢

1 个答案:

答案 0 :(得分:0)

原因可能是IE在POST上的HTTP标头中的“内容长度”参数中发送“0”,尽管请求的主体具有非零内容(包含表单数据)。使用现有表单数据的请求但在IIS上未正确处理“0”内容长度,并且HttpContext.Request中不提供值。根据文章Challenge-Response Authentication and Zero-Length Posts,如果浏览器向网站的安全部分发出请求,要求用户使用凭据进行授权,则会发生这种情况。在此之后,IE要求下一个POST请求是对该凭证请求的无体响应。有关详细信息,请参阅链接文章。