【问题标题】:Asp.Net Core render ViewComponent to variableAsp.Net Core 将 ViewComponent 渲染到变量
【发布时间】:2019-12-08 12:56:35
【问题描述】:

我正在尝试将ViewComponent 呈现为 ASP.NET Core 3.0(页面)中服务中的字符串。

我找到了两个部分解决我的问题的方法,但都适用于旧的 pre 3.0 版本,并且有一些我不知道如何解决的问题。

  • 第一个取自 GitHub Gist,但在设计时考虑到了控制器,并且 NullView 在 3.0 中被删除(并且很难找到任何关于它的参考)。
  • 第二个选项是here,但在第 42 行失败(未找到视图)。我相信这是由于 .net core 中所做的更改,其中视图现在已预编译,因此 razor 视图引擎无法找到它们。

我做了一些自己的实验,但无法让它发挥作用(我相信我面临与我发布的第二个解决方案相同的问题)。对于如何使其正常工作,我将不胜感激。我已将我的最佳尝试和最小项目添加到 GitHub,其中 Render 位于 Service 文件夹中,而 Index.cshtml.cs 中是对服务的调用。

谢谢!

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    原因

    1. NullView 现在是一个内部类。但这是一个非常简单的类,什么都不做。换句话说,只需将其从 src 复制并粘贴到您的源代码中。
    2. 您上面链接的教程用于呈现普通视图。但是,由于您尝试渲染视图组件而不是视图,因此您应该避免使用passing a view path directly。您应该改为传递 ViewComponent 类名(或 Type)。

      模型 = 等待 _viewRender.RenderToStringAsync( "/Components/Test/Default.cshtml", // 不要传递视图路径,因为我们渲染的不是视图文件而是视图组件 "Test", // 因为 `ViewComponent` 的名字是 Test new TestModel { StrToPrint = "从服务打印" });
    3. 根据official docs, 运行时在以下路径中搜索视图

      1. /Views/{控制器名称}/Components/{视图组件名称}/{视图名称}
      2. /Views/Shared/Components/{视图组件名称}/{视图名称}
      3. /Pages/Shared/Components/{查看组件名称}/{查看名称}

      但是,您的Test ViewComponent 位于Pages/Components/Test/Default.cshtmlRazor 默认找不到。配置自定义视图位置,或将其移动到标准位置,以便 Razor 可以找到视图文件。

    4. 最后,rendering a ViewComponent as a page 似乎有点矫枉过正。我建议你应该使用IViewComponentHelperViewComponent 呈现为IHtmlContent,这样我就可以写信给StringWriter

      public class MyViewComponentContext 
      {
          public HttpContext HttpContext { get; set; }
          public ActionContext ActionContext { get; set; }
          public ViewDataDictionary ViewData { get; set; }
          public ITempDataDictionary TempData { get; set; }
      }
      private async Task<string> Render( MyViewComponentContext myViewComponentContext,string viewComponentName,object args) {
          using (var writer = new StringWriter())
          { 
              var helper = this.GetViewComponentHelper(myViewComponentContext, writer);
              var result = await helper.InvokeAsync(viewComponentName, args);  // get an IHtmlContent
              result.WriteTo(writer, HtmlEncoder.Default);
              await writer.FlushAsync();
              return writer.ToString();
          }
      }
      

    演示

    如果我按照上面描述的方式解决了问题,那么在运行您的项目时,我会得到正确的结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多