2012-01-15 53 views
1

我有一個_layout頁面,它有一個登錄框(局部視圖),該視圖具有它自己的模型。所以控制器看起來是這樣的:MVC3多個模型 - 單個頁面

 public ActionResult Index() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(LoginModel loginModel) 
    { 
     if(ModelState.IsValid) 
     { 
      var g = new GallaryImage(); 
      var user = g.LoginUser(loginModel.Username, loginModel.Password); 
      if(user != null) 
      { 
       FormsAuthentication.SetAuthCookie(user.username, false); 
       return RedirectToAction("Index", "Home"); 
      } 
      ModelState.AddModelError("", "Invalid Username/Password"); 
     } 
     return View(loginModel); 
    } 

但只要我的主要內容頁需要一個模式,因爲登錄框中需要一個LoginModel類型,但我的內容頁面發送不同的模型我的web應用程序失敗:

這是我的主索引畫面GET方法:

public ActionResult Index() 
    { 
     IndexModel model = new IndexModel(); 
     var g = new GallaryService.GallaryImage(); 
     var i = g.GetRandomImage(); 

     if (i != null) 
      model.RandomImageUrl = "~/Images/Watermarks/" + i.filename; 
      return View(model); 
    } 

所以,我的主要內容頁中有一個IndexModel,但我的部分觀點有LoginModel。當我嘗試運行它時,出現錯誤:

「傳入字典的模型項類型爲'GalleryPresentation.Models.IndexModel',但此字典需要類型爲'GalleryPresentation.Models.LoginModel'的模型項「。

我該如何處理 - 我的_layout需要登錄框的模型。

按照要求,這裏是Loginbox cshtml文件。

@using GalleryPresentation.Models 
@model LoginModel 

<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script> 
@using (Html.BeginForm("index", "Account", FormMethod.Post)) 
{ 
    <table class="smallBox"> 
     <tr> 
      <td>@Html.LabelFor(m => m.Username)</td> 
      <td>@Html.TextBoxFor(m => m.Username, new { @class = "smallText" })</td> 
      <td>@Html.LabelFor(m => m.Password)</td> 
      <td>@Html.PasswordFor(m => m.Password, new { @class = "smallText" })</td> 
     </tr> 
     <tr> 
      <td colspan="4" align="right"><input type="submit" value="Login"/></td> 
     </tr> 
     <tr> 
      <td colspan="2">@Html.ValidationSummary()</td> 
     </tr> 
    </table> 

} 

而且Index.cshtml文件(主要內容畫面)具有這樣的:

@using GalleryPresentation.Models 
@model IndexModel 
@{ 
    ViewBag.Title = "Craig and Melanie's Digital Moments"; 
} 

<br/> 
<div style="text-align: center"> 
    <img src="@Url.Content(Model.RandomImageUrl)" alt="@ViewBag.Title" /> 
</div> 
+0

請包括登錄框部分查看cshtml。 – 2012-01-15 02:57:56

+0

@Phil - 添加了代碼。 – Craig 2012-01-15 03:16:02

+0

看起來我可以使用我的LoginModel作爲所有其他模型的基類,然後繼承它?這似乎工作 - 但這是很好的設計/實踐?我需要確保所有模型都繼承自LoginModel(我想我會重命名爲BaseModel - 需要其他東西需要?)。 – Craig 2012-01-15 03:24:40

回答

1

類似這樣的問題並不總是最容易回答,因爲沒有一個簡單的解決方案。有幾個問題應該考慮。如果可能的話,我會建議您在單獨的視圖中處理登錄驗證錯誤。小登錄框的局部視圖不需要強類型的視圖模型。

沒有完美的解決方案,但我認爲對於您始終在呈現依賴於_Layout的視圖的每個請求上創建LoginModel對象是非常有意義的。下面的解決方案主張創建一個單獨的登錄視圖,該視圖可用於顯式登錄嘗試以及處理任何登錄失敗。

如果您在此之後遇到任何問題,請在評論中隨時提出您的問題,我會盡我所能來回答。

登錄框

@using (Html.BeginForm("Index", "Account")) 
{ 
    <table class="smallBox"> 
     <tr> 
      <td>Username</td> 
      <td>@Html.TextBox("Username", new { @class = "smallText" })</td> 
      <td>Password</td> 
      <td>@Html.Password("Password", new { @class = "smallText" })</td> 
     </tr> 
     <tr> 
      <td colspan="4" align="right"><input type="submit" value="Login"/></td> 
     </tr> 
    </table> 
} 

賬戶控制器

public ActionResult Login() 
{ 
    return View(); 
} 

public ActionResult RetryLogin() 
{ 
    ModelState.AddModelError(null, "The Username or Password you entered is invalid. Please try again."); 
    return View("Login"); 
} 

[HttpPost] 
public ActionResult Index(LoginModel loginModel) 
{ 
    if(ModelState.IsValid) 
    { 
     var g = new GallaryImage(); 
     var user = g.LoginUser(loginModel.Username, loginModel.Password); 
     if(user != null) 
     { 
      FormsAuthentication.SetAuthCookie(user.username, false); 
      return RedirectToAction("Index", "Home"); 
     } 

     ModelState.AddModelError("", "Invalid Username/Password"); 
    } 

    return RedirectToAction("RetryLogin"); 
} 

登錄查看

@using (Html.BeginForm("Index", "Account")) 
{ 
    @Html.ValidationSummary() 
    <!-- login form here --> 
} 
+0

看起來像一個驚人的答案。我不理解Loginbox如何適應_layout - 或者我們說Loginbox不再位於_layout上,並且它是一個單獨的登錄屏幕? – Craig 2012-01-16 09:06:26

+0

我建議你在_layout中使用局部視圖,並處理/ Account/Login場景。在這一點上的局部看法可能不是真正必要的,但它可能仍然有幫助分裂出來。 – 2012-01-16 15:19:11

相關問題