ASP.net MVC4: Using a different model in a partial view?

16,703

Sure you can do that:

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

Pass the userTodos as a parameter to the Partial helper.

The error you're getting is because you're returning a list of todos to the Index page/view with return View(todos); inside the Index action method. The Index page needs a LoginModel object instead of an IEnumerable of todo objects.

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

To solve this, you need to change the way you're passing the todos though. Since your Index page receives a LoginModel, you can add a Todos property to this class like this:

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

and then, modify your Index action method:

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

In the view, do this:

<% Html.Partial("_ListTodos", Model.Todos); %>
Share:
16,703
Neil
Author by

Neil

rangle.io Intermediate Software Developer

Updated on June 14, 2022

Comments

  • Neil
    Neil almost 2 years

    I am just learning ASP.net MVC so please bear with me if I am bad at explaining my issue.

    Is it possible to use a different model in a partial view than what is being inherited in the view?

    My view Index currently inherits LoginModel, which deals with the authorization of users. Once a user is authorized, I want the Index to display the list of todos the user has. todos are retrieved via LINQ.

    So my partial view wants to inherit System.Web.Mvc.ViewPage<IEnumerable<todo_moble_oauth.Models.todo>>, but I get an error when I use this: `The model item passed into the dictionary is of type

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

    This is my Index view

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

    My partial view _ListTodos is as follows:

    <%@ 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 has the following:

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

    The HomeController Index() method:

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

    Any help is greatly appreciated, thanks.

  • Neil
    Neil almost 11 years
    Thank you very much, this is a nice and detailed solution too. I had to switch <% Html.Partial("_ListTodos", Model.Todos); %> to <% Html.RenderPartial("_ListTodos", Model.Todos); %> to make it work, but everything is gold now, thanks!
  • David
    David over 10 years
    I had a similar situation but my model structure was a little different and did not require altering since I only needed to create a new instance of the model. For my needs I used this line of code (Razor Syntax): @Html.Partial("dialogs/_partial-view", new MyObjectModel())