【问题标题】:ASP.NET Core Render a View with Partial Views inside to StringASP.NET Core 将带有部分视图的视图渲染为字符串
【发布时间】:2021-07-19 07:31:10
【问题描述】:

我正在努力渲染一个在视图内部有部分的视图。

视图确实被渲染为字符串,但视图内部的部分根本没有被渲染。

这是我对字符串实用程序代码的看法:

public static class EmailUtility
    {
        public static async Task<string> RenderPartialViewToString(this Controller controller, string viewName, object model)
        {
            controller.ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                IViewEngine viewEngine = controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
                ViewEngineResult viewEngineResult = GetViewEngineResult(controller, viewName, false, viewEngine);

                if (!viewEngineResult.Success)
                {
                    return $"A view with the name {viewName} could not be found";
                }

                ViewContext viewContext = new ViewContext(
                    controller.ControllerContext,
                    viewEngineResult.View,
                    controller.ViewData,
                    controller.TempData,
                    sw,
                    new HtmlHelperOptions()
                );

                await viewEngineResult.View.RenderAsync(viewContext);

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

        private static ViewEngineResult GetViewEngineResult(Controller controller, string viewName, bool isPartial, IViewEngine viewEngine)
        {
            if (viewName.StartsWith("~/"))
            {
                var hostingEnv = controller.HttpContext.RequestServices.GetService(typeof(IWebHostEnvironment)) as IWebHostEnvironment;
                return viewEngine.GetView(hostingEnv.WebRootPath, viewName, !isPartial);
            }
            else
            {
                return viewEngine.FindView(controller.ControllerContext, viewName, !isPartial);
            }
        }
    }

这就是我在Controller中调用方法的方式:

string html = await this.RenderPartialViewToString("~/Views/Shared/MailerLayoutMaster.cshtml", model);

这是 MailerLayoutMaster.cshtml:

@model Model

@{ 
    Layout = null;
}

<!DOCTYPE html>
<html>
    <head>

    </head>
    <body>
        @{ 
            switch ((int) Model.EmailType)
            {
                case (int) EmailTypeEnum.ContactUsSubmitted:
                    await Html.PartialAsync("../Shared/MailTemplates/EmailPartial.cshtml", Model);
                    break;
                default:
                    
                    break;
            }
        }
    </body>
</html>

这是我的 EmailPartial.cshtml

@model Model

<table>
    <tr>
        <td>Name: <b>@Model.Name</b></td>
    </tr>
    <tr>
        <td>Surname: <b>@Model.Surname</b></td>
    </tr>
    <tr>
        <td>Email: <b>@Model.Email</b></td>
    </tr>
    <tr>
        <td>Number: <b>@Model.Phone</b></td>
    </tr>
</table>

这是我得到的字符串:

<!DOCTYPE html>
<html lang="en-ZA">
    <head>

    </head>
    <body>

    </body>
</html>

如果有帮助,这是我的项目结构:

Controllers
    Controller.cs
Utilities
    ViewToStringUtil.cs
Views
    Shared
        MailTemplates
            EmailPartial.cshtml
        MailerLayoutMaster.cshtml

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core


    【解决方案1】:

    我认为这是因为您没有以正确的方式调用局部视图。无需使用 .cshtml 扩展名来调用局部视图。更新您的代码,如下所示:-

    string html = await this.RenderPartialViewToString("~/Views/Shared/MailerLayoutMaster", model);
    

     switch ((int) Model.EmailType)
                {
                    case (int) EmailTypeEnum.ContactUsSubmitted:
                        await Html.PartialAsync("../Shared/MailTemplates/EmailPartial", Model);
                        break;
    
    //clarify code
    

    此外,您可以根据文件夹结构尝试不使用完整路径,只使用部分视图名称。您可以检查它是否有效。

    string html = await this.RenderPartialViewToString("PartialViewName", model);
    

    【讨论】:

    • 我尝试了您的答案,但没有找到视图。我认为的问题(来自大量测试和调试)是部分视图没有被渲染(html 字符串只有主布局 html 内容)。您也许知道为什么部分没有在主视图中呈现?
    【解决方案2】:

    解决方案非常简单。

    之前我只需要@

    await Html.PartialAsync("../Shared/MailTemplates/EmailPartial.cshtml", Model);
    

    应该是:

    @await Html.PartialAsync("../Shared/MailTemplates/EmailPartial.cshtml", Model);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多