如何搜索 Razor 页面视图组件路径?我无法让它们工作,.NET Core 试图包含不相关的模型

How are Razor Page View Component paths searched? I fail to get them working, .NET Core tries to include irrelevant model

我无法将 ViewComponent 包含在页面中。

我有一个文件夹结构: - Pages - Components - ExternalSystems - Default.cshtml - Views - Shared - Components - ExternalSystems - Default.cshtml

Class 文件

public class Default : ViewComponent
{
    private readonly Models.PermissionRegisterContext _context;

    public Default(Models.PermissionRegisterContext context)
    {
        _context = context;
    }


    public async Task<IViewComponentResult> InvokeAsync()
    {
        var externalSystems = await _context.ExternalSystem.ToListAsync();

        return View("Default", externalSystems);
    }
}

Pages/Index.cshtml 中,我尝试通过反复试验来包含此组件(毕竟我正在学习这些东西): @await Component.InvokeAsync("ExternalSystems"); @await Component.InvokeAsync("/Pages/Components/ExternalSystems"); @await Component.InvokeAsync("/Pages/Components/ExternalSystems/Default"); @await Component.InvokeAsync("/Pages/Components/ExternalSystems/Default.cshtml"); @await Component.InvokeAsync("/Views/Shared/ExternalSystems");

我希望异常会像 @Html.Partial:

一样显示搜索过的地方

InvalidOperationException: The partial view 'none' was not found. The following locations were searched: /Pages/none.cshtml /Views/Shared/none.cshtml

然而,每次调用 @await Component.InvokeAsync 它都会抛出这个异常:

InvalidOperationException: Could not find an 'Invoke' or 'InvokeAsync' method for the view component '.Pages.Identities.IndexModel'.

首先,它没有显示我搜索的路径。第二,等什么?你为什么要告诉我一些关于 Pages.Identities 的事情?是的,我有那个模型,但在我试图包含的 Pages/Index.cshtml 或视图组件中都没有引用它。

有人可以为我提供指导以确定:如何搜索视图组件路径?对于 Razor Pages,它是 not documented, only in 3rd party site。 不管怎样,它对我来说不是那样工作——调试步骤是什么?控制台调试没有显示任何有用信息。

网络 2.0.7

假设您创建了一个视图组件,如下所示:

public class ExternalSystems : ViewComponent 
{  

    public ExternalSystems()
    {
      //constructor can have dependencies injected. 
    }     

    public IViewComponentResult Invoke() 
    {
       //View is a helper method available in classes inherited
       //from ViewComponent that returns an instance of 
       //ViewViewComponentResult. It has multiple overloads as described 
       //later.
       return View(viewName,viewModel);           
    }
}

视图方法有多个重写:

  View() - use default view for view component without any viewmodel
  View(viewModel) - use default view for view  component with specified viewmodel
  View(viewName) - use specified view for view component without any viewmodel
  View(viewName,viewModel) - use specified view for view component with specified viewmodel

当您尝试从控制器呈现此视图组件时,将在以下位置查找视图:

  1. "/Views/{ControllerName}/Components/ExternalSystems/{ViewName}.cshtml" 。
    因此,如果您使用 HomeController 并在 View(viewName,viewModel) 调用中将 viewName 指定为 ExternalSystemsView,您的路径将变为 /Views/Home/Components/ExternalSystems/ExternalSystemsView.cshtml 。这允许每个控制器为视图组件返回的视图拥有自己的自定义视图。

  2. 如果 ExternalSystemsView.cshtml 不在上面的路径中,它将在 /Views/Shared/Components/ExternalSystems/ExternalSystemsView.cshtml 中查找

  3. 您可以通过在调用 View(viewName,viewModel) 时传递完整的视图路径来覆盖查找位置 - View("Views/Shared/Components/Common/YourView.cshtml")来自 ViewComponent 的 Invoke 方法。

    注意:如果您不指定视图名称,则默认为 Default.cshtml,这与用于控制器的 Index.html 不同

对于您的情况,@await Component.InvokeAsync("ExternalSystems") 是正确的调用,因为它期望将视图组件名称作为参数。 ViewName 将从您在 ViewComponent 的 Invoke 方法中作为 viewName 参数值传递给 View(viewName,viewModel) 调用的内容中选取,如果未指定视图名称,则默认为 Default.cshtml。

好吧,我的错误是我没有看到我用 [ViewComponent] 装饰了 ...Pages.Identities.IndexModel。这是无意的,只是试图通过反复试验使 ViewComponents 工作,并没有看到这个错误。

基本上 dotnet 发现的类型没有 Invoke/InvokeAsync 函数,因此卡在那个异常上。

我验证了在提供 "HelloWorld" 作为视图名称时搜索了这些路径:

  • /Pages/Components/HelloWorld/HelloWorld.cshtml
  • /Views/Shared/Components/HelloWorld/HelloWorld.cshtml