Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net MVC layout and partial views

let's consider two views that use the same layout composed of:

  • A left column containing a "body" (which is filled differently by both views)
  • A right column that displays general information (passed via the model)

Instead of defining the right part twice, I wondered if I could create a PartialView to link directly from the layout page.

The problem is that the partial views implicitely inherit their models from the view that is being rendered. And since each view has its own model, I end up with a model type mismatch in the partial view.

From here I see two solutions:

  • I could insert the common part of the view model in the ViewBag. Unfortunately this means that each view that uses this layout has to implement this "convention" but nothing warns the developer about it at compile time...
  • I could use polymorphism to make each view model inherit from the same base class (edit: or interface) that the Partial Views uses. This would work up to a certain extend but would potentially exponentially increase in complexity as soon as I have a second partial view in the same layout.

So here are the questions:

  • Am I right with the assumptions above?
  • Do you see any other possibility?
  • Any return on experience on this?

Thanks a lot, TB.

like image 562
Timothée Bourguignon Avatar asked Jun 26 '12 11:06

Timothée Bourguignon


People also ask

What is difference between layout and partial view in MVC?

A layout is something that we can include once in a single page and we can use the same layout to any number of pages. A partial view is something that we can include the same content any number of times in a single page(where it is required) and can be used in any number of pages.

Can I use layout in partial view?

Partial views shouldn't be used to maintain common layout elements. Common layout elements should be specified in _Layout. cshtml files. Don't use a partial view where complex rendering logic or code execution is required to render the markup.

What is layout view and partial?

Layout view is often used to set the layout of the page. For example, if each page of a web application need the same layout, we can set the same part in layout view and use @RenderBody() to reserve space for body part. Partial view is used to reduce the duplication of view content(not include the layout part).

When should partial views be used?

You should use partial views in two primary cases: When you need to reuse a similar "group of components" in multiple locations in a website (e.g. a "login form" might be used in different places in the website).


1 Answers

Use an Interface and implement it on the two models, this is exactly the kind of thing they're used for.

Here is an example of two different Views using two different Models that both implement an interface. This is subtyping instead of ad-hoc polymorphism.

public class ViewModelOne : IReusableView
{
    public string Name { get; set; }
    public string Something { get; set; }
    public int ANumber { get; set; }
}

public class ViewModelTwo : IReusableView
{
    public string Name { get; set; }
    public string Thing { get; set; }
    public string SomethingElse { get; set; }
    public int ANumber2 { get; set; }
}

public interface IReusableView
{
    string Name { get; }
}

So we have the really simple partial view here that is 'InnerPartialView':

@model TestIntegration.Models.IReusableView
<div>
    @Model.Name
</div>

Which is used in the home and about pages of this example controller:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View(new ViewModelOne() { Name = "hello", Something="sdfsdfs", ANumber = 1 });
        }

        public ActionResult About()
        {
            return View(new ViewModelTwo() { Name = "hello 2", SomethingElse = "aaaddd", ANumber2 = 10, Thing="rand" });
        }
    }

The home view:

@model TestIntegration.Models.ViewModelOne
@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    @Html.Partial("InnerPartialView")
</p>

The about view:

@model TestIntegration.Models.ViewModelTwo
@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
         @Html.Partial("InnerPartialView")
</p>
like image 76
mattmanser Avatar answered Sep 20 '22 17:09

mattmanser