8

Sto solo imparando ASP.net MVC quindi, per favore, sopporta me se non sono bravo a spiegare il mio problema.ASP.net MVC4: utilizzo di un modello diverso in una vista parziale?

È possibile utilizzare un modello diverso in una vista parziale rispetto a ciò che viene ereditato nella vista?

La vista personale Index eredita attualmente LoginModel, che riguarda l'autorizzazione degli utenti. Una volta che un utente è autorizzato, voglio il Index per visualizzare l'elenco di todos che l'utente ha. todos vengono recuperati tramite LINQ.

Quindi la mia vista parziale vuole ereditare System.Web.Mvc.ViewPage<IEnumerable<todo_moble_oauth.Models.todo>>, ma ottengo un errore quando uso questo: `La voce del modello passato nel dizionario è di tipo

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

Questa è la mia Index vista

<%@ 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> 

mio vista parziale _ListTodos è la seguente:

<%@ 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) %> 
<% } %> 

mio LoginModel ha il seguente:

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; } 
} 

Procedimento HomeControllerIndex():

[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(); 
    } 

Tutto l'aiuto notevolmente è apprezzato, grazie.

risposta

6

Certo si può fare:

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

Passare il userTodos come parametro per l'helper parziale.

L'errore che si ottiene è perché si sta restituendo un elenco di tutti gli elementi della pagina/vista indice con return View(todos); all'interno del metodo di azione Index. La pagina indice necessita di un oggetto LoginModel invece di un IEnumerable di oggetti todo.

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

Per risolvere questo problema, è necessario modificare il modo in cui si sta passando il todos però. Dal momento che la tua pagina Index riceve un LoginModel, è possibile aggiungere una proprietà Todos a questa classe in questo modo:

[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; } 

e quindi, modificare il proprio metodo di azione 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(); 
} 

Nella vista, fare questo:

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

Grazie mille, anche questa è una soluzione piacevole e dettagliata. Ho dovuto cambiare '<% Html.Partial (" _ ListTodos ", Model.Todos); %> 'a' <% Html.RenderPartial ("_ ListTodos", Model.Todos); %> 'per farlo funzionare, ma ora è tutto oro, grazie! – Neil

+0

Ho avuto una situazione simile ma la struttura del mio modello era leggermente diversa e non richiedeva modifiche, poiché avevo solo bisogno di creare una nuova istanza del modello. Per le mie esigenze ho utilizzato questa riga di codice (Razor Syntax): @ Html.Partial ("dialogs/_partial-view", new MyObjectModel()) – David