【问题标题】:Render html conditionally based on route in Razor Pages根据 Razor Pages 中的路由有条件地渲染 html
【发布时间】:2020-05-21 06:20:12
【问题描述】:

假设我有以下 Razor 文件 _Layout.cshtml。使用 ASP.NET Core 3+ 和 Razor Pages 时如何编写注释条件。

<ul class="navbar-nav">
    <li class="nav-item">
        <a class="nav-link" asp-page="/Index">Index</a>
    </li>

    @* If route starts with /a/, for example http://localhost/a/1.html and http://localhost/a/2/1.html *@
    <li class="nav-item">
        <a class="nav-link" asp-page="/a/Index">A</a>
    </li>

    @* If route starts with /b/, for example http://localhost/b/1.html and http://localhost/b/2/1.html *@
    <li class="nav-item">
        <a class="nav-link" asp-page="/b/Index">B</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" asp-page="/b/1/Index">B other</a>
    </li>
</ul>

【问题讨论】:

  • 不确定这是否能解决您的问题,但看起来您可以向 ViewState 添加自定义值并基于此显示/隐藏元素。见stackoverflow.com/a/57040167/12730491(这里他们改变了整个布局文件,但它也应该适用于单个元素)。
  • @rm-code 这可行,但我认为有一种简单的方法可以访问 Razor 文件中的当前路由。假设不存在是否安全?

标签: asp.net-core razor razor-pages


【解决方案1】:

在 Razor 页面中,您可以在 _Layout 文件中使用 ViewContext.RouteData.Values["page"]。如果 URL 是例如https://localhost:44359/Help/About 那么它将产生/Help/About

使用您的代码:

@{
    string page = ViewContext.RouteData.Values["page"] as string; // Values[] produces objects, so cast is needed
}

<ul class="navbar-nav">
    <li class="nav-item">
        <a class="nav-link" asp-page="/Index">Index</a>
    </li>

    @if (page.StartsWith("/a/"))
    {
        <li class="nav-item">
            <a class="nav-link" asp-page="/a/Index">A</a>
        </li>
    }

    @if (page.StartsWith("/b/"))
    {
        <li class="nav-item">
            <a class="nav-link" asp-page="/b/Index">B</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-page="/b/1/Index">B other</a>
        </li>
    }
</ul>

【讨论】:

    【解决方案2】:

    您可以制定针对特定文件夹中的所有 Razor 页面执行的 Razor 页面约定。使用此约定,您可以设置一个操作过滤器(一个结果过滤器)来为 ViewData 添加一个标识符。

    过滤器:

    class AddRouteIdentifierFilter : ResultFilterAttribute
    {
        private readonly string identifier;
    
        public TestFilter(string identifier)
        {
            this.identifier = identifier;
        }
    
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            base.OnResultExecuting(context);
            ((PageResult)context.Result).ViewData["route-identifier"] = identifier;
        }
    }
    

    设置约定:

    services.AddMvc().AddRazorPagesOptions(opt => 
        opt.Conventions.AddFolderApplicationModelConvention("/A", model =>
            model.Filters.Add(new AddRouteIdentifierFilter("a"));
        );
        opt.Conventions.AddFolderApplicationModelConvention("/B", model =>
            model.Filters.Add(new AddRouteIdentifierFilter("b"));
        );
    );
    

    在 Razor 页面视图中访问标识符:

    <h1>Identifier: @ViewData["route-identifier"]</h1>
    

    【讨论】:

      猜你喜欢
      • 2020-11-06
      • 2020-01-12
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2020-12-10
      • 2015-06-28
      • 2017-02-22
      相关资源
      最近更新 更多