Kodekan
Kodekan

Reputation: 1601

asp.net using a different model in a partial view than in its parent?

My _Layout page uses @RenderSection at a couple of points, for example to render the sidebars (if there are any). I have about 30 different views that use 10 different models where they get the content from. However there are only 4 different sidebars at the moment, so I out them into partial views that are called like this:

@section SBLeft {
    @Html.Partial("_SidebarTopics)
}

This works fine on my frontpage because the sidebar partial _SidebarTopics that is called from the Frontpage\Index.cshtml view uses the same model (WebsiteStructureModel) that is called at the start of the Index view:

@model Web.Areas.Public.Models.WebsiteStructureModel

Now I run into problems when I want to use a sidebar that uses Model A, if the "parent" view uses Model B. It results in an error like this:

The model item passed into the dictionary is of type 'Web.Areas.Public.Models.ProjectDetailsModel', but this dictionary requires a model item of type 'Web.Areas.Public.Models.WebsiteStructureModel'.

Using two @model statements at the beginning of the Index view does not work so I can't pass the second model explicitly to the sidebar as second parameter of the @Html.Partial command. And using a @model statement at the beginning of the partial view is ignored.

There must be some way to call a partial view and have that partial view use a specified model that may not neccessarily be the one used by the calling/parent view - Please help me understand how this can be done!

Upvotes: 3

Views: 2330

Answers (1)

CallumVass
CallumVass

Reputation: 11458

There are 2 ways to do this.

First way:

You could combine your 2 models into a view model:

public class ViewModel
{
    public WebsiteStructureModel WebModel { get; set; }
    public ProjectDetailsModel ProjectModel { get; set; }
}

You'd obviously populate this in your Action and then pass that to the View

Second way:

Rather than calling @Html.Partial("_SidebarTopics") you could create an Action in your controller which will return PartialView("_SidebarTopics", model); where model is the model passed into the partial view, for example:

@section SBLeft {
    @Html.Action("SidebarTopics", new { /* route params */ });
}

Controller:

public ActionResult SidebarTopics(/* route params */)
{
    var model = new ProjectDetailsModel();
    return PartialView("_SiderbarTopics", model);
}

Upvotes: 5

Related Questions