Take the community feedback survey now.
Take the community feedback survey now.
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);
}
It depends a little on what MVC version you are using, there are a lot of questions like this on stackoverflow
MVC5
http://stackoverflow.com/questions/23494741/mvc-5-render-view-to-string
MVC2
http://stackoverflow.com/questions/483091/render-a-view-as-a-string
Here it is a little more explained
http://www.codemag.com/Article/1312081
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.
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..
Cheers,
//Patrick
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.SetControllerType(templateModel.TemplateType);
existingRequestContext.SetContentLink(pageToRender.ContentLink);
existingRequestContext.SetRoutedData(pageToRender);
existingRequestContext.SetContextMode(ContextMode.Default);
existingRequestContext.RouteData.Values["action"] = "Index";
existingRequestContext.RouteData.DataTokens["namespaces"] = new[] { templateModel.TemplateType.Namespace };
if (!string.IsNullOrWhiteSpace(preferredLanguageToRender))
{
existingRequestContext.SetLanguage(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)
{
((IHttpHandler)this.mvcHandler).ProcessRequest(context);
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
return ((IHttpAsyncHandler)this.mvcHandler).BeginProcessRequest(context, cb, extraData);
}
public void EndProcessRequest(IAsyncResult result)
{
((IHttpAsyncHandler)this.mvcHandler).EndProcessRequest(result);
}
}
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?