diff --git a/src/Umbraco.Web/Mvc/UmbracoMvcHandler.cs b/src/Umbraco.Web/Mvc/UmbracoMvcHandler.cs index 1ace297bfd..649ac54f27 100644 --- a/src/Umbraco.Web/Mvc/UmbracoMvcHandler.cs +++ b/src/Umbraco.Web/Mvc/UmbracoMvcHandler.cs @@ -1,5 +1,7 @@ using System; +using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Web; @@ -38,6 +40,15 @@ namespace Umbraco.Web.Mvc routeDef.Controller = controller; } + /// + /// This is used internally purely to render an Umbraco MVC template to string and shouldn't be used for anything else. + /// + internal void ExecuteUmbracoRequest() + { + StoreControllerInRouteDefinition(); + base.ProcessRequest(RequestContext.HttpContext); + } + protected override void ProcessRequest(HttpContextBase httpContext) { StoreControllerInRouteDefinition(); @@ -54,4 +65,6 @@ namespace Umbraco.Web.Mvc return base.BeginProcessRequest(httpContext, callback, state); } } + + } \ No newline at end of file diff --git a/src/Umbraco.Web/Standalone/StandaloneHttpContext.cs b/src/Umbraco.Web/Standalone/StandaloneHttpContext.cs index 4cf64a8adf..55339e97b6 100644 --- a/src/Umbraco.Web/Standalone/StandaloneHttpContext.cs +++ b/src/Umbraco.Web/Standalone/StandaloneHttpContext.cs @@ -1,5 +1,7 @@ using System; +using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Web; @@ -11,11 +13,59 @@ namespace Umbraco.Web.Standalone /// internal class StandaloneHttpContext : HttpContextBase { + private readonly string _url; + private readonly HttpSessionStateBase _session = new StandaloneHttpSessionState(); + private readonly HttpResponseBase _response; + private readonly HttpRequestBase _request = new StandaloneHttpRequest(); + private readonly TextWriter _writer = new StringWriter(); + private readonly IDictionary _items = new Dictionary(); + + public StandaloneHttpContext() + { + //create a custom response with a custom writer. + _response = new HttpResponseWrapper(new HttpResponse(_writer)); + } + + public StandaloneHttpContext(string url) + : this() + { + if (url == null) throw new ArgumentNullException("url"); + _url = url; + _request = new HttpRequestWrapper(new HttpRequest("", _url, "")); + } + + // fixme - what shall we implement here? + + public override IDictionary Items + { + get { return _items; } + } + + public override HttpSessionStateBase Session + { + get { return _session; } + } public override HttpRequestBase Request { - get { return null; } + get { return _request; } } + + public override HttpResponseBase Response + { + get { return _response; } + } + + } + + internal class StandaloneHttpSessionState : HttpSessionStateBase + { + + } + + internal class StandaloneHttpRequest : HttpRequestBase + { + } } diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index fe60c6959e..a13ed031f8 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -137,12 +137,9 @@ namespace Umbraco.Web.Templates requestContext.RouteData.Values.Add("controller", routeDef.ControllerName); //add the rest of the required route data routeHandler.SetupRouteDataForRequest(renderModel, requestContext, contentRequest); - //create and assign the controller context - routeDef.Controller.ControllerContext = new ControllerContext(requestContext, routeDef.Controller); - //render as string - var stringOutput = routeDef.Controller.RenderViewToString( - routeDef.ActionName, - renderModel); + + var stringOutput = RenderUmbracoRequestToString(requestContext); + sw.Write(stringOutput); break; case RenderingEngine.WebForms: @@ -157,6 +154,33 @@ namespace Umbraco.Web.Templates } + /// + /// This will execute the UmbracoMvcHandler for the request specified and get the string output. + /// + /// + /// Assumes the RequestContext is setup specifically to render an Umbraco view. + /// + /// + /// + /// To acheive this we temporarily change the output text writer of the current HttpResponse, then + /// execute the controller via the handler which innevitably writes the result to the text writer + /// that has been assigned to the response. Then we change the response textwriter back to the original + /// before continuing . + /// + private string RenderUmbracoRequestToString(RequestContext requestContext) + { + var currentWriter = requestContext.HttpContext.Response.Output; + var newWriter = new StringWriter(); + requestContext.HttpContext.Response.Output = newWriter; + + var handler = new UmbracoMvcHandler(requestContext); + handler.ExecuteUmbracoRequest(); + + //reset it + requestContext.HttpContext.Response.Output = currentWriter; + return newWriter.ToString(); + } + private void SetNewItemsOnContextObjects(PublishedContentRequest contentRequest) { // handlers like default.aspx will want it and most macros currently need it