21

我正在尝试使用这个问题的公认答案。

看来这正是我正在寻找的,但我有一个问题。我不知道该怎么称呼它。这是我到目前为止所拥有的:

首先,我从我提到的解决方案中复制代码:

public string ToHtml(string viewToRender, ViewDataDictionary viewData, ControllerContext controllerContext)
{
    var result = ViewEngines.Engines.FindView(controllerContext, viewToRender, null);

    StringWriter output;
    using (output = new StringWriter())
    {
        var viewContext = new ViewContext(controllerContext, result.View, viewData, controllerContext.Controller.TempData, output);
        result.View.Render(viewContext, output);
        result.ViewEngine.ReleaseView(controllerContext, result.View);
    }

    return output.ToString();
}

这就是我所拥有的:

string viewToRender = "...";
int Data1 = ...;
int Data2 = ...;

System.Web.Mvc.ViewDataDictionary viewData = new System.Web.Mvc.ViewDataDictionary();
viewData.Add("Data1",Data1);
viewData.Add("Data2",Data2);

string html = ToHtml(viewToRender, viewData, ?????)//Here is my problem.

我应该在 controllerContext 参数中传递什么?

4

3 回答 3

42

而不是继承Controller,这意味着您必须记住每次都实现它,或者从 a 继承CustomControllerBase,这意味着您必须记住每次都继承 - 只需创建一个扩展方法:

public static class ControllerExtensions
{
    public static string RenderView(this Controller controller, string viewName, object model)
    {
        return RenderView(controller, viewName, new ViewDataDictionary(model));
    }

    public static string RenderView(this Controller controller, string viewName, ViewDataDictionary viewData)
    {
        var controllerContext = controller.ControllerContext;

        var viewResult = ViewEngines.Engines.FindView(controllerContext, viewName, null);

        StringWriter stringWriter;

        using (stringWriter = new StringWriter())
        {
            var viewContext = new ViewContext(
                controllerContext,
                viewResult.View,
                viewData,
                controllerContext.Controller.TempData,
                stringWriter);

            viewResult.View.Render(viewContext, stringWriter);
            viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
        }

        return stringWriter.ToString();
    }
}

然后在你的内部Controller你可以这样调用:

this.RenderView("ViewName", model);
于 2013-10-15T10:17:16.640 回答
11

您可以创建一个明显扩展控制器的基本控制器并在基本控制器中使用上述功能,并且扩展此基本控制器的其他控制器将能够使用它。但是必须将 ControllerContext 用作

Request.RequestContext

因此你的 BaseController 会像

public class BaseController: Controller
{
//your function here
}

你的 ToHtml() 函数将是

protected virtual string ToHtml(string viewToRender, ViewDataDictionary viewData )
{
   var controllerContext=Request.RequestContext;
   var result = ViewEngines.Engines.FindView(controllerContext, viewToRender, null);

   StringWriter output;
   using (output = new StringWriter())
   {
      var viewContext = new ViewContext(controllerContext, result.View, viewData, controllerContext.Controller.TempData, output);
      result.View.Render(viewContext, output);
      result.ViewEngine.ReleaseView(controllerContext, result.View);
   }

   return output.ToString();
}

以及使用基本控制器

public class MyController: BaseController
{
//ToHtml(...);
}
于 2013-08-27T09:23:44.430 回答
4

这几乎是dav_i 帖子的副本,除了您有一个具有强类型化功能的模型以及生成部分视图的能力:

而不是继承Controller,这意味着您必须记住每次都实现它,或者从 a 继承CustomControllerBase,这意味着您必须记住每次都继承 - 只需创建一个扩展方法:

public static class ControllerExtensions
{
    public static string RenderView<TModel>(this Controller controller, string viewName, TModel model, bool partial = false)
    {
        var controllerContext = controller.ControllerContext;
        controllerContext.Controller.ViewData.Model = model;

        // To be or not to be (partial)
        var viewResult = partial ? ViewEngines.Engines.FindPartialView(controllerContext, viewName) : ViewEngines.Engines.FindView(controllerContext, viewName, null);

        StringWriter stringWriter;

        using (stringWriter = new StringWriter())
        {
            var viewContext = new ViewContext(
                controllerContext,
                viewResult.View,
                controllerContext.Controller.ViewData,
                controllerContext.Controller.TempData,
                stringWriter);

            viewResult.View.Render(viewContext, stringWriter);
            viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
        }

        return stringWriter.ToString();
    }
}

然后在你的内部Controller你可以这样调用(以获得完整视图):

this.RenderView("ViewName", model);

这意味着您还将获得 doctype 和 HTML 元素等。对于部分视图使用:

this.RenderView("ViewName", model, true);
于 2017-05-03T08:56:42.363 回答