Render view to string


I want to render a view to a string, given a PageReference. So I need to:

1) Find the controller associated with the page type

2) Get an instance to the controller with correct controller context (node and language)

3) Render the view as a string

How can I achieve this?

May 20, 2015 10:02

The lazy way

var relativUrl = EPiServer.Web.Routing.UrlResolver.Current.GetUrl(pageReference, null, new EPiServer.Web.Routing.VirtualPathArguments { ContextMode = EPiServer.Web.ContextMode.Default });
var url = new Uri(UriSupport.SiteUrl, relativUrl);
var htmlStr = string.Empty;
using (var client = new WebClient()) {
	htmlStr = client.DownloadString(url);

May 20, 2015 17:22

It depends a little on what MVC version you are using, there are a lot of questions like this on stackoverflow



Here it is a little more explained

May 20, 2015 20:58

Thanks guys, I have found out how to render the view thanks to stack but I still need answer on how to get the controller from a page reference, and to get the context right of that controller.

May 21, 2015 10:49

Hi Johan!

About gettting the controller, I think you should be able to go along these lines.

            var myRef = currentPage.ContentLink;
            var httpContext = default(HttpContextBase);
            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var typeRepo = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
            var templateRepo = ServiceLocator.Current.GetInstance<TemplateResolver>();

            var content = contentLoader.Get<IContent>(myRef);
            var type = typeRepo.Load(content.ContentTypeID);
            var template = templateRepo.Resolve(httpContext, type, TemplateTypeCategories.MvcController);
            var controllerName = template.Name.EndsWith("Controller", StringComparison.InvariantCultureIgnoreCase)
                ? template.Name.Substring(0, template.Name.LastIndexOf("Controller", StringComparison.InvariantCultureIgnoreCase))
                : template.Name;

Depending on how you're running it the context part could be tricky though..


May 22, 2015 11:37

I wrote something to render EPiServer pages as a child action. :

    using System.Globalization;
    using System.IO;
    using System.Web.Routing;
    using EPiServer.Core;
    using EPiServer.Web;
    using EPiServer.Web.Routing;

    public class MvcPageDataRenderer 
        private readonly TemplateResolver templateResolver;

        public MvcPageDataRenderer(TemplateResolver templateResolver)
            this.templateResolver = templateResolver;

        public string ExecuteChildRequest(RequestContext existingRequestContext, PageData pageToRender, string preferredLanguageToRender)
            var templateModel = this.templateResolver.ResolveMvcTemplate(existingRequestContext.HttpContext, pageToRender);

            existingRequestContext.SetController(templateModel.TemplateType.Name.Replace("Controller", string.Empty));

            existingRequestContext.RouteData.Values["action"] = "Index";
            existingRequestContext.RouteData.DataTokens["namespaces"] = new[] { templateModel.TemplateType.Namespace };

            if (!string.IsNullOrWhiteSpace(preferredLanguageToRender))
                EPiServer.BaseLibrary.Context.Current["EPiServer:ContentLanguage"] = new CultureInfo(preferredLanguageToRender);

            var handler = new ChildActionHandler(existingRequestContext);

            using (var stringWriter = new StringWriter(CultureInfo.CurrentCulture))
                existingRequestContext.HttpContext.Server.Execute(handler, stringWriter, true);
                return stringWriter.ToString();

    using System;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using System.Web.UI;

    /// <summary>
    /// Shamelessly "inspired" by classes in System.Web.Mvc assembly
    /// It appears that only a System.Web.UI.Page can be executed
    /// as a child request. If you try to execute an MvcHandler
    /// directly an exception (with no detail) is thrown
    /// </summary>
    internal class ChildActionHandler : Page, IHttpAsyncHandler
        internal class ChildActionMvcHandler : MvcHandler
            public ChildActionMvcHandler(RequestContext context)
                : base(context)

            protected override void AddVersionHeader(HttpContextBase httpContext)
        private readonly ChildActionMvcHandler mvcHandler;

        public ChildActionHandler(RequestContext context)
            this.mvcHandler = new ChildActionMvcHandler(context);

        public override void ProcessRequest(HttpContext context)

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
            return ((IHttpAsyncHandler)this.mvcHandler).BeginProcessRequest(context, cb, extraData);

        public void EndProcessRequest(IAsyncResult result)
Edited, May 28, 2015 12:04
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.