I have run into a situation where I would like to render a partial view to a string and then return it as part of a JSON response like so:
return Json(new { statusCode = 1, statusMessage = "The person has been added!", personHtml = PartialView("Person", person) });
The ability to do something like this would open up a ton of amazing possibilities, so I really scoured the internet looking for a solution. Unfortunately, no one seems to have come up with a clean solution for it, so I dug into the MVC code and came up one…and because I’m such a nice guy, you get to copy it for free. 😉
public abstract class MyBaseController : Controller { protected string RenderPartialViewToString() { return RenderPartialViewToString(null, null); } protected string RenderPartialViewToString(string viewName) { return RenderPartialViewToString(viewName, null); } protected string RenderPartialViewToString(object model) { return RenderPartialViewToString(null, model); } protected string RenderPartialViewToString(string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.RouteData.GetRequiredString("action"); ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } }
Now you can simply do this:
public class MyController : MyBaseController { public ActionResult CreatePerson(Person p) { if (ModelState.IsValid) { try { PersonRepository.Create(p); return Json(new { statusCode = 1, statusMessage = "The person has been added!", personHtml = RenderPartialViewToString("Person", p) }); } catch (Exception ex) { return Json(new { statusCode = 0, statusMessage = "Error: " + ex.Message }); } } else return Json(new { statusCode = 0, statusMessage = "Invalid data!" }); } }
Also note that you can modify these functions to render a View (rather than a PartialView) with this small change:
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName);
Enjoy!
Thank you, this is exactly what I was after.
Rich
AWESOME, This was excactly what I was trying to do.
Thanks!
Josh
Just as an update, you could wrap the StringWriter inside a using statement:
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString(“action”);
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
Good idea, Josh. I will update the post. Thanks. 🙂
thanks, i looking for long time 🙂
😀 Hey, nice. Thanks for the source!
Thanks, just needed exactly the same thing in same scenario 🙂
I would love to use this solution, but I am running into an error!
viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
Error 80 ‘System.Web.Mvc.ViewContext’ does not contain a constructor that takes ‘5’ arguments
Am I forgetting something?
Joris,
This solution was implemented with ASP.NET MVC 2. Maybe you need to upgrade?
awesome! thanks much. this is what i was looking for 🙂
Nice work – thanks for sharing this.
Brilliant,
I’ve tried a whole bunch of different solutions and this is the best and simplest. Supports embedded Html helpers too.
thank you so much… You’ve saved me and my team. thank you for sharing this pearl 😉
Is there any way for calling a partial view in a different controller?
If you’re asking how to render a View that is located on another controller path, I’m pretty sure you can just do this:
RenderPartialViewToString(“~/Path/To/View.aspx”)
I hope that answers your question.
[…] internet. The techniques outlined below are built on the excellent post from Kevin Craft at http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/ this has the advantage of being simple, straight forward and fully support embedded Html […]
[…] http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string […]
This is a pretty good solution it helped a lot with validating partial views but it pollutes your inheritance hierarchy.
I’ve rewritten it as a C# extension method. You can find it on my blog (learningdds.com) or directly from here:
http://learningdds.com/public/ControllerExtension.cs
Hope this is helpful.
Excellent job, thanks!
love it, thanks so much!
I’ve the same problem that Joris has. I use ASP.NET MVC 1 and all the team use it, so I can’t upgrade it to ASP.NET MVC 2.0, any ideas ?
Kip, I would suggest digging through the MVC code. It is open source and that is exactly what I did to come up with this solution. MVC 1 probably isn’t that much different. Find the code that renders a view and then just copy/modify the code around it into a utility function that you can use to render partials.
I was trying to do this very thing but was getting stuck. Your article helped me out!
A solution with HtmlHelper extension method, but not tested in all situation for the moment …
public static string RenderPartialToString(this HtmlHelper html, string viewName, object viewData)
{
var baseOutput = html.ViewContext.Writer;
StringWriter sw = new StringWriter();
try
{
html.ViewContext.Writer = sw;
html.RenderPartial(viewName, viewData);
}
catch(Exception ex )
{
html.ViewContext.Writer = baseOutput;
sw.Dispose();
return ex.Message + ex.StackTrace;
}
html.ViewContext.Writer = baseOutput;
sw.Flush();
return sw.ToString();
}
Wouldn’t an extension to ViewResultBase be neater? e.g. in the Controller:
var viewText = View().RenderToString(this);
var partialViewText = PartialView().RenderToString(this);
// or with a named view and model
var namedViewText = View(“Index”, model).RenderToString(this);
the extension method would then just be
public static string RenderToString(this ViewResultBase viewResult, Controller controller)
{
// init string writer
using (StringWriter sw = new StringWriter())
{
// get the view context
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
// render the view
viewResult.View.Render(viewContext, sw);
// return the string
return sw.ToString();
}
}
and you’d only require one
I’ve just realised this won’t quite work as the viewResult.View property will be null without a call to ViewEngineCollection.FindView or FindPartialView so we would need two methods, one for ViewResult and one for PartialViewResutl and before the line where we create the ViewContext we’d need to call either:
viewResult.View = viewResult.ViewEngineCollection.FindView(controller.ControllerContext, viewResult.ViewName, viewResult.MasterName).View;
or
viewResult.View = viewResult.ViewEngineCollection.FindPartialView(controller.ControllerContext, viewResult.ViewName).View;
Serves me right for posting without checking the code
Sweet as Terry Nutkins!
Great for returning json status, messages and some markup to be insterted onto the page.
I have made this extension to HtmlHelper classe because I don’t call Render() and RenderPartial() in Controller / View, I call render in my own classes which have a reference to the ViewPage HtmlHelper.
I have an HtmlHelper extension which initialize my own control factory, and this control factory give the reference of the Htmlhelper to all controls created by this factory.
Thanks. Exactly what I needed!
Awsome cant wait to try….wondering if i have no update target, i can’t really use the client side validation that mvc2 has..which sucks
Cheers, thanks for sharing this. You have saved me a lot of time!
Thanks. Like everyone else, just what I was looking for. You really are a nice guy!
PS. And a lovely couple!
Thanks. 🙂
I am new to MVC. Can anyone please post an example of how to use the json html result in view. Thanks.
Consuming the JSON result actually has very little to do with MVC. It will be consumed via JavaScript. You will make an AJAX request to the server and then process the result accordingly. For example, if you have an MVC action that returns the same result I used in my blog post, then you can consume the result using jQuery as follows:
$.post(‘/addUser’, userData, function(result) {
alert(result.statusMessage);
if (result.statusCode == 1) {
var newPerson = $(result.personHtml);
$(“#people”).append(newPerson);
}
});
That’s great.
Thanks for sharing, helps a lot.
Great, it even works in MVC3.
[…] no out-of-the-box support for rendering partial views to strings, but I found this create post ASP.NET MVC Render Partial View to String which shows how to implement a RenderPartialViewToString method. To avoid the need of a parent […]
Amazing. Thanks.
Good job mate. Exactly the case I need. Thanks
I’ve been searching a while for this. Exactly what I needed. Huge thanks!
I wish we were using MVC 2.0. As
viewResult.View.Render(viewContext, sw);
Doesn’t write anything to my streamwriter. I’ve seen another solution where it mucks around with fake contexts, but I need session variables in my view so it errors if I try doing that. 😦
[…] って、意味わかんないけど; メールにしたいとか、 とにかく、HTTPレスポンス以外の用途でVierwを使えればな~ なことがある。 で、どうするか? ズバリの記事がありました。 http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/ […]
Thanks very much for sharing that Kevin. Very much appreciated.
[…] RenderPartialViewToString method came from here and renders a partial to string using the Razor view […]
Works like a charm, thank you so much!
Hi All,
Just more than awesome!!!
What a great article!!
Thanks to all for sharing!!
Thanks,
Amol
You really are such a nice guy =D
I need to render partial views to build a CMS. I want to dynamically load views (from a place where user installs modules, which are in essence, ASP.NET MVC Views) and then render them in the server (execute them, and get the result out of them), and then put it inside the specified place. Your code was a good starting point for me. However, still I’m not able to figure out how to do that. Thanks.
Thank you for such nice article 🙂
It has helped me a lot.
Thanks buddy.
After a struggle of 2 days, this was the best and simple one.
Thanks a lot
great article , you save me alot
Wonderful. Here my edited version so code can be moved outside the controller (maybe in a helper file)
public static string RenderViewToString(ControllerContext context, ViewDataDictionary viewData, TempDataDictionary tempData, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = context.RouteData.GetRequiredString(“action”);
viewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, tempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
Then can be called from the controller like this:
MyHelper.RenderViewToString(this.ControllerContext, this.ViewData, this.TempData, “_PartialViewName”, MyObject)
In my case I made two versions, one requiring only the controller, viewname and model, since in most of the cases we only need to render simple partial views that work with model or viewmodel.
Thanks for sharing. Just what I needed.
Great article – thanks!
Anybody know how to do this outside of web apps / MVC, e.g. in a WinForms app or console app?
Couldn’t you achieve the same thing making a View with JSON in it?
Probably, but its more work, especially if you need to do it often. Its also not really a traditional use of the view considering ASP.NET MVC has JSON functionality built right into the controller. Good suggestion, though!
Just wondering if you got the RenderViewToString from the StackOverflow post that predates it, here: http://stackoverflow.com/questions/483091/render-a-view-as-a-string/2759898#2759898
Looks pretty similar.
Nope, didn’t get it from there. It took me several hours of digging through the MVC code to come up with my solution. I’m guessing you came up with your solution in the same manner, which is why they are so similar.
Exactly what I was looking for..Thanks for posting
Thanks for the code, this help a lot. Is there a way to remove the tabs and line breaks (“\r”, “\n”, “\t”, etc…) from the result?
This really helped me, thanks. Here’s how I removed the “\r”…etc:
Change to return MvcHtmlString:
public static MvcHtmlString RenderViewToString(ControllerContext context, string viewName, object model)
return MvcHtmlString.Create(sw.GetStringBuilder().ToString());
Here’s the entire:
public static MvcHtmlString RenderViewToString(ControllerContext context, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = context.RouteData.GetRequiredString(“action”);
ViewDataDictionary viewData = new ViewDataDictionary(model);
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
viewResult.View.Render(viewContext, sw);
return MvcHtmlString.Create(sw.GetStringBuilder().ToString());
}
}
I do not see how MvcHtmlString-ifying should remove any tabs or line breaks. In fact, it does not. MvcHtmlString does not modify the wrapped string at all. To get rid of the above mentioned items you could use something like TidyNet or TidyManaged. Though, this is pretty much a side-effect. BTW, why would you want to do this?
Hey, this is super helpful. I’m having some trouble unit testing it, though; I need to somehow mock the ViewEngines.Engines.FindPartialView(ControllerContext, viewName) call. Mocking up up a fake ControllerContext is straightforward enough, but I can’t find a way to set something up for the FindPartialView method.
I’ve tried http://stackoverflow.com/questions/3621961/asp-net-mvc-unit-testing-renderpartialviewtostring-with-moq-framework, but without luck (what is the RouteConfigurator class?) and http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/ (similar idea, same problem). Any thoughts? How did you unit test your example?
Did you ever figure out how to unit test this? I’m having the same issue.
It works fine if I don’t have a nested partial. If I have @Html.Partial(“_PartialName”, Model) instead of a partial that is rendered to string, it leaves out the nested partial.
Any suggestions?
How can I get a nested partial view to render with this logic?
Ex. From a partial with name “_ParentPartial”
…
@Html.Partial(“_ChildPartialName”, Model)
…
Nevermind, some of my logic excluded the partial from rendering. Works like a charm!
[…] partial view to string. I implemented this method in BaseController as protected method. Thanks to Kevin Craft to showed the implementation in his […]
Hi Just wondering why you wouldn’t just do
return sw.ToString();
rather than
return sw.GetStringBuilder().ToString();
I also am having trouble unit testing this – please post how you unit tested it (or verify that you didn’t)
This is what I actually came here for too. As far as I can see this shortcoming is due to classical Asp.Net on top of which Mvc resides. Despite a lot of horse-trading* there has been no solution to the problem yet.
*precompiled view, custom view engine, in-memory-view-rendering, headless browser, hosting Asp.Net app from disk location, layers and layers of indirection, etc.
[…] to render that view to a string. One case I’ve seen in other blogs is that you may want to return an html string in a JSON response so that script on the calling page can update a partial page […]
Hi Kevin,
This was just what I was looking for. I ended up writing a blog post about my own use of this technique and why it was useful to me. I’ve clearly linked back to you here; I hope that’s okay. You can read the blog post here:
http://icanmakethiswork.blogspot.com/2012/07/rendering-partial-view-to-string.html
Thanks again – you’ve saved me some hard work!
Thanks for the backlink. I’m glad it helped you out. 🙂
Good post thanks!. However when the partial view is rendering it is adding extra blank spaces.
eg:
please look at the value attribute of the input element.
Have any idea?
Awesome, of all the solutions I found this is the only one which actually worked as expected
[…] into an html element. The idea of rendering a partial view from a controller came from this other blog. […]
Extremely you’re such a nice guy. 🙂
I get always an exception in the .Render() method that something in the writer object is null. I use mvc 4.0. Any ideas?
the best solution on the net to this issue, thanks for posting!!
best solution on the net, thanks for posting!
Hey Crafty.
Thanks for your article which had helpled me in rendering the partial view as string from controller.
But is there any way to UnitTest this method as i am having nightmare in testing this method.
If you already have any sample that would really help me a lot..
Thank you
You are a hero.
Hi Crafty, I tried to implement your code in MVC 4, but I generated an error to this:
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, “”); This error says: Value cannot be null.
Parameter name: controllerContext. Please help, Thanks a lot.
I have not worked with MVC 4 yet, but I assume my solution is probably outdated by now. It has been several years, after all. 🙂
Superb work.
I’m getting an error when executing this line:
viewResult.View.Render(viewContext, sw);
“Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property”
This problem only occured when trying to convert large data such as 10k rows and above.
Thank you.
Now the better solution is use ASP.NET Razor view engine.
Great Post….Thanks a ton.
[…] important thing here is the method “RenderPartialViewToString”. I ran across this which was a tremendous resource in solving my problem here, which was returning a Json Object with […]