2

I am using this code to try and render a razor partial view as a string for the purposes of sending an email.

    public static string RenderPartialToString(
        string userControlPath,
        object viewModel,
        ControllerContext controllerContext,
        TempDataDictionary tempData)
    {
        using (var writer = new StringWriter())
        {
            var viewDataDictionary = new ViewDataDictionary(viewModel);
            var view = new WebFormView(controllerContext, userControlPath);
            var viewContext = new ViewContext(
                controllerContext,
                view,
                viewDataDictionary,
                tempData,
                writer
                );

            viewContext.View.Render(viewContext, writer);

            return writer.GetStringBuilder().ToString();
        }

    }

The problem is that I get the follow error:

must derive from ViewPage, ViewPage<TModel>, ViewUserControl, or ViewUserControl<TModel>. Stack Trace:  at  System.Web.Mvc.WebFormView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) at .... RenderPartialToString

How would I fix that ?

1 Answer 1

2

Indeed, WebFormView doesn't inherit from the mentioned classes, just IView. I did a little Google research and got a prototype working. This page was the most helpful.

I created an empty MVC3 application and created the following HomeController. When I run the application, the page shows the rendered string. The resultAsString variable shows how to capture the rendering as a string.

using System;
using System.IO;
using System.Web.Mvc;

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var result = RenderPartial(this.ControllerContext, "This is @DateTime.Now right now");
        var resultAsString = result.Content;
        return result;          
    }

    private ContentResult RenderPartial(ControllerContext controllerContext, string template)
    {
        var temporaryViewPath = string.Format("~/Views/{0}.cshtml", Guid.NewGuid());
        using (var stringWriter = new StringWriter())
        {
            using (var fileStream = System.IO.File.Create(Server.MapPath(temporaryViewPath)))
            {
                using (var streamWriter = new StreamWriter(fileStream))
                {                       
                    streamWriter.WriteLine(template);
                    streamWriter.Close();
                }
                fileStream.Close();
            }
            var razor = new RazorView(controllerContext, temporaryViewPath, null, false, null);
            razor.Render(new ViewContext(controllerContext, razor, new ViewDataDictionary(), new TempDataDictionary(), stringWriter), stringWriter);
            System.IO.File.Delete(Server.MapPath(temporaryViewPath));
            return Content(stringWriter.ToString());
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

would you be able to specify some code ? what exactly should I define it as ?
I posted code from a working prototype. The method signature is different, but you should be able to adapt it to your needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.