Join us this Friday for AI in Action at the Virtual Happy Hour! This free virtual event is open to all—enroll now on Academy and don’t miss out.
Join us this Friday for AI in Action at the Virtual Happy Hour! This free virtual event is open to all—enroll now on Academy and don’t miss out.
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?