如何将 ASP.NET MVC 视图呈现为字符串? [英] How to render an ASP.NET MVC view as a string?

查看:23
本文介绍了如何将 ASP.NET MVC 视图呈现为字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想输出两个不同的视图(一个作为将作为电子邮件发送的字符串),另一个是向用户显示的页面.

I want to output two different views (one as a string that will be sent as an email), and the other the page displayed to a user.

这在 ASP.NET MVC 测试版中可行吗?

Is this possible in ASP.NET MVC beta?

我尝试了多个示例:

1. ASP.NET MVC Beta 中的 RenderPartial 到字符串

如果我使用这个例子,我会收到无法在 HTTP 后重定向标头已发送.".

If I use this example, I receive the "Cannot redirect after HTTP headers have been sent.".

2. MVC 框架:捕获视图的输出

如果我使用它,我似乎无法执行redirectToAction,因为它尝试呈现可能不存在的视图.如果我确实返回视图,它完全搞砸了,看起来一点也不对.

If I use this, I seem to be unable to do a redirectToAction, as it tries to render a view that may not exist. If I do return the view, it is completely messed up and doesn't look right at all.

有没有人对我遇到的这些问题有任何想法/解决方案,或者有更好的建议?

Does anyone have any ideas/solutions to these issues i have, or have any suggestions for better ones?

非常感谢!

下面是一个例子.我想要做的是创建 GetViewForEmail 方法:

Below is an example. What I'm trying to do is create the 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);
}

接受 Tim Scott 的回答(由我稍微更改和格式化):

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

示例用法

假设控制器调用以获取订单确认电子邮件,传递 Site.Master 位置.

Assuming a call from the controller to get the order confirmation email, passing the Site.Master location.

string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);

推荐答案

这是我的想法,它对我有用.我将以下方法添加到我的控制器基类中.(你总是可以在其他地方创建这些静态方法,我认为接受控制器作为参数)

Here's what I came up with, and it's working for me. I added the following method(s) to my controller base class. (You can always make these static methods somewhere else that accept a controller as a parameter I suppose)

MVC2 .ascx 风格

protected string RenderViewToString<T>(string viewPath, T model) {
  ViewData.Model = model;
  using (var writer = new StringWriter()) {
    var view = new WebFormView(ControllerContext, viewPath);
    var vdd = new ViewDataDictionary<T>(model);
    var viewCxt = new ViewContext(ControllerContext, view, vdd,
                                new TempDataDictionary(), writer);
    viewCxt.View.Render(viewCxt, writer);
    return writer.ToString();
  }
}

Razor .cshtml 样式

public string RenderRazorViewToString(string viewName, object model)
{
  ViewData.Model = model;
  using (var sw = new StringWriter())
  {
    var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,
                                                             viewName);
    var viewContext = new ViewContext(ControllerContext, viewResult.View,
                                 ViewData, TempData, sw);
    viewResult.View.Render(viewContext, sw);
    viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
    return sw.GetStringBuilder().ToString();
  }
}

添加了 Razor 代码.

added Razor code.

这篇关于如何将 ASP.NET MVC 视图呈现为字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆