如何将部分视图渲染为字符串

Dav*_*Dev 47 asp.net-mvc partial-views

我有以下代码:

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

我想修改它以便我可以

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 }
    };
}
Run Code Online (Sandbox Code Playgroud)

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

请注意,我在发布解决方案之前编辑了问题.

Ted*_*erg 49

我为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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它允许我执行以下操作:

var html = PartialView("SomeView").RenderToString();
Run Code Online (Sandbox Code Playgroud)

此外,此方法持久保存视图的任何Model,ViewBag和其他视图数据.


Dav*_*Dev 25

这是一个有效的答案的略微修改版本:

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();
}
Run Code Online (Sandbox Code Playgroud)

用法:

string ret = RenderPartialToString("~/Views/MyController/MyPartial.ascx", model);
Run Code Online (Sandbox Code Playgroud)

  • 这对我很有用.但是,如果我向部分视图添加RenderPartial,我将传递给此方法,我开始在RenderControl调用上获得异常:"Value不能为null.参数名称:view" (5认同)
  • 没有为我工作,我使用剃刀视图引擎,似乎这适用于ascx用户控件而不是部分cshtml视图.我在这里发布了我自己的剃须刀版本:http://stackoverflow.com/questions/5532345/mvc-render-to-string-in-the-controller-or-else-were/8677839#comment10788063_8677839 (4认同)

Vde*_*dex 10

DaveDev的答案对我来说效果很好,但是当局部视图调用另一个部分时,我得到"值不能为空.参数名称:视图"

搜索我已经做了以下似乎运作良好的变体.

 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();
        }

    }
Run Code Online (Sandbox Code Playgroud)

用法:

String result = MVCHelpers.RenderPartialToString("PartialViewHere", Model, ControllerContext)
Run Code Online (Sandbox Code Playgroud)


Ole*_*syk 7

您可以创建将视图呈现为字符串的扩展.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在行动中使用它

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