找到给定路径对应的Blazor组件class
Find the Blazor component class corresponding to a given path
在 Blazor 服务器应用程序中,如何找到与给定路径(在 string
中)匹配的剃刀组件的 class(return 作为 Type
) ,说 "/controller/action"
)?我不想导航到实际页面;我只想找到相应的 class 并用它执行一些反射类型的东西。在我看来,Blazor 处理路由的方式与 MVC 的方式非常不同,我找不到任何有用的文档。
您可以使用反射来查找具有 RouteAttribute
属性的所有组件。 @page
指令被转换为 RouteAttribute
.
var pageTypeList = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetCustomAttribute(typeof(Microsoft.AspNetCore.Components.RouteAttribute)) != null);
仔细研究了agua from mars提供的源码后,想到了以下解决方案。第一步是获取由 Blazor 框架创建的 Router
对象,我通过在我的 App.razor
:
中使用 CascadingValue
来实现
<Router AppAssembly="@typeof(Program).Assembly" @ref="router">
<Found Context="routeData">
<CascadingValue Value="@router">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
...
</RouteView>
</CascadingValue>
</Found>
<NotFound>
...
</NotFound>
</Router>
@code {
private Router router;
}
所以现在在我的应用程序的任何页面中,我都可以使用 CascadingParameterAttribute
获取 Router
对象。接下来是反射(因为这里涉及的很多东西都定义为internal
):
public Type Find(Router router, string path) {
var assm = typeof(Router).Assembly;
var routes = typeof(Router).GetProperty("Routes", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(router);
var type = assm.GetTypes().FirstOrDefault(t => t.Name == "RouteContext");
var context = Activator.CreateInstance(type, new[] { path });
routes.GetType().GetMethod("Route", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(routes, new[] { context });
return type.GetProperty("Handler").GetValue(context) as Type;
}
而这个功能正是我所需要的。
注意:这更多是对已接受答案的评论,但我没有代表。
TL;DR - RouteData.PageType
将解决大多数简单用例的原始问题。如果您遇到与此不一致的结果 - 请使用 Mu-Tsun Tsai 答案的更新版本,如下所述。
我也遇到过类似的情况。我用了。当我这样做时,我发现 RouteData.PageType
提供了一个相似的值——这可能适用于大多数简单的情况。
不幸的是,我的案例需要 PageType 来确定导航是否有效 - 如果无效,则导航到默认页面。我怀疑嵌套导航导致了竞争条件,RouteData.PageType
没有发现 - 由于某种原因,它返回了引用页面的 PageType,而不是在有限和不一致的情况下目标页面的 PageType .
我最终回到了 Mu-Tsun Tsai 的答案,因为它能够根据目标页面确定类型。
注意事项
- 反射的使用已经打破了原来的答案。需要进行更新才能使用
routes.GetType().GetMethod("Route", BindingFlags.Instance | BindingFlags.Public).Invoke(routes, new[] { context });
- 路径必须是相对路径,否则将无法检测页面类型
在 Blazor 服务器应用程序中,如何找到与给定路径(在 string
中)匹配的剃刀组件的 class(return 作为 Type
) ,说 "/controller/action"
)?我不想导航到实际页面;我只想找到相应的 class 并用它执行一些反射类型的东西。在我看来,Blazor 处理路由的方式与 MVC 的方式非常不同,我找不到任何有用的文档。
您可以使用反射来查找具有 RouteAttribute
属性的所有组件。 @page
指令被转换为 RouteAttribute
.
var pageTypeList = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetCustomAttribute(typeof(Microsoft.AspNetCore.Components.RouteAttribute)) != null);
仔细研究了agua from mars提供的源码后,想到了以下解决方案。第一步是获取由 Blazor 框架创建的 Router
对象,我通过在我的 App.razor
:
CascadingValue
来实现
<Router AppAssembly="@typeof(Program).Assembly" @ref="router">
<Found Context="routeData">
<CascadingValue Value="@router">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
...
</RouteView>
</CascadingValue>
</Found>
<NotFound>
...
</NotFound>
</Router>
@code {
private Router router;
}
所以现在在我的应用程序的任何页面中,我都可以使用 CascadingParameterAttribute
获取 Router
对象。接下来是反射(因为这里涉及的很多东西都定义为internal
):
public Type Find(Router router, string path) {
var assm = typeof(Router).Assembly;
var routes = typeof(Router).GetProperty("Routes", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(router);
var type = assm.GetTypes().FirstOrDefault(t => t.Name == "RouteContext");
var context = Activator.CreateInstance(type, new[] { path });
routes.GetType().GetMethod("Route", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(routes, new[] { context });
return type.GetProperty("Handler").GetValue(context) as Type;
}
而这个功能正是我所需要的。
注意:这更多是对已接受答案的评论,但我没有代表。
TL;DR - RouteData.PageType
将解决大多数简单用例的原始问题。如果您遇到与此不一致的结果 - 请使用 Mu-Tsun Tsai 答案的更新版本,如下所述。
我也遇到过类似的情况。我用了RouteData.PageType
提供了一个相似的值——这可能适用于大多数简单的情况。
不幸的是,我的案例需要 PageType 来确定导航是否有效 - 如果无效,则导航到默认页面。我怀疑嵌套导航导致了竞争条件,RouteData.PageType
没有发现 - 由于某种原因,它返回了引用页面的 PageType,而不是在有限和不一致的情况下目标页面的 PageType .
我最终回到了 Mu-Tsun Tsai 的答案,因为它能够根据目标页面确定类型。
注意事项
- 反射的使用已经打破了原来的答案。需要进行更新才能使用
routes.GetType().GetMethod("Route", BindingFlags.Instance | BindingFlags.Public).Invoke(routes, new[] { context });
- 路径必须是相对路径,否则将无法检测页面类型