【问题标题】:In Blazor, how to retrieve all routable Razor component names in Pages directory?在 Blazor 中,如何检索 Pages 目录中所有可路由的 Razor 组件名称?
【发布时间】:2020-10-21 19:01:38
【问题描述】:

我想通过遍历可路由的 Razor 组件名称以编程方式生成菜单列表,如下所示。下面如何实现GetAllRoutableRazorComponentNames()?有可能吗?

@foreach (var filename in GetAllRoutableRazorComponentNames())
{
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="@filename">
            <span class="oi oi-list-rich" aria-hidden="true">@filename</span>
        </NavLink>
    </li>
}

【问题讨论】:

  • 您需要使用反射来查找具有 PageAttribute 的所有类型
  • @MisterMagoo:System.IO 类有什么简单的方法吗?
  • Router 组件使用RouteTableFactory 来做类似的事情。这是internal,但如果您需要自己的东西,source 应该很有用。
  • 一个组件可以有 2 个或更多 @page 属性,并且可能需要参数。您的菜单将如何处理?
  • 只是整个事情看起来有点X/Y问题。例如,标准应用程序有一个“/error”页面,你不希望它出现在你的菜单中。

标签: c# asp.net asp.net-core razor blazor


【解决方案1】:

我认为“完整”的解决方案将来也会对其他人有用,因此我将其作为社区 wiki。随意编辑。

感谢回答我问题的人herehere。我在这里使用了他们的解决方案,但做了一些小的调整。

@using System.Reflection
@using System.Text.RegularExpressions

<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Notes</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>

<div class="@NavMenuCssClass" @onclick=ToggleNavMenu>
    <ul class="nav flex-column">
        @foreach (var name in GetRoutableComponentNamesForMenu())
        {
            <li class="nav-item px-3">
                <NavLink class="nav-link"
                         href=@(name=="Index"?string.Empty:name)
                         Match=@(name=="Index"?NavLinkMatch.All:NavLinkMatch.Prefix)>
                    <span class="oi oi-home" aria-hidden="true"></span>
                    @Regex.Replace(name, @"(\B[A-Z])", " $1")
                </NavLink>
            </li>
        }
    </ul>
</div>


@code {
    private bool collapseNavMenu = true;

    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }

    public IEnumerable<string> GetRoutableComponentNamesForMenu()
    {
        var allComponents = Assembly
                .GetExecutingAssembly()
                .ExportedTypes
                .Where(t => t.IsSubclassOf(typeof(ComponentBase)));

        var routableComponents = allComponents
            .Where(c => c
                        .GetCustomAttributes(inherit: true)
                        .OfType<RouteAttribute>()
                        .Count() > 0);


        foreach (var routableComponent in routableComponents)
        {
            yield return routableComponent
                            .ToString()
                            // you need to adjust the following!
                            .Replace("Notes.Client.MenuPages.", string.Empty);
        }
    }
}

注意

  • MenuPages 是项目中的一个目录,仅包含要显示为菜单的可路由 Razor 组件。 Error 页面肯定不存在!

  • MenuPages 中每个组件的名称以 PascalCase 格式表示。

由于我是反射新手,完全限定的名称前缀是硬编码的。如果您知道如何在不进行硬编码的情况下使其更优雅,请随时进行编辑。

【讨论】:

    【解决方案2】:

    好的,这个只返回可路由的组件。当我有时间时,我也会改进它。但它会做你想做的事:

        @using System.Linq;
    @using System.Reflection;
    
    
    <button type="button" @onclick="GetRoutables">
        Get Route
        Url With Authorize Attribute
    </button>
    
    @code{
    
      public void GetRoutables()
      {
         // Get all the components whose base class is ComponentBase
        var components = Assembly.GetExecutingAssembly()
           .ExportedTypes
         .Where(t => t.IsSubclassOf(typeof(ComponentBase))).ToList();
        
        var routables = components.Where(c => 
            c.GetCustomAttributes(inherit: true).OfType<RouteAttribute> 
            ().ToArray().Count() > 0);
                       
    
         foreach (var routable in routables)
         {
            Console.WriteLine(routable.ToString());
    
         }     
    
        }
    
    }
    

    希望这会有所帮助...

    【讨论】:

      猜你喜欢
      • 2019-11-29
      • 2021-04-01
      • 2011-04-11
      • 1970-01-01
      • 2018-08-26
      • 2022-01-24
      • 2022-01-07
      • 2020-03-24
      • 2018-12-05
      相关资源
      最近更新 更多