2012-01-15 5 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, но моя страница содержания посылает другую модель:

Это метод 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 », но для этого словаря требуется элемент модели типа« ГалереяPresentation.Models.LoginModel », «.

Как справиться с этим - My _layout нуждается в модели для окна входа.

В соответствии с запросом, вот файл cboxbox Loginbox.

@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

Пожалуйста включают Войти Box парциальное Просмотреть cshtml. –

+0

@Phil - добавлен код. – Craig

+0

Похоже, я могу использовать мой LoginModel в качестве базового класса для всех остальных моделей, а затем наследовать его? Это похоже на работу - но это хороший дизайн/практика? Мне нужно убедиться, что все модели наследуются от LoginModel (что, я думаю, я переименовал бы в BaseModel - если бы что-то еще понадобилось?). – Craig

ответ

1

Вопросы, как это не всегда легче ответить, потому что это не простое решение. Есть несколько вопросов, хотя это следует учитывать. Если это возможно, я бы рекомендовал вам обрабатывать ошибки проверки входа в отдельном представлении. Частичное представление для маленького регистрационного окна не требует строго типизированной модели представления.

Нет идеального решения, но я не думаю, что вам всегда нужно создавать объекты LoginModel по каждому запросу, который отображает представление, которое зависит от _Layout. Нижеприведенное решение защищает создание отдельного входа в систему, которое может использоваться для явных попыток входа в систему и для обработки любых сбоев входа.

Если у вас возникли проблемы после этого, не стесняйтесь ответить на ваш вопрос в комментарии, и я сделаю все возможное, чтобы ответить.

Войти Box

@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

+0

Я предполагаю, что у вас есть как частичное представление, используемое в _layout, так и полное представление, которое обрабатывает сценарий/Account/Login. Частичный вид в этот момент, вероятно, не является необходимым, но все же может быть полезно разбить это. –

Смежные вопросы