以编程方式将视图渲染为字符串

我想获取一个视图将在字符串中生成的html代码,在我的控制器中修改它,然后将其添加到我的JsonResult。

我发现代码可以做我正在谈论的部分内容。 我想从aspx View中做到这一点。

– 额外说明:

假设我有一个页面Frame.aspx / Controller / Frame将返回

我希望在它出来之前得到响应,所以我可以用jsonp包装它。 我不希望每次都在代码中编辑返回结果,这就是我想以编程方式加载视图的原因。

/ Controller / Frame当前返回Frame.aspx的内容: hello

假设有一个函数可以在字符串生成器中呈现视图

 StringBuilder sb = new StringBuilder(); RenderView(sb, "Frame"); 

现在拿sb并用jsonp包装它:

 public JsonResult Frame(string callback) { StringBuilder sb = new StringBuilder(); RenderView(sb, "Frame"); return new JsonResult { Data = "(function() { " + callback + "(" + clientResponse + "); })();" , JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } 

这就像一个魅力(通过SO得到它)。

我这样使用它:

 public class OfferController : Controller { [HttpPost] public JsonResult EditForm(int Id) { var model = Mapper.Map(_repo.GetOffer(Id)); return Json(new { status = "ok", partial = this.RenderPartialViewToString("Edit", model) }); } } public static partial class ControllerExtensions { public static string RenderPartialViewToString(this ControllerBase controller, string partialPath, object model) { if (string.IsNullOrEmpty(partialPath)) partialPath = controller.ControllerContext.RouteData.GetRequiredString("action"); controller.ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath); ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); // copy model state items to the html helper foreach (var item in viewContext.Controller.ViewData.ModelState) if (!viewContext.ViewData.ModelState.Keys.Contains(item.Key)) { viewContext.ViewData.ModelState.Add(item); } viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } } 

Mike Hadlow在博客中发表了一篇名为CaptureActionHtml()的函数。 我用它来编写较小的,更易于管理的报告,然后传递它们。

http://mikehadlow.blogspot.com/2008/06/mvc-framework-capturing-output-of-view_05.html

 using System; using System.IO; using System.Web; using System.Web.Mvc; namespace Suteki.Common.Extensions { public static class ControllerExtensions { ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The controller /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this TController controller, Func action) where TController : Controller { return controller.CaptureActionHtml(controller, null, action); } ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The controller /// The master page to use for the view /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this TController controller, string masterPageName, Func action) where TController : Controller { return controller.CaptureActionHtml(controller, masterPageName, action); } ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The current controller /// The controller which has the action to execute /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this Controller controller, TController targetController, Func action) where TController : Controller { return controller.CaptureActionHtml(targetController, null, action); } ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The current controller /// The controller which has the action to execute /// The name of the master page for the view /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this Controller controller, TController targetController, string masterPageName, Func action) where TController : Controller { if (controller == null) { throw new ArgumentNullException("controller"); } if (targetController == null) { throw new ArgumentNullException("targetController"); } if (action == null) { throw new ArgumentNullException("action"); } // pass the current controller context to orderController var controllerContext = controller.ControllerContext; targetController.ControllerContext = controllerContext; // replace the current context with a new context that writes to a string writer var existingContext = System.Web.HttpContext.Current; var writer = new StringWriter(); var response = new HttpResponse(writer); var context = new HttpContext(existingContext.Request, response) {User = existingContext.User}; System.Web.HttpContext.Current = context; // execute the action var viewResult = action(targetController); // change the master page name if (masterPageName != null) { viewResult.MasterName = masterPageName; } // we have to set the controller route value to the name of the controller we want to execute // because the ViewLocator class uses this to find the correct view var oldController = controllerContext.RouteData.Values["controller"]; controllerContext.RouteData.Values["controller"] = typeof(TController).Name.Replace("Controller", ""); // execute the result viewResult.ExecuteResult(controllerContext); // restore the old route data controllerContext.RouteData.Values["controller"] = oldController; // restore the old context System.Web.HttpContext.Current = existingContext; return writer.ToString(); } } } 

这是在MVC 2.0和> net 4.0中捕获视图的另一种解决方法。 我刚刚为安德鲁斯原创内容添加了几行代码。

  public static class ControllerExtensions { ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The controller /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this TController controller, Func action) where TController : Controller { return controller.CaptureActionHtml(controller, null, action); } ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The controller /// The master page to use for the view /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this TController controller, string masterPageName, Func action) where TController : Controller { return controller.CaptureActionHtml(controller, masterPageName, action); } ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The current controller /// The controller which has the action to execute /// The action to execute /// The HTML output from the view public static string CaptureActionHtml( this Controller controller, TController targetController, Func action) where TController : Controller { return controller.CaptureActionHtml(targetController, null, action); } ///  /// Captures the HTML output by a controller action that returns a ViewResult ///  /// The type of controller to execute the action on /// The current controller /// The controller which has the action to execute /// The name of the master page for the view /// The action to execute /// The HTML output from the view /// public static string CaptureActionHtml(this Controller controller, TController targetController, string masterPageName, Func action) where TController : Controller { if (controller == null) { throw new ArgumentNullException("controller"); } if (targetController == null) { throw new ArgumentNullException("targetController"); } if (action == null) { throw new ArgumentNullException("action"); } // pass the current controller context to orderController var controllerContext = controller.ControllerContext; targetController.ControllerContext = controllerContext; // replace the current context with a new context that writes to a string writer var existingContext = HttpContext.Current; var writer = new StringWriter(); var response = new HttpResponse(writer); var context = new HttpContext(existingContext.Request, response) { User = existingContext.User }; HttpContext.Current = context; // execute the action var viewResult = action(targetController); // change the master page name if (masterPageName != null) { viewResult.MasterName = masterPageName; } // we have to set the controller route value to the name of the controller we want to execute // because the ViewLocator class uses this to find the correct view var oldController = controllerContext.RouteData.Values["controller"]; controllerContext.RouteData.Values["controller"] = typeof(TController).Name.Replace("Controller", ""); // execute the result viewResult.ExecuteResult(controllerContext); StringWriter sw = new StringWriter(); var xx = targetController.TempData["pdf"]; //var viewContext = new ViewContext(controllerContext, viewResult.View, new ViewDataDictionary(targetController.ViewData.Model), new TempDataDictionary(), sw); var viewContext = new ViewContext(controllerContext, viewResult.View, viewResult.ViewData, new TempDataDictionary(), sw); viewResult.View.Render(viewContext, HttpContext.Current.Response.Output); response.Flush(); // restore the old route data controllerContext.RouteData.Values["controller"] = oldController; // restore the old context HttpContext.Current = existingContext; return sw.ToString(); } } } 

干杯!!