我正在使用ASP.NET Core托管的WebAssembly Blazor编写一个应用程序。有些页面是在Blazor中实现的,但有些旧页面仍然是ASP.NET Core Razor视图。我需要在Blazor组件中创建一个链接,指向服务器上控制器的操作。
我可以写:
NavigationManager.NavigateTo("SomeContoller/SomeAction/123", true)
但我不想将url硬编码为action,因为更改服务器路由或controller/action名称会破坏这样的链接。有没有任何方法可以通过一些帮助程序创建正确的链接,类似于ASP.Net核心UriHelper?类似:
UriHelper.Action("SomeAction", "SomeController", new {id = 123});
在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,
};
}
}
}
}
您可以为应用程序中使用的所有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)