在控制器或其他地方渲染部分字符串

发布于 2024-10-29 06:18:08 字数 169 浏览 1 评论 0原文

所以基本上我有一个可以为我构建一个漂亮表格的局部视图。我想每周通过电子邮件将此表发送给我的用户。我不想再次复制模板,而是想将模型转发到控制器并以 String 形式接收相应生成的 HTML

是否可以在控制器中执行此操作,我觉得这应该是一个非常简单的过程。

So basically I have a partial view which can build a nice table for me. I would like to email this table out every week to my users. Instead of having to basically copy the template again, I would like to forward my model to the controller and receive the corresponding generated HTML as a String.

Is it possible to do this in a Controller, I feel it should be a pretty simple process.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空城仅有旧梦在 2024-11-05 06:18:08

将其放入帮助文件中:

public static string RenderViewToString(ControllerContext context, string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = context.RouteData.GetRequiredString("action");

            ViewDataDictionary viewData = new ViewDataDictionary(model);

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
                ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }

然后从控制器中您可以像这样调用它:

var order = orderService.GetOrder(id);

var orderPrint = MyHelper.RenderViewToString(this.ControllerContext, "_OrderView", order);

Put this into a Helper file:

public static string RenderViewToString(ControllerContext context, string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = context.RouteData.GetRequiredString("action");

            ViewDataDictionary viewData = new ViewDataDictionary(model);

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
                ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }

And then from the controller you can call it like this:

var order = orderService.GetOrder(id);

var orderPrint = MyHelper.RenderViewToString(this.ControllerContext, "_OrderView", order);
逐鹿 2024-11-05 06:18:08

如果您搜索将部分视图渲染为字符串,您还会遇到一些好的线索。这就是我为 ControllerBase 类提出以下扩展方法所做的事情:

public static string RenderPartialViewToString( this ControllerBase controller, string partialPath, ViewDataDictionary viewData = null )
{
    if( string.IsNullOrEmpty(partialPath) )
        partialPath = controller.ControllerContext.RouteData.GetRequiredString("action");

    using( StringWriter sw = new StringWriter() )
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath);

        ViewContext viewContext = new ViewContext(controller.ControllerContext,
            viewResult.View,
            ( viewData == null ) ? controller.ViewData : viewData,
            controller.TempData,
            sw);

        // copy retVal state items to the html helper 
        foreach( var item in viewContext.Controller.ViewData.ModelState )
        {
            if( !viewContext.ViewData.ModelState.Keys.Contains(item.Key) )
                viewContext.ViewData.ModelState.Add(item);
        }

        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}

从概念上讲,要遵循的过程涉及使用为您的应用程序定义的 ViewEngines 通过其名称查找部分视图。然后,您可以从该部分创建一个 ViewContext,并将各种模型状态属性复制到其中。

该代码分配一个可选的 ViewDataDictionary,您可以将其提供给 ViewContext。如果您不提供 ViewDataDictionary,它将获取为调用它的控制器定义的 ViewDataDictionary。

这意味着您可以直接在控制器中定义 ViewData 值(或 ViewBag 属性),然后调用扩展方法——这将在渲染时将这些 ViewData/ViewBag 属性应用于局部——或者您可以创建一个在操作方法中分离 ViewDataDictionary 对象并将其传递给扩展方法。第一个更快/更容易,但它“污染”了操作方法的 ViewData,而第二个需要更长的时间来设置,但可以让您将部分视图数据与操作方法的 ViewData 分开。

If you search for rendering partial views to strings you'll also come across some good leads. That's what I did to come up with the following extension method for the ControllerBase class:

public static string RenderPartialViewToString( this ControllerBase controller, string partialPath, ViewDataDictionary viewData = null )
{
    if( string.IsNullOrEmpty(partialPath) )
        partialPath = controller.ControllerContext.RouteData.GetRequiredString("action");

    using( StringWriter sw = new StringWriter() )
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath);

        ViewContext viewContext = new ViewContext(controller.ControllerContext,
            viewResult.View,
            ( viewData == null ) ? controller.ViewData : viewData,
            controller.TempData,
            sw);

        // copy retVal state items to the html helper 
        foreach( var item in viewContext.Controller.ViewData.ModelState )
        {
            if( !viewContext.ViewData.ModelState.Keys.Contains(item.Key) )
                viewContext.ViewData.ModelState.Add(item);
        }

        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}

Conceptually, the procedure to follow involves using the ViewEngines defined for your app to find a partial view by its name. You then create a ViewContext off of that partial, and copy the various model state properties over to it.

The code assigns an optional ViewDataDictionary that you can provide to the ViewContext. If you don't provide the ViewDataDictionary it grabs the ViewDataDictionary defined for the controller that it's being called against.

What this means is that you can either define ViewData values (or ViewBag properties) directly in your controller and then call the extension method -- which will apply those ViewData/ViewBag properties to the partial when it gets rendered -- or you can create a separate ViewDataDictionary object in your action method and pass it to the extension method. The first is quicker/easier, but it "pollutes" the ViewData for your action method, while the second takes a little longer to set up but lets you keep your partial view data separate from your action method's ViewData.

深海蓝天 2024-11-05 06:18:08

查看 MvcMailer 项目。再加上呈现表格的部分视图,您应该能够非常轻松地将电子邮件与表格放在一起。

Look into the MvcMailer project. Coupled with a partial view that renders your table, you should be able to pretty easily put together emails with your tables.

陌伤浅笑 2024-11-05 06:18:08

将视图渲染为字符串

我使用像上面这样简单的东西但我几乎总是为电子邮件创建单独的视图。主要是因为需要使用绝对链接并将CSS插入头部。

Render a view as a string

I use something simple like above but I almost always create separate views for the emails. Mainly due to the need to use absolute links and inserting the CSS into the head.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文