2012-06-19 28 views
4

我已經查看了本網站上提供的許多解決方案以及其他解決方案,但其中沒有一個似乎對我的解決方案非常適用。如何使用MVC顯示使用多個表單的ValidationSummary

在我的佈局頁面上我有一個登錄區域在屏幕的頂部。除非用戶登錄,否則這種情況一直存在。此登錄表單上有一個ValidationSummary,每次我使用網站上的其他表單發回時,都會觸發此登錄表單的驗證。

我幾乎可以肯定,這取決於我如何從我的佈局頁面調用此登錄頁面。這不是局部視圖,而是在共享文件夾中,它位於我項目的Area中。在我的佈局頁我所說的登錄表單是這樣的:

@Html.Action("LogOn", "Account", new { area = "Store" }) 

登錄頁包含以下內容:

@model Project.ViewModels.LogOn_ViewModel 

@{ 
    Layout = null; 
} 

@using (Ajax.BeginForm("LogOn", "Account", new { @area = "Store" }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "LoginContainer", LoadingElementId = "actionLoaderImage" }, new { id="LogonForm" })) 
{ 
    @Html.AntiForgeryToken() 

    <div class="loginArea"> 
     <div class="notRegistered"> 
      <h4>Not registered yet?</h4> 
      Register now<br/> 
      @Html.ActionLink("Register", "Index", "SignUp", new { area = "Store" }, new { @class = "greenButton" }) 
     </div> <!-- /notRegistered --> 

     <div class="loginForm"> 
      <div class="formFields"> 
       <label class="inline">@Html.LabelFor(m => m.UserName)</label> 
       @Html.TextBoxFor(m => m.UserName) 
       <label class="inline">@Html.LabelFor(m => m.Password)</label> 
       @Html.PasswordFor(m => m.Password) 
       <input type="submit" name="LogIn" value="Log in" class="blueButton" /> 
       <img id="actionLoaderImage" src="@Url.Content("~/Content/web/images/loader.gif")" alt="icon" style="margin-right:15px; display:none;" /> 
       @Html.ValidationSummary() 
      </div> 
     </div> <!-- /loginForm --> 
    </div> <!-- /loginArea --> 
} 

登錄控制器是標準的東西:

 // GET: /Account/Logon 

     public ActionResult LogOn() 
     { 
      // if logged in show logged in view 
      if (User.Identity.IsAuthenticated) 
       return View("LoggedIn"); 

      return View(); 
     } 


     // POST: /Account/Logon 

     [HttpPost] 
     public ActionResult LogOn(LogOn_ViewModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       if (SecurityService.Login(model.UserName, model.Password, model.RememberMe)) 
       { 
        return View("LoggedIn"); 
       } 
       else 
       { 
        ModelState.AddModelError("", "The user name or password provided is incorrect."); 
       } 
      } 
      return PartialView(model); 
     } 

我懷疑這裏發生的事情是Html.Action是'張貼'登錄表單,如果一個帖子發生在頁面的其他地方。這很有意義,因爲佈局頁面本身將作爲表單發佈操作的一部分發布。

我嘗試從其他一些SO問題和博客(http://blogs.imeta.co.uk/MBest/archive/2010/01/19/833.aspx)實現定製Validator示例,但是我發現使用這些示例不會顯示客戶端驗證的驗證摘要,這對我沒有多大用處。

我正在尋找的解決方案需要允許客戶端和服務器端驗證以正確的形式出現。有沒有人有這樣的例子使用MVC?如果可能的話,我想避免使用jquery手動查看客戶端驗證,只是使用框架來處理我的工作。

感謝您的建議, 豐富

+1

你有沒有考慮使用一個按鈕(與一個相關的「點擊」事件)提交登錄表單,而不是輸入「提交」按鈕? – Jesse

回答

2

這個問題玩耍的時間超過我願意承認後,答案一如既往很簡單,一旦你知道如何!

針對此問題的任何人提出的解決方案是重命名您的操作,以便您的POST操作與GET操作的名稱不同。這樣,當佈局頁面回發並觸發PartialView也被重新發布時,您的PartialView只有GET操作,因此不會觸發ValidationSummary。

根據我上面的示例,我已更改表單以回發到另一個操作,以便我登錄部分視圖,並已解決此問題。

在我的佈局頁的鏈接在商店區域的部分仍然是相同的:

@Html.Action("LogOn", "Account", new { area = "Store" }) 

登錄表單動作是那麼改變指向一個新動作 - 不叫同名的GET動作:

@using (Ajax.BeginForm("ConfirmLogon", "Account", new { @area = "Store" }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "LoginContainer", LoadingElementId = "actionLoaderImage" }, new { id="LogonForm" })) 
    { 
     .... 
    } 

然後我改名爲我的控制器操作,因此有POST操作不同的動作名稱,以便在佈局網頁使用後打來電話,部分裝載了一個POST的行動,它不會調用我的登錄POST操作:

 // POST: /Account/ConfirmLogon 

     [HttpPost] 
     public ActionResult ConfirmLogon(LogOn_ViewModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       if (SecurityService.Login(model.UserName, model.Password, model.RememberMe)) 
       { 
        return PartialView("LoggedIn"); 
       } 
       else 
       { 
        ModelState.AddModelError("", "The user name or password provided is incorrect."); 
       } 
      } 
      return PartialView("Logon",model); 
     } 

希望這會幫助其他人解決這個問題。似乎如此明顯,但驅使我堅果:D