Both the ASPX and Razor view engines can define the master page/layout to use at a global level. For ASPX it's in the web.config:
<pages masterPageFile="~/Views/Shared/Site.Master">For Razor it's in the view start file for your chosen language, in my case it's C# (_ViewStart.cshtml):
...
</pages>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
ASPX view engine partial views (*.ascx) include (apart from the obvious file extension difference) a specific directive instructing the view engine that it is a partial view (@ Control) and not a regular view (@ Page). This causes the view engine to knowingly treat it as a partial view, rendering only its contents. However, since Razor views are all the same there is no declaration to indicate that the view code in one .cshtml file is for a partial view versus a full view. Any Razor view will have the same startup rules applied.
When a Razor view is rendered as a partial from another view, such as:
@Html.Partial("mypartialview")
or
<% Html.RenderPartial("mypartialview"); %>
the view engine seems to recognize that the view is being loaded as a partial and (presumably) changes the inner view's Layout property to null and things work as desired.
However, when you make an MVC action call that specifically loads JUST a partial view as the ViewResult with the intent of doing a partial page refresh, the results will differ based on the the view engine. For an ASPX engine partial view (i.e. *.ascx) the view will load and render as is. It contains no references to a master page and the view engine knows explicitly that it is a "@ Control" and thus does not wrap it in any default master page, if one is defined. On the other hand, a Razor view is loaded as any other view and will include the master layout set by default. What is intended as a partial page update will actual return with all of the layout pages HTML around it. In order to keep a Razor view as a partial view, any existing value for the view's Layout property must be negated. This code can be placed in a code block of any view that is intended to be a partial view:
@{
this.Layout = null;
}
This will cancel out any default master layout setting and render the view with only that view's contents. When the same view is included in another view as a partial, the above code will have not effect since the calling view has already nulled out the layout file anyway.
If you wanted to, you could use a view for either a full view (with the default layout's content) or a partial view by conditionally nulling out the Layout property based on some view data set by an appropriate controller action. Combined with a parameter passed in by the AJAX caller, this could provide a useful mechanism for reusing view elements.
7 comments:
I ran into this problem just today (I am learning razor by myself) this post was very helpful.
I had a problem where I was doing a RenderAction within the layout view, I was not aware of the _ViewStart file so since the controler rendered was returning a ViewResult I got a stack overflow due load the layout recursively.
What i did is I just changed the return type of my Controller to PartialView and that was it. I learnt a lot just by resarching this, thanks.
This solved my problem. Thank very much!
This was exactly what I was searching for - an explanation of partial views with the Razor view engine. However, the better solution to my problem was actually to use Pancho's suggestion of using PartialView() in the controller action rather than changing the layout in the view.
@Pancho - Thank you for pointing out the PartialView() method. Somehow, I never saw that. It makes sense that they'd include that in the controller for just such scenarios. It's certainly a better and clearer solution to using the standard View() method and having to nullify the layout property in the partial view markup. Obviously I haven't explored enough.
This was exactly what I needed. I had problems with multiple jQuery calls because the *.js files were loaded exponentially.
Hi!
This is a nice article. Thank for sharing your knowledge. There are some other links related to "Calling partial view using Ajax in ASP.NET MVC 4". I hope this is a
very useful for developers.
http://www.mindstick.com/Articles/8e131adf-2621-4cd7-8557-770c1ede799c/?Calling%20partial%20view%20using%20Ajax%20in%20ASP.NET%20MVC%204
http://ciintelligence.blogspot.in/2012/06/aspnet-mvc-ajax-load-with-partial-view.html
Very helpful. Thanks for sharing ur exp. knowledge
Post a Comment