我需要生成特定于Customer
对象的html(用于电子邮件正文)
我想过制作View
获取Customer
对象并呈现相应的文字。
有没有办法调用视图并获取渲染输出而不将其与控制器操作相关联?
理想情况下,在pseydocode中我会做这样的事情
customer = new Customer();
view = new GetCustomerEmailBodyView(customer);
string htmlBody = view.SomeFunctionToRenderViewAndGetOutput()
我找到了一个解决方案来获取视图的here的HTML,该视图的动作返回StringResult(继承自ViewResult)而不是ActionResult,它暴露了Html
属性。
但是我仍然需要自定义操作来调用它,我不喜欢它依赖于ControllerContext使得很难测试它的事实。
我要求对抗MVC校长吗?我应该如何为这种情况构建代码?
答案 0 :(得分:3)
来自here的原始代码
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();
}
}
答案 1 :(得分:1)
你是说你希望某个程序能够利用View而根本不在控制器环境中,或者你是说你希望能够在控制器内将视图渲染成字符串,而不是打电话给其他控制器?
对于前者,我不能提供太多帮助,但对于后者,我们在基本控制器类型中使用此方法,我们将继承所有其他控制器:
/// <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元素通过渲染此局部视图生成字符串。