2013-12-11 34 views
0

我遇到了ASP.NET MVC 4.0應用程序的奇怪行爲。看起來POST請求表單數據在用戶登錄過程中隨機丟失。該應用程序使用本地用戶數據庫的表單認證。我有限定形式的簡單的登錄屏幕,如下所示:ASP MVC + IIS7,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和密碼 - 存在於該請求。我使用Fiddler驗證了這一點。但是在服務器上,如果我在帳戶控制器中檢查HttpContext.Request [「UserName」],則該值爲空,儘管請求中存在UserName值。

此行爲是隨機發生的,它不依賴於瀏覽器(在IE9,FF 25,Chrome 24上報告)。該應用程序託管在IIS7集成管道模式下,SSL與自簽名證書一起使用(但即使未使用SSL也會發生此問題)。在開發環境中重現它幾乎是不可能的(它在DEV中的服務器上看到了這種行爲兩次),但是在生產環境中(我不幸無法訪問)這很常見。

你有什麼想法如何解決這個問題?我能否以某種方式監控缺失值的原因?

謝謝

+0

當你在你的LoGon方法中放置一個斷點時,模型被作爲參數填入? –

+0

模型已通過(實例不爲空,對象存在),但UserName和Password屬性爲null。 – Mikee

+0

你能顯示你的控制器動作碼嗎? –

回答

0

其原因可能是,該IE發送在上POST HTTP報頭的「內容長度」參數「0」,儘管事實上該請求的主體具有非零內容(包含形式數據)。請求與現有的表單數據,但「0」內容長度未在IIS上正確處理,並且值在HttpContext.Request中不可用。根據文章Challenge-Response Authentication and Zero-Length Posts,如果瀏覽器向需要使用憑證的用戶授權的網站的安全部分發出請求,就會發生這種情況。在該請求之後,IE期望下一個POST請求對該憑證請求無迴應。詳情請參閱鏈接的文章。