8

Właśnie uczę się ASP.net MVC, więc proszę o zachowanie mnie, jeśli jestem zły w wyjaśnianiu mojego problemu.ASP.net MVC4: Używanie innego modelu w widoku częściowym?

Czy możliwe jest użycie innego modelu w widoku częściowym, niż to, co jest dziedziczone w widoku?

Mój widok Index obecnie dziedziczy LoginModel, który dotyczy autoryzacji użytkowników. Gdy użytkownik jest uprawniony, chcę, aby Index wyświetlał listę użytkownika todos. todos są pobierane przez LINQ.

Więc moja częściowy widok chce dziedziczyć System.Web.Mvc.ViewPage<IEnumerable<todo_moble_oauth.Models.todo>>, ale pojawia się błąd, gdy używam to: `Przekazany do słownika poz model jest typu

System.Data.Linq.DataQuery`1[todo_moble_oauth.Models.todo]', but this dictionary requires a model item of type 'todo_moble_oauth.Models.LoginModel' 

To mój Index Widok

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<todo_moble_oauth.Models.LoginModel>" %> 

<section id="loginForm"> 
    <% if (Request.IsAuthenticated) { %> 

     <% Html.RenderPartial("_ListTodos"); %> 

    <% } else { %> 

     <h1>Todo Mobile</h1> 

     <blockquote>Easily store your list of todos using this simple mobile application</blockquote> 

     <% using (Html.BeginForm()) { %> 
      <%: Html.AntiForgeryToken() %> 
      <%: Html.ValidationSummary(true) %> 

        <%: Html.LabelFor(m => m.UserName) %> 
        <p class="validation"><%: Html.ValidationMessageFor(m => m.UserName) %></p> 
        <%: Html.TextBoxFor(m => m.UserName) %> 

        <%: Html.LabelFor(m => m.Password) %> 
        <p class="validation"><%: Html.ValidationMessageFor(m => m.Password) %></p> 
        <%: Html.PasswordFor(m => m.Password) %> 

        <label class="checkbox" for="RememberMe"> 
         <%: Html.CheckBoxFor(m => m.RememberMe) %> 
         Remember Me? 
        </label> 

      <input type="submit" value="Login" /> 
     <% } %> 
    <% } %> 
</section> 

Moja częściowy widok _ListTodos jest następujący:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<todo_moble_oauth.Models.todo>>" %> 

<% foreach (var item in Model) { %> 
     <%: Html.DisplayFor(modelItem => item.title) %> 
     <%: Html.DisplayFor(modelItem => item.description) %> 
<% } %> 

My LoginModel ma następujący:

public class LoginModel 
{ 
    [Required] 
    [Display(Name = "User name")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [Display(Name = "Remember me?")] 
    public bool RememberMe { get; set; } 
} 

HomeControllerIndex() metoda:

[AllowAnonymous] 
    public ActionResult Index() 
    { 
     // if user is logged in, show todo list 
     if (Request.IsAuthenticated) 
     { 
      //var currentUser = Membership.GetUser().ProviderUserKey; 
      todosDataContext objLinq = new todosDataContext(); 
      var todos = objLinq.todos.Select(x => x); 
      return View(todos); 
     } 
     return View(); 
    } 

Każda pomoc jest mile widziana, dzięki.

Odpowiedz

6

Oczywiście można to zrobić:

<% Html.Partial("_ListTodos", userTodos); %> 

Przepuścić userTodos jako parametr częściowej pomocnika.

Błąd, który otrzymujesz, polega na zwrocie listy zadań do strony/widoku indeksu z return View(todos); wewnątrz metody działania Index. Strona Index wymaga obiektu LoginModel zamiast obiektu IEnumerable obiektów todo.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="System.Web.Mvc.ViewPage<todo_moble_oauth.Models.LoginModel>" %> 

Aby rozwiązać ten problem, należy zmienić sposób jesteś przekazując todos chociaż. Ponieważ strona Index otrzyma LoginModel można dodać obiekt Todos do tej klasy tak:

[Required] 
[Display(Name = "User name")] 
public string UserName { get; set; } 

[Required] 
[DataType(DataType.Password)] 
[Display(Name = "Password")] 
public string Password { get; set; } 

[Display(Name = "Remember me?")] 
public bool RememberMe { get; set; } 

public IEnumerable<todo_moble_oauth.Models.todo> Todos { get; set; } 

a następnie zmodyfikować swój sposób działania index:

[AllowAnonymous] 
public ActionResult Index() 
{ 
    // if user is logged in, show todo list 
    if (Request.IsAuthenticated) 
    { 
     //var currentUser = Membership.GetUser().ProviderUserKey; 
     todosDataContext objLinq = new todosDataContext(); 
     var todos = objLinq.todos.Select(x => x); 

     LoginModel model = new LoginModel(); 
     model.Todos = todos; 

     return View(model); 
    } 

    return View(); 
} 

W widoku, wykonaj następujące czynności:

<% Html.Partial("_ListTodos", Model.Todos); %> 
+2

Bardzo dziękuję, jest to również ładne i szczegółowe rozwiązanie. Musiałem zmienić '<% Html.Partial (" _ ListTodos ", Model.Todos); %> 'do' <% Html.RenderPartial ("_ ListTodos", Model.Todos); %> ', aby działało, ale teraz wszystko jest w złocie, dzięki! – Neil

+0

Miałem podobną sytuację, ale moja struktura modelu była trochę inna i nie wymagała zmian, ponieważ musiałem tylko stworzyć nową instancję modelu. Do moich potrzeb użyłem tego wiersza kodu (Razor Syntax): @ Html.Partial ("dialogs/_partial-view", new MyObjectModel()) – David