我想输出两个不同的视图(一个作为将作为电子邮件发送的字符串),另一个显示给用户的页面 .
这是否可以在ASP.NET MVC beta中使用?
我尝试过多个例子:
1. RenderPartial to String in ASP.NET MVC Beta
如果我使用此示例,则会收到“在HTTP标头发送后无法重定向” .
2. MVC Framework: Capturing the output of a view
如果我使用它,我似乎无法执行redirectToAction,因为它尝试渲染可能不存在的视图 . 如果我确实返回了视图,那么它完全搞砸了,看起来并不正确 .
有没有人对我遇到的这些问题有任何想法/解决方案,或者有更好的建议?
非常感谢!
以下是一个例子 . 我要做的是创建 GetViewForEmail method :
public ActionResult OrderResult(string ref)
{
//Get the order
Order order = OrderService.GetOrder(ref);
//The email helper would do the meat and veg by getting the view as a string
//Pass the control name (OrderResultEmail) and the model (order)
string emailView = GetViewForEmail("OrderResultEmail", order);
//Email the order out
EmailHelper(order, emailView);
return View("OrderResult", order);
}
Accepted answer from Tim Scott (changed and formatted a little by me):
public virtual string RenderViewToString(
ControllerContext controllerContext,
string viewPath,
string masterPath,
ViewDataDictionary viewData,
TempDataDictionary tempData)
{
Stream filter = null;
ViewPage viewPage = new ViewPage();
//Right, create our view
viewPage.ViewContext = new ViewContext(controllerContext, new WebFormView(viewPath, masterPath), viewData, tempData);
//Get the response context, flush it and get the response filter.
var response = viewPage.ViewContext.HttpContext.Response;
response.Flush();
var oldFilter = response.Filter;
try
{
//Put a new filter into the response
filter = new MemoryStream();
response.Filter = filter;
//Now render the view into the memorystream and flush the response
viewPage.ViewContext.View.Render(viewPage.ViewContext, viewPage.ViewContext.HttpContext.Response.Output);
response.Flush();
//Now read the rendered view.
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally
{
//Clean up.
if (filter != null)
{
filter.Dispose();
}
//Now replace the response filter
response.Filter = oldFilter;
}
}
Example usage
假设来自控制器的呼叫获取订单确认电子邮件,则传递Site.Master位置 .
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);
14 回答
我在另一个网站上看到了MVC 3和Razor的实现,它对我有用:
更多关于Razor render- MVC3 View Render to String
你是用这种方式得到字符串中的视图
我们以两种方式称这种方法
要么
这是我想出来的,它对我有用 . 我将以下方法添加到我的控制器基类中 . (您可以随时将这些静态方法设置为接受控制器作为参数的其他地方)
MVC2 .ascx style
Razor .cshtml style
编辑:添加了Razor代码 .
这个答案不在我的路上 . 这最初来自https://stackoverflow.com/a/2759898/2318354但是在这里我已经展示了将它与"Static"关键字一起使用以使其适用于所有控制器的方法 .
为此,你必须在类文件中生成
static
类 . (假设您的类文件名是Utils.cs)这个例子是For Razor .
Utils.cs
现在,您可以通过将“this”作为参数传递给Controller,在控制器文件中添加NameSpace,从控制器调用此类 .
根据@Sergey给出的建议,这个扩展方法也可以从cotroller调用,如下所示
我希望这对你使代码干净整洁有用 .
我发现了一个新的解决方案,可以将视图呈现为字符串,而不必混淆当前HttpContext的响应流(它不允许您更改响应的ContentType或其他 Headers ) .
基本上,您所做的就是为视图创建一个假的HttpContext来呈现自己:
这适用于ASP.NET MVC 1.0,以及ContentResult,JsonResult等 . (更改原始HttpResponse上的Headers不会抛出“服务器无法在发送HTTP标头后设置内容类型”异常) .
在ASP.NET MVC 2.0 RC中 Update: ,代码有所改变,因为我们必须传入用于将视图写入
ViewContext
的StringWriter
:这是我为ASP.NETCore RC2编写的一个类 . 我使用它,所以我可以使用Razor生成HTML电子邮件 .
我使用的是MVC 1.0 RTM,上述解决方案都不适用于我 . 但是这个做了:
要从一个更未知的问题重复,请看一下MvcIntegrationTestFramework .
它可以节省您编写自己的帮助程序以传输结果,并且已证明可以很好地工作 . 我假设这将是一个测试项目,作为奖励,一旦你有这个设置,你将拥有其他测试功能 . 主要麻烦可能是整理依赖链 .
小建议
对于强类型模型,只需将其添加到ViewData.Model属性,然后再传递给RenderViewToString . 例如
要在服务层中呈现字符串视图而不必传递ControllerContext,这里有一篇很好的Rick Strahl文章http://www.codemag.com/Article/1312081,它创建了一个通用控制器 . 代码摘要如下:
然后在Service类中呈现View:
这对我有用:
This article描述了如何在不同场景中将视图呈现为字符串:
MVC Controller调用另一个自己的ActionMethods
MVC Controller调用另一个MVC控制器的ActionMethod
WebAPI Controller调用MVC控制器的ActionMethod
解决方案/代码作为一个名为 ViewRenderer 的类提供 . 它是Rick Stahl的WestwindToolkit at GitHub的一部分 .
Usage (3. - WebAPI示例):
如果你想完全放弃MVC,从而避免所有的HttpContext混乱......
这里使用了很棒的开源Razor引擎:https://github.com/Antaris/RazorEngine
当我遇到上述方法的错误时,我找到了一种更好的方法来渲染剃刀视图页面,这个解决方案适用于Web表单环境和mvc环境 . 不需要控制器 .
下面是代码示例,在此示例中,我使用异步http处理程序模拟了mvc操作: