How to generate a HTML of a given partial view on ASP.NET view engine is known.
But if this functionality is used on razor partial view it does not work, as exception says the partial view does not derive from "UserControl".
How to fix the rendering to support razor partial view?
I need this because I generate emails form this partial views ...
UPDATE:
Code that fails (@mcl):
public string RenderPartialToString(string controlName, object viewData)
{
ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
viewPage.Url = this.GetUrlHelper();
string fullControlName = "~/Views/Email/" + controlName + ".ascx";
viewPage.ViewData = new ViewDataDictionary(viewData);
viewPage.Controls.Add(viewPage.LoadControl(fullControlName));
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
viewPage.RenderControl(tw);
}
}
return sb.ToString();
}
Although adequate answers have already been given, I'd like to propose a less verbose solution, that can be used without the helper methods available in an MVC controller class. Using a third party library called "RazorEngine" you can use .Net file IO to get the contents of the razor file and call
Get the third party library here.
Borrowing @jgauffin answer as an HtmlHelper extension:
Usage in a razor view:
great code; little hint: if you sometimes have to bypass more data and not only the viewmodel ..
You could also use the
RenderView Controller extension
from here (source)and use it like this:
it works for razor and web-forms viewengines
I saw that someone was wondering how to do it for another controller.
In my case I had all of my email templates in the Views/Email folder, but you could modify this to pass in the controller in which you have views associated for.
Essentially what this does is take a controller, such as AccountController and modify it to think it's an EmailController so that the code will look in the
Views/Email
folder. It's necessary to do this because theFindView
method doesn't take a straight up path as a parameter, it wants aControllerContext
.Once done rendering the string, it returns the AccountController back to its initial state to be used by the Response object.
Update