1011 1110
1011 1110

Reputation: 781

_Layout and Partial View

Using an MVC5 application and I am trying to load a model within a partial view that is also within the _layout page. This doesn't seem to work as it conflicts with other models loaded up in different views.

I found an alternative with ViewBags, but it's messy and I don't think it's the best approach. Is there a way to load up a partial view within a model that's inside the _layout page so the model loaded from the partial view doesn't conflict with another model?

Updated:

What I'm trying to do is this:

In the _layout page. I'm trying to use an image carousel which is supplied by bootstrap to be interactive with the user (so the user can change the images, titles, and sub-titles).

I created a model to store the data, such as the title, etc. :

public class BannerEditor
{
    public int ID { get; set; }

    [Display(Name="Title")]
    [StringLength(150)]
    public string title { get; set; }

    [Display(Name = "Sub-Title")]
    [StringLength(300)]
    public string subTitle { get; set; }

    [Display(Name = "Image Path")]
    public string imgPath { get; set; }

    [Display(Name= "Starting Banner")]
    public int startBanner { get; set; }
} 

Then for my partial View I wrote some code and tried to load the model.:

@model IEnumerable<webby.Models.BannerEditor>

@foreach (var item in Model)
{
    if (item.startBanner == 1)
    { 
    <div class="item active">
        <img [email protected] alt="...">
        <div class="carousel-caption">
            <h3>@item.title</h3>
            <p>@item.subTitle</p>
        </div>
    </div>
    }
    else
    {
        <div class="item">
            <img [email protected] alt="...">
            <div class="carousel-caption">
                <h3>@item.title</h3>
                <p>@item.subTitle</p>
            </div>
        </div>
    }
}

then in my _Layout page, I just added the Partial.

    <div class="carousel-inner">
        @Html.Partial("BannerLoad")

Here is the controller:

    public ActionResult BannerLoad()
    {
         return PartialView(db.BannerEditors.ToList())
     }

It gives me an error stating that it cannot load the Articles model into my partial view. The model that it needs to load is the BannerEditor. Since my _layout is loaded into every page, and the partial view is loading a model. The partial view's model conflicts with every other loaded model. The models name is "Articles".

Is there a way around this?

Upvotes: 1

Views: 433

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239260

Use child actions for this kind of thing. They're like partial views, but they get their own context, allowing you to fetch and work with whatever model you need to without affecting the rest of the page:

Controller

[ChildActionOnly]
public ActionResult BannerLoad()
{
    var banners = db.BannerEditors.ToList();
    return PartialView(banners);
}

BannerLoad.cshtml

@model IEnumerable<Namespace.To.BannerEditor>

<!-- HTML to display your banners -->

_Layout.cshtml

@Html.Action("BannerLoad");

All that looks pretty similar to what you already have, but there's some key differences:

  1. Partials don't work with actions, that's actually what makes a child action a child action and not a partial. It seems in your current code that you're expecting Html.Partial to render your BannerLoad action, but it will never do that. It will only dump the content from BannerLoad.cshtml onto the page, which because it never got fed an appropriate model, will cause an error.

  2. Partials don't have their own context (because they don't work within a separate action), so they must receive their model from the parent view. If you don't pass a model in (which you aren't), they are automatically passed the "current" model. This will be whatever model the view the main action is using and will obviously change action to action. You cannot set a model on _Layout.cshtml, for example, and have that passed in, as that's not the origin point.

  3. Even if you could set the model on something like _Layout.cshtml, that would only work for that one partial. If you had any other partials, you're still out of luck.

Upvotes: 2

Related Questions