asp.net-mvc 如何将局部视图渲染为字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2537741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Render Partial View into a String
提问by DaveDev
I have the following code:
我有以下代码:
public ActionResult SomeAction()
{
return new JsonpResult
{
Data = new { Widget = "some partial html for the widget" }
};
}
I'd like to modify it so that I could have
我想修改它以便我可以拥有
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 }
};
}
is this possible? Could somebody explain how?
这可能吗?有人可以解释一下吗?
note, I edited the question before posting the solution.
注意,我在发布解决方案之前编辑了问题。
采纳答案by DaveDev
This is a slightly modified version of an answer that works:
这是一个有效的答案的略微修改版本:
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();
}
Usage:
用法:
string ret = RenderPartialToString("~/Views/MyController/MyPartial.ascx", model);
回答by Ted Nyberg
I opted for an extension method like the following for an ASP.NET MVC 4 app. I think it's simpler than some of the suggestions I've seen:
我为 ASP.NET MVC 4 应用程序选择了如下扩展方法。我认为它比我看到的一些建议更简单:
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();
}
}
It allows me to do the following:
它允许我执行以下操作:
var html = PartialView("SomeView").RenderToString();
Also, this approach persists any Model, ViewBagand other view data for the view.
此外,这种方法会保留视图的任何Model、ViewBag和其他视图数据。
回答by Vdex
DaveDev's answer worked well for me, however when the partial view calls another partial I get "Value cannot be null. Parameter name: view"
DaveDev 的回答对我来说效果很好,但是当局部视图调用另一个局部视图时,我得到“值不能为空。参数名称:视图”
Searching around I have made a variant of the followingthat seems to work well.
四处搜索,我制作了以下似乎效果很好的变体。
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();
}
}
Usage:
用法:
String result = MVCHelpers.RenderPartialToString("PartialViewHere", Model, ControllerContext)
回答by Oleksandr Fentsyk
You can create extension that render view into 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);
}
}
And then use it in action
然后在行动中使用它
[HttpPost]
public ActionResult GetTreeUnit(string id)
{
int _id = id.ExtractID();
string render = ControllerContext.RenderPartialToString("SomeView");
return Json(new { data = render });
}
回答by Arun Prasad E S
Works perfect (Only view name required)
* for parameters you can use a model
* can call this from a view also
完美运行(仅需要视图名称)
* 对于参数,您可以使用模型
* 也可以从视图中调用它
View side or Calling Side
查看方或呼叫方
BuyOnlineCartMaster ToInvoice1 = new BuyOnlineCartMaster(); // for passing parameters
ToInvoice1.CartID = 1;
string HtmlString = RenderPartialViewToString("PartialInvoiceCustomer", ToInvoice1);
Function Generating HTML
函数生成 HTML
public class BuyOnlineCartMaster
{
public int CartID { get; set; }
}
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();
}
}
Partial View page
部分查看页面
@{
var ModelContents = (Common.BuyOnlineCartMaster)ViewData.Model;
}
Your cart id : @(ModelContents.CartID)
回答by jim tollan
Dave,
戴夫,
a variation on the same theme (mvc v1.0):
同一主题的变体(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();
}
usage within controller:
控制器内的用法:
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);
}
回答by Dan P
You can do that out of the box with:
您可以通过以下方式开箱即用:
var partial = new HtmlString(Html.Partial("_myPartial", Model).ToString());
回答by Krishna Soni
public virtual string RenderPartialViewToString(string viewName, object viewmodel)
{
if (string.IsNullOrEmpty(viewName))
{
viewName = this.ControllerContext.RouteData.GetRequiredString("action");
}
ViewData.Model = viewmodel;
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = System.Web.Mvc.ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
var viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}

