2

我需要生成特定于我想制作的Customer对象的 html(用于电子邮件的正文),该对象获取对象并呈现适当的文本。
ViewCustomer

有没有办法调用视图并获取渲染输出而不将其与控制器操作相关联?

理想情况下,在pseydocode中我会做这样的事情

customer = new Customer();
view = new GetCustomerEmailBodyView(customer);
string htmlBody = view.SomeFunctionToRenderViewAndGetOutput()

我找到了一种解决方案来获取此处Html的视图的 HTML,该视图具有返回 StringResult(从 ViewResult 继承)而不是公开属性的 ActionResult 的操作。
但是,我仍然需要进行自定义操作来调用它,而且我不喜欢它依赖于 ControllerContext 从而难以测试它的事实。

我对 MVC 负责人的要求是什么?对于这种情况,我的代码应该如何构建?

4

2 回答 2

3

来自这里的原始代码

protected string RenderPartialViewToString(string viewName, object model) {
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");
    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();
    }
}
于 2010-10-29T22:25:16.773 回答
1

您是说您希望某些程序能够在根本不处于控制器上下文中的情况下利用视图,还是您是说您希望能够从控制器内将视图呈现为字符串,而无需调用其他程序控制器?

对于前者,我帮不上什么忙,但对于后者,我们在与所有其他控制器一起继承的基本控制器类型中有这个方法:

    /// <summary>
    /// Generates a string based on the given PartialViewResult.
    /// </summary>
    /// <param name="partialViewResult"></param>
    /// <returns></returns>
    protected internal string RenderPartialViewToString(ViewResultBase partialViewResult)
    {
        Require.ThatArgument(partialViewResult != null);
        var context = ControllerContext;
        Require.That(context != null);
        using (var sw = new StringWriter())
        {
            if (string.IsNullOrEmpty(partialViewResult.ViewName))
            {
                partialViewResult.ViewName = context.RouteData.GetRequiredString("action");
            }
            ViewEngineResult result;
            if (partialViewResult.View == null)
            {
                result = partialViewResult.ViewEngineCollection.FindPartialView(context, partialViewResult.ViewName);
                Require.That(result.View != null,
                             () => new InvalidOperationException(
                                       "Unable to find view. Searched in: " +
                                       string.Join(",", result.SearchedLocations)));
                partialViewResult.View = result.View;
            }

            var view = partialViewResult.View;
            var viewContext = new ViewContext(context, view, partialViewResult.ViewData,
                                              partialViewResult.TempData, sw);
            view.Render(viewContext, sw);
            return sw.ToString();
        }
    }

用法:

public ActionResult MyAction(...) 
{
    var myModel = GetMyModel(...);
    string viewString = RenderPartialViewToString(PartialView("MyView", myModel));
    // do something with the string
    return someAction;
}

我们实际上在基于事件的 AJAX 模型中使用它,其中我们的大多数操作实际上只是返回 AJAX 编码的客户端事件列表,其中一些客户端事件可能是使用字符串更新特定 DOM 元素通过渲染这个局部视图产生。

于 2010-10-29T22:21:08.990 回答