在BlazorWeb程序集中创建指向服务器控制器操作的链接

时间:2020-09-11 12:55:44

标签: asp.net-core routes blazor

我正在使用ASP.NET Core托管的WebAssembly Blazor编写应用程序。有些页面是在Blazor中实现的,但是某些旧页面仍然是ASP.NET Core Razor视图。我需要在Blazor组件中创建一个指向服务器上控制器动作的链接。

我可以写:

NavigationManager.NavigateTo("SomeContoller/SomeAction/123", true)

但是我不想将URL硬编码为操作,因为更改服务器路由或控制器/操作名称将破坏此类链接。有什么方法可以通过类似于ASP.Net Core UriHelper的帮助器来创建正确的链接?喜欢:

UriHelper.Action("SomeAction", "SomeController", new {id = 123});

2 个答案:

答案 0 :(得分:1)

在 Blazor 服务器应用中,您可以使用 LinkGenerator。用法和 UriHelper 没有太大区别:

@using Microsoft.AspNetCore.Routing
@inject LinkGenerator LinkGenerator

<a href="@LinkGenerator.GetPathByAction("SignIn", "Authentication")">Sign in</a>

ReSharper 也理解这一点,因此您将获得控制器和操作名称的自动补全。

在 WebAssembly 应用程序中,LinkGenerator 不可用,因此最好的办法是从服务器转储所有路由并实现您自己的链接生成器,该链接生成器在客户端使用该数据(其复杂性取决于路由的复杂性,来自 ASP.NET Core 的那个非常复杂)。

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Routing;

namespace BlazorTest.Server.Controllers
{
    [Route("api/routes")]
    [ApiController]
    public class RouteInformationController : ControllerBase
    {
        private readonly EndpointDataSource _endpointDataSource;

        public RouteInformationController(EndpointDataSource endpointDataSource)
        {
            _endpointDataSource = endpointDataSource;
        }

        public IEnumerable<object> Get()
        {
            foreach (var endpoint in _endpointDataSource.Endpoints.OfType<RouteEndpoint>())
            {
                var actionDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
                if (actionDescriptor == null)
                    continue;

                yield return new
                {
                    actionDescriptor.ControllerName,
                    actionDescriptor.ActionName,
                    Parameters = actionDescriptor.Parameters.Select(p => p.Name),
                    RoutePattern = endpoint.RoutePattern.RawText,
                };
            }
        }
    }
}

答案 1 :(得分:0)

您可以为应用程序中使用的所有URL创建一个具有常量属性的静态类。之后,在页面路径和导航路径中使用相同的静态类属性。下面是一个非常基本的版本:

public static class RouteUrls
{
    public static string Home = "/Home";
    public static string ProductList = "/Product";
    public static string ProductDetail = "/Product/Detail";
    public static string SomePage = "/SomeContoller/SomeAction";
}

// to access it use like this:
NavigationManager.NavigateTo($"{RouteUrls.SomePage}/123", true)

相关问题