简体   繁体   English

Asp.Net Core 将 ViewComponent 渲染为变量

[英]Asp.Net Core render ViewComponent to variable

I am trying to render ViewComponent to a string in a service in ASP.NET Core 3.0 (Pages).我正在尝试将ViewComponent呈现为 ASP.NET Core 3.0(页面)中的服务中的字符串。

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.我为我的问题找到了两个部分解决方案,但都针对 3.0 之前的旧版本,并且存在一些我不知道如何解决的问题。

  • 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).第一个取自GitHub Gist ,但在设计时考虑到了控制器,并且NullView在 3.0 中被删除(并且很难找到任何参考资料)。
  • The second option is here , but fails one line 42 (no view is found).第二个选项是here ,但在第 42 行失败(未找到视图)。 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.我相信这是由于 .net core 中的更改造成的,其中视图现在是预编译的,因此 razor 视图引擎无法找到它们。

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.我已将我的最佳尝试和最小项目添加到GitHub ,其中 Render 在 Service 文件夹中,在 Index.cshtml.cs 中是对服务的调用。

Thanks!谢谢!

The Reasons原因

  1. NullView is an internal class now. NullView现在是一个内部类。 But that's a very simple class that does nothing.但这是一个非常简单的类,什么也不做。 In other words, simply copy & paste it from the src into your source code.换句话说,只需将它从 src 复制并粘贴到您的源代码中。
  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.您应该改为传递一个ViewComponent 类名称(或类型)。

    \nModel = await _viewRender.RenderToStringAsync(模型 = 等待 _viewRender.RenderToStringAsync(\n    \n   
       
       
        
        \n    
       
       
        
        
          "/Components/Test/Default.cshtml", 
         
        
        
          "/Components/Test/Default.cshtml", 
        
       
       
        
        \n   
       
       // don't pass a view path since we're not rendering a view file but a view component // 不要传递视图路径,因为我们渲染的不是视图文件而是视图组件\n    "Test", // because the `ViewComponent` Name is Test "Test", // 因为 `ViewComponent` 的名字是 Test\n    new TestModel { StrToPrint = "Print From Service" }); new TestModel { StrToPrint = "从服务打印" });\n
  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} /Views/{控制器名称}/Components/{视图组件名称}/{视图名称}
    2. /Views/Shared/Components/{View Component Name}/{View Name} /Views/Shared/Components/{视图组件名称}/{视图名称}
    3. /Pages/Shared/Components/{View Component Name}/{View Name} /Pages/Shared/Components/{查看组件名称}/{查看名称}

    However, your Test ViewComponent resides in Pages/Components/Test/Default.cshtml , which can not be found by Razor by default .但是,您的Test ViewComponent 驻留在Pages/Components/Test/Default.cshtml默认情况下 Razor 无法找到它 Either configure a custom View Location, or move it to the standard location such that Razor can find the view files.配置自定义视图位置,或将其移动到标准位置,以便 Razor 可以找到视图文件。

  4. Finally, rendering a ViewComponent as a page seems a bit of overkill.最后, 将 ViewComponent 渲染为页面似乎有点矫枉过正。 I would suggest you should use IViewComponentHelper to render the ViewComponent as an IHtmlContent such that I can write to a StringWriter :我建议你应该使用IViewComponentHelper呈现ViewComponent作为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(); } }

Demo演示

If I fix the issues as I described above, when running your project I'll get the correct result:如果我解决了上面描述的问题,那么在运行您的项目时,我会得到正确的结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET Core ViewComponent调用:InvalidCastException - ASP.NET Core ViewComponent Invocation: InvalidCastException 如何在ViewComponent Asp.Net Core中获取当前登录用户 - How get current login user in ViewComponent Asp.Net Core 在 ASP.NET CORE MVC 中使用 CRUD 操作的 ViewComponent - ViewComponent With CRUD Operations in ASP.NET CORE MVC 无法识别 ASP.NET Core ViewComponent 的 Invoke() 方法调用 - ASP.NET Core ViewComponent's Invoke() method call not recognized 如何在Asp.net核心中的ViewComponent之间共享ViewData - How share ViewData between ViewComponent in Asp.net core 使用 Razor Pages 在 Asp.NET Core 2.2 中找不到 ViewComponent - ViewComponent not found in Asp.NET Core 2.2 using Razor Pages 如何将 ModelExpression 绑定到 ASP.NET Core 中的 ViewComponent? - How to bind a ModelExpression to a ViewComponent in ASP.NET Core? ASP.NET Core使用ViewComponent跟踪侧栏的活动页面 - ASP.NET Core track active Page for sidebar using ViewComponent ViewComponent 必须有一个名为“InvokeAsync”或“Invoke”的公共方法 - ASP.NET CORE (.NET 6) - ViewComponent must have one public method named 'InvokeAsync' or 'Invoke' - ASP.NET CORE (.NET 6) 在 ASP.NET 中搜索 ViewComponent 的路径 - Searching paths for ViewComponent in ASP.NET
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM