Asp.Net Core将ViewComponent渲染为变量 [英] Asp.Net Core render ViewComponent to variable

查看:78
本文介绍了Asp.Net Core将ViewComponent渲染为变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

  • 第一个摘录自

    I am trying to render ViewComponent to a string in a service in ASP.NET Core 3.0 (Pages).

    I found two partial solutions to my problem, but both are for older pre 3.0 version and have some issues that I do not know how to resolve.

    • First one is taken from GitHub Gist, but designed with controllers in mind and NullView was removed 3.0 (and is really hard to find any reference on it).
    • The second option is here, but fails one line 42 (no view is found). I believe that this is due to the changes made in .net core, where the views are now precompiled and the razor view engine therefore cannot find them.

    I did some of my own experimenting, but could not get it working (I believe I am facing the same issue as the second solution I posted). I would appreciate any help regarding this matter on how to get it working. I've added my best attempt and a minimum project to GitHub, where Render is in the Service folder and in the Index.cshtml.cs is the call to the service.

    Thanks!

    解决方案

    The Reasons

    1. NullView is an internal class now. But that's a very simple class that does nothing. In other words, simply copy & paste it from the src into your source code.
    2. The tutorials you linked above is used to render a plain view. However, since you're trying to render a view component instead of a view, you should avoid passing a view path directly. You should pass a ViewComponent Class Name (or Type) instead.

      Model = await _viewRender.RenderToStringAsync(
          "/Components/Test/Default.cshtml", // don't pass a view path since we're not rendering a view file but a view component
          "Test",                            // because the `ViewComponent` Name is Test
          new TestModel { StrToPrint = "Print From Service" });
      

    3. According to the official docs, The runtime searches for the view in the following paths:

      1. /Views/{Controller Name}/Components/{View Component Name}/{View Name}
      2. /Views/Shared/Components/{View Component Name}/{View Name}
      3. /Pages/Shared/Components/{View Component Name}/{View Name}

      However, your Test ViewComponent resides in Pages/Components/Test/Default.cshtml, which can not be found by Razor by default. Either configure a custom View Location, or move it to the standard location such that Razor can find the view files.

    4. Finally, rendering a ViewComponent as a page seems a bit of overkill. I would suggest you should use IViewComponentHelper to render the ViewComponent as an IHtmlContent such that I can write to a 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();
          }
      }
      

    Demo

    If I fix the issues as I described above, when running your project I'll get the correct result:

    这篇关于Asp.Net Core将ViewComponent渲染为变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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