-
Rendering a partial view n number of times with ASP.NET MVC
Posted on July 30th, 2010 No commentsUPDATE
After spending a little more time working with MVC2 and having read this comment by Brad Wilson, I now know about the existence of Html.Partial which renders a partia view directly to a string.
This simplifies my code in a number of ways. Firstly the code itself is just simpler. There’s no longer any need to render the partial out to a string because our new Partial method does this for us.
The RenderPartials method now looks like:
public static void RenderPartials(this HtmlHelper helper, string partialViewName, IEnumerable models, string htmlFormat) { foreach (var view in models.Select(model => helper.Partial(partialViewName,model))) { helper.ViewContext.HttpContext.Response.Output.Write(htmlFormat, view.ToHtmlString()); } }
Much cleaner !!
This also fixed up the problem of using a names partial view rather than the full path. Again, all of this is handled by our new Partial method which leaves us get on with the important stuff.
Thanks again to the MVC team for including something extremely useful in MVC2.
Origional Post
I’ve recently been thinking about the way that RenderPartial works in ASP.NET MVC and one of the things I’ve been wanting is a way to render a partial view n number of times based on some kind of collection.
I had a look around and didn’t find anything so I’ve written out a solution which I’d like to share. It’s by no means a perfect solution right now. I’d like to add support for named partials rather than specifying the path to the partial view and this will be part of the next iteration.
Why?
The main reason for this solution is to solve the problem of having looping code in the views. This can quite often get a bit messy especially when mixing html and C#.The implementation
Firstly, here’s the method signature:
public static void RenderPartials(this HtmlHelper helper, string partialViewName, IEnumerable models, string htmlFormat)
- The partialViewName parameter is going to be the location of our partial view. I’m going to be improving this to accept just the name of the view in this next iteration.
- The models parameter contains a collection and for each item in that collection, we’ll render out our partial view.
- The htmlFormat paramter is an optional parameter. This basically allows you to specify code that you’d like to be part of the iteration of each model item with {0} being the partial view itself (I’ll give an example below)
The method:
So here’s the method as it stands at the moment.
public static void RenderPartials(this HtmlHelper helper, string partialViewName, IEnumerable models, string htmlFormat) { htmlFormat = (htmlFormat.IsNullOrEmpty()) ? "{0}" : htmlFormat; foreach (var model in models) { var viewDataDictionary = new ViewDataDictionary(model); var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); var x = new ViewPage {ViewData = viewDataDictionary, Url = urlHelper, ViewContext = helper.ViewContext}; Control control = x.LoadControl(partialViewName); x.Controls.Add(control); var sb = new StringBuilder(); using (var sw = new StringWriter(sb)) { using (var tw = new HtmlTextWriter(sw)) { x.RenderControl(tw); helper.ViewContext.HttpContext.Response.Output.Write(htmlFormat,sb); // Output content to the response stream } } } }
with a simple overload method to make the htmlFormat parameter optional:
public static void RenderPartials(this HtmlHelper helper, string partialViewName, IEnumerable models) { helper.RenderPartials(partialViewName,models,null); }
How do we use it?
Here’s a basic example of how we can use this new RenderPartials method within one of our views:
<%: Html.RenderPartials("~/Areas/OrderManagement/Views/Shared/Order.ascx", Model.Orders, "<span class="\"specialOrder\"">{0}</span>"); %>
This will now render our partial view Order.ascx once for each order in Model.Orders. Our third parameter for htmlFormat specifies some html that we’re wrapping our partial view in with {0} being the partial view itself. This allows for our front end team to add custom html to specific renderings of our partial view.
Conclusion
So the main idea of this method is to neaten up our views a little bit whilst at the same time, giving our front end guys enough control and flexibility to make the solution viable.If you have any comments or sugestions you can either drop me a line at jamie@jamie-dixon.co.uk or leave a comment below.
You can follow me on Twitter at http://twitter.com/jamiedixon


