/// <summary> /// Used when changes are required to render a view as a string, without altering the ControllerContext for the actual request. /// </summary> private ExtendedControllerContext CloneControllerContext() { ControllerContext copy = new ControllerContext(Request.RequestContext, this); // ControllerContext property might be null, that's why we don't use that overload. /* * We would never want to have partial views rendered outside of the view, i.e. with @Html.Partial(), * emitting JavaScript code into the actual view, because that's not what would be intended. * * This simple overwrite fixes a few scenarios collaterally: * - JavaScript partials don't try to emit JavaScript, because they are rendered using the ExtendedControllerContext. * - The same applies to both partial and JavaScript views being rendered by the AjaxTransformAttribute engine. * * In addition, the only scenario likely to ever want this to happen would be something like an AJAX call, * where we'd like to return both the HTML and the JavaScript, but that can already be handled through the existing methods. */ ExtendedControllerContext context = new ExtendedControllerContext(copy); // required for requests to *.cshtml physical files, in order to render the error view. if (!context.RouteData.Values.ContainsKey(Constants.RouteDataController)) { context.RouteData.Values.Add(Constants.RouteDataController, Constants.RouteDataControllerNotFound); context.RouteData.Values.Add(Constants.RouteDataAction, Constants.RouteDataActionNotFound); } return context; }
/// <summary> /// Gets a view string aftering producing a ControllerContext where it should be rendered. /// </summary> private string InternalGetViewString(string viewName, string controller, object model, Func<string, ControllerContext, ViewEngineResult> findView, ExtendedControllerContext context) { if (!controller.NullOrEmpty()) { context.RouteData.Values["controller"] = controller; } if (viewName.NullOrEmpty()) { viewName = context.RouteData.GetActionString(); } IView view = findView(viewName, context).View; string result = RenderViewToString(context, view, model); return result; }
/// <summary> /// Renders a view as a string. /// </summary> /// <param name="viewName">The view name. </param> /// <param name="controller">The controller name.</param> /// <param name="model">The view model.</param> /// <param name="context">The controller context.</param> public string ViewString(string viewName, string controller, object model, ExtendedControllerContext context) { Func<string, ControllerContext, ViewEngineResult> findView = (name, ctx) => ViewEngines.Engines.FindView(ctx, name, null); return InternalGetViewString(viewName, controller, model, findView, context); }