Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 674
Neil Avatar asked May 22 '13 17:05

Neil


People also ask

Can we use model in partial view?

Partial Views can use the Page Model for their data whereas Child Actions use independent data from the Controller. Editor/Display templates pass items from the model to the system but can be overridden by user partial views.

Can we use 2 models in a view?

You can use multiple models in a single view by creating a common model for all the models that are to be used in a single view. To achieve this, refer to the following steps. First, create a new model (common for all models) and refer all other models that are to be used in the same view.

How do you pass a model from view to partial view?

To create a partial view, right click on Shared folder -> select Add -> click on View.. Note: If the partial view will be shared with multiple views, then create it in the Shared folder; otherwise you can create the partial view in the same folder where it is going to be used.


1 Answers

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); %>
like image 199
Leniel Maccaferri Avatar answered Oct 30 '22 19:10

Leniel Maccaferri