繁体   English   中英

找到给定路径对应的 Blazor 组件类

[英]Find the Blazor component class corresponding to a given path

在 Blazor 服务器应用程序中,如何找到与给定路径(在string ,例如"/controller/action" )匹配的 razor 组件的类(返回为Type )? 我不想导航到实际页面; 我只想找到相应的类并用它执行一些反射类型的东西。 在我看来,Blazor 处理路由的方式与 MVC 的非常不同,我找不到任何有帮助的文档。

您可以使用反射来查找具有RouteAttribute属性的所有组件。 @page指令被转换为RouteAttribute

var pageTypeList = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetCustomAttribute(typeof(Microsoft.AspNetCore.Components.RouteAttribute)) != null);

注意:这更多是对已接受答案的评论,但我没有代表。

TL;DR - RouteData.PageType将解决大多数简单用例的原始问题。 如果您遇到与此不一致的结果 - 使用 Mu-Tsun Tsai 答案的更新版本,如下所述。

我有一个类似的情况导致我来到这里。 我用了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 });
  • 路径需要是相对的,否则它不会检测页面类型

仔细研究了来自mars的agua提供的源码,想出了如下解决方案。 第一步是获取由 Blazor 框架创建的Router对象,我通过在App.razor使用CascadingValueApp.razor

<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;
}

而这个功能正是我所需要的。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM