7

I have a partial view and int it, there is no trace of any inheritance from any layout. But whenever I want to use it (render it) inside a view, the layout gets repeated once for the view, and once for the partial view. This post suggests to create an empty layout. But I think this is the workaround. Is there anyway to stop loading layout (master layout) for partial views. I don't understand, why when there is no code to use the master layout, why should it get loaded. It's just like creating a page in ASP.NET and seeing that it inherits from a master page without having <%@ Master ... directive.

This is my partial view:

@* Recursive category rendering *@
@using Backend.Models;

@{
    List<Category> categories = new ThoughtResultsEntities().Categories.ToList();
    int level = 1;
 }

 @RenderCategoriesDropDown(categories, level)

 @helper RenderCategoriesDropDown(List<Category> categories, int level)
 {
     List<Category> rootCategories = categories.Where(c => c.ParentId == null).ToList();
     <select id='categoriesList' name='categoriesList'>
     @foreach (Category rootCategory in rootCategories)
     {
         <option value='@rootCategory.Id' class='level-1'>@rootCategory.Title</option>
         @RenderChildCategories(categories, level, rootCategory.Id);
     }
     </select>
 }

 @helper RenderChildCategories(List<Category> categories, int level, int  parentCategoryId)
 {
     string padding = string.Empty;
     level++;
     List<Category> childCategories = categories.Where(c => c.ParentId == parentCategoryId).ToList();
     foreach (Category childCategory in childCategories)
     {
          <option value='@childCategory.Id' class='level-@level'>@padding.PadRight(level, '-') @childCategory.Title</option>
          @RenderChildCategories(categories, level, childCategory.Id);
     }
     level--;
 }
Community
  • 1
  • 1
Saeed Neamati
  • 35,341
  • 41
  • 136
  • 188

2 Answers2

17

I was able to reproduce this issue when rendering partial pages through ajax calls. The

return View("partialpage")   

would always accompany with layout. I have overridden this behavior by explicitly calling

return PartialView("partialpage")  
Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155
  • Good practice. I didn't know that PartialView is one of the ActionResult types. But what you do when you don't work with ajax and you want to build your page based on putting together some partial views (something like a dashboard). Which method? – Saeed Neamati Jul 01 '11 at 11:35
  • 1
    i use RenderPartial or RenderAction depending upon the availability of model – Muhammad Adeel Zahid Jul 01 '11 at 11:37
11

The layout might be coming from your ~/Views/_ViewStart.cshtml

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

You could try overriding this in your partial view like:

@{
    Layout = null;
}
Daniel Liuzzi
  • 16,807
  • 8
  • 52
  • 57
  • This worked for me. Thank you. But isn't it weird? In WebForms it's like always saying that "this page doesn't have a master page", or "this user control doesn't have a master page". I mean, seems that the default value should be `Layout = null;` and there shouldn't be the necessity to say it explicitly. – Saeed Neamati Jul 01 '11 at 11:19
  • WebForms view engine used different file extensions (.ascx for partials, .aspx for pages). Razor on the other hand uses the same extension for everything, so that might be the reason (not 100% sure on this though). By the way I couldn't reproduce your issue. How are you calling your partial? I tried with @Html.Partial("_Foo") and it just worked. No need to set Layout to null. – Daniel Liuzzi Jul 01 '11 at 11:25
  • 1
    I used `@Html.Action("PartialViewControllerAction")`. Method documentation says that it returns the rendered result of partial view execution. – Saeed Neamati Jul 01 '11 at 11:33
  • OK, so then you're calling a child action not a partial view. Let me see if I can repro it now. – Daniel Liuzzi Jul 01 '11 at 11:42
  • In your child action are you using `return View();` by any chance? Because if you do `return PartialView();` the layout is automatically removed for you. – Daniel Liuzzi Jul 01 '11 at 11:46
  • Yeah, I call `return View();` and I should call `return PartialView();` as @muhammad-adeel-zahid said. – Saeed Neamati Jul 01 '11 at 11:53