如何将部分视图渲染成string

我有以下代码:

public ActionResult SomeAction() { return new JsonpResult { Data = new { Widget = "some partial html for the widget" } }; } 

我想修改它,以便我可以

 public ActionResult SomeAction() { // will render HTML that I can pass to the JSONP result to return. var partial = RenderPartial(viewModel); return new JsonpResult { Data = new { Widget = partial } }; } 

这可能吗? 有人可以解释一下吗?

请注意 ,我在发布解决scheme之前编辑了问题。

我select了像ASP.NET MVC 4应用程序一样的扩展方法。 我认为这比我见过的一些build议更简单:

 public static class ViewExtensions { public static string RenderToString(this PartialViewResult partialView) { var httpContext = HttpContext.Current; if (httpContext == null) { throw new NotSupportedException("An HTTP context is required to render the partial view to a string"); } var controllerName = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString(); var controller = (ControllerBase)ControllerBuilder.Current.GetControllerFactory().CreateController(httpContext.Request.RequestContext, controllerName); var controllerContext = new ControllerContext(httpContext.Request.RequestContext, controller); var view = ViewEngines.Engines.FindPartialView(controllerContext, partialView.ViewName).View; var sb = new StringBuilder(); using (var sw = new StringWriter(sb)) { using (var tw = new HtmlTextWriter(sw)) { view.Render(new ViewContext(controllerContext, view, partialView.ViewData, partialView.TempData, tw), tw); } } return sb.ToString(); } } 

它允许我做到以下几点:

 var html = PartialView("SomeView").RenderToString(); 

此外,这种方法仍然存在视图的任何模型ViewBag和其他视图数据。

这是一个稍作修改的答案的版本:

 public static string RenderPartialToString(string controlName, object viewData) { ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() }; viewPage.ViewData = new ViewDataDictionary(viewData); viewPage.Controls.Add(viewPage.LoadControl(controlName)); StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { using (HtmlTextWriter tw = new HtmlTextWriter(sw)) { viewPage.RenderControl(tw); } } return sb.ToString(); } 

用法:

 string ret = RenderPartialToString("~/Views/MyController/MyPartial.ascx", model); 

DaveDev的答案对我很好,但是当部分视图调用另一个部分我得到“值不能为空参数名称:视图”

search周围我做了以下似乎运作良好的变种。

  public static string RenderPartialToString(string viewName, object model, ControllerContext ControllerContext) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.RouteData.GetRequiredString("action"); ViewDataDictionary ViewData = new ViewDataDictionary(); TempDataDictionary TempData = new TempDataDictionary(); ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } 

用法:

 String result = MVCHelpers.RenderPartialToString("PartialViewHere", Model, ControllerContext) 

您可以创build将视图渲染为string的扩展。

 public static class RenderPartialToStringExtensions { /// <summary> /// render PartialView and return string /// </summary> /// <param name="context"></param> /// <param name="partialViewName"></param> /// <param name="model"></param> /// <returns></returns> public static string RenderPartialToString(this ControllerContext context, string partialViewName, object model) { return RenderPartialToStringMethod(context, partialViewName, model); } /// <summary> /// render PartialView and return string /// </summary> /// <param name="context"></param> /// <param name="partialViewName"></param> /// <param name="viewData"></param> /// <param name="tempData"></param> /// <returns></returns> public static string RenderPartialToString(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData) { return RenderPartialToStringMethod(context, partialViewName, viewData, tempData); } public static string RenderPartialToStringMethod(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData) { ViewEngineResult result = ViewEngines.Engines.FindPartialView(context, partialViewName); if (result.View != null) { StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { using (HtmlTextWriter output = new HtmlTextWriter(sw)) { ViewContext viewContext = new ViewContext(context, result.View, viewData, tempData, output); result.View.Render(viewContext, output); } } return sb.ToString(); } return String.Empty; } public static string RenderPartialToStringMethod(ControllerContext context, string partialViewName, object model) { ViewDataDictionary viewData = new ViewDataDictionary(model); TempDataDictionary tempData = new TempDataDictionary(); return RenderPartialToStringMethod(context, partialViewName, viewData, tempData); } } 

然后在行动中使用它

 [HttpPost] public ActionResult GetTreeUnit(string id) { int _id = id.ExtractID(); string render = ControllerContext.RenderPartialToString("SomeView"); return Json(new { data = render }); } 

完美的作品(只需要查看名字)
*参数你可以使用模型
*也可以从视图中调用

查看方或呼叫方

 BuyOnlineCartMaster ToInvoice1 = new BuyOnlineCartMaster(); // for passing parameters ToInvoice1.CartID = 1; string HtmlString = RenderPartialViewToString("PartialInvoiceCustomer", ToInvoice1); 

函数生成HTML

  public static string RenderPartialViewToString(string viewName, object model) { using (var sw = new StringWriter()) { BuyOnlineController controller = new BuyOnlineController(); // instance of the required controller (you can pass this as a argument if needed) // Create an MVC Controller Context var wrapper = new HttpContextWrapper(System.Web.HttpContext.Current); RouteData routeData = new RouteData(); routeData.Values.Add("controller", controller.GetType().Name .ToLower() .Replace("controller", "")); controller.ControllerContext = new ControllerContext(wrapper, routeData, controller); controller.ViewData.Model = model; var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); viewResult.View.Render(viewContext, sw); return sw.ToString(); } } 

戴夫,

同一主题的变体(mvc v1.0):

  protected static string RenderPartialToString(Controller controller, string partialName, object model) { var vd = new ViewDataDictionary(controller.ViewData); var vp = new ViewPage { ViewData = vd, ViewContext = new ViewContext(), Url = new UrlHelper(controller.ControllerContext.RequestContext) }; ViewEngineResult result = ViewEngines .Engines .FindPartialView(controller.ControllerContext, partialName); if (result.View == null) { throw new InvalidOperationException( string.Format("The partial view '{0}' could not be found", partialName)); } var partialPath = ((WebFormView)result.View).ViewPath; vp.ViewData.Model = model; Control control = vp.LoadControl(partialPath); vp.Controls.Add(control); var sb = new StringBuilder(); using (var sw = new StringWriter(sb)) { using (var tw = new HtmlTextWriter(sw)) { vp.RenderControl(tw); } } return sb.ToString(); } 

控制器内的用法:

  public string GetLocationHighlites() { IBlockData model = WebPagesMapper.GetLocationHighlites(); // **this** being the controoler instance // LocationPartial.ascx can be defined in shared or in view folder return RenderPartialToString(**this**,"LocationPartial", model); } 

你可以用下面的方法做到这一点:

 var partial = new HtmlString(Html.Partial("_myPartial", Model).ToString());