如何搜索 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
当您尝试从控制器呈现此视图组件时,将在以下位置查找视图:
"/Views/{ControllerName}/Components/ExternalSystems/{ViewName}.cshtml" 。
因此,如果您使用 HomeController 并在 View(viewName,viewModel) 调用中将 viewName 指定为 ExternalSystemsView,您的路径将变为
/Views/Home/Components/ExternalSystems/ExternalSystemsView.cshtml 。这允许每个控制器为视图组件返回的视图拥有自己的自定义视图。
如果 ExternalSystemsView.cshtml 不在上面的路径中,它将在 /Views/Shared/Components/ExternalSystems/ExternalSystemsView.cshtml 中查找
您可以通过在调用 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
我无法将 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
当您尝试从控制器呈现此视图组件时,将在以下位置查找视图:
"/Views/{ControllerName}/Components/ExternalSystems/{ViewName}.cshtml" 。
因此,如果您使用 HomeController 并在 View(viewName,viewModel) 调用中将 viewName 指定为 ExternalSystemsView,您的路径将变为 /Views/Home/Components/ExternalSystems/ExternalSystemsView.cshtml 。这允许每个控制器为视图组件返回的视图拥有自己的自定义视图。如果 ExternalSystemsView.cshtml 不在上面的路径中,它将在 /Views/Shared/Components/ExternalSystems/ExternalSystemsView.cshtml 中查找
您可以通过在调用 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