如何将参数从 MVC/Razor 页面传递到顶级服务器端 blazor 组件?

How to pass parameters to a top-level server-side blazor component from an MVC/Razor page?

将 Blazor 组件添加到现有 MVC 或 Razor 页面时,能够将参数传递到 Blazor 组件非常有用,例如传递 MVC 页面 URL 中的参数(例如 ID ) 到组件上。

在 Core 3 Preview 9 之前,这对于使用此语法的服务器渲染组件是可能的:

@(await Html.RenderComponentAsync<NewJobComponent>(new { SaleId = Model.SaleId }))

但是从预览版 9 开始 parameters can only be passed to statically rendered Blazor components

组件还需要知道外层MVC页面的信息,如何实现?

更新

从 .NET Core 3.1 Preview 1 开始,这种用于将参数传递给所有类型的顶级组件的功能现已恢复,正如 Dan Roth 在 this blog post 中所讨论的那样:

Pass parameters to top-level components

Blazor Server apps can now pass parameters to top-level components during the initial render. Previously you could only pass parameters to a top-level component with RenderMode.Static. With this release, both RenderMode.Server and RenderModel.ServerPrerendered are now supported. Any specified parameter values are serialized as JSON and included in the initial response.

For example, you could prerender a Counter component with a specific current count like this:

Html.RenderComponentAsync<Counter>(RenderMode.ServerPrerendered, new {
CurrentCount = 123 })) ```

原答案

由于 performance issues around the stateful prerendering of pages.

,此功能已被删除,希望是暂时的

正在 Blazor 组件中检索 URL 参数和 ID

希望将参数直接传递给组件的功能 return,但与此同时,可以通过注入 [=17] 在 Blazor 组件中检索来自外部 MVC 页面 URL 的参数=](以前称为IUriHelper)进入组件:

@Inject NavigationManager navigationManager;

然后您可以使用 this kind of approach as discussed here:

从 URL 访问命名参数
protected override void OnParametersSet()
{
   var uri = new Uri(navMan.Uri);
   string myparamStr= 
Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query).TryGetValue("myparam", out var myparam) ? myparam.First() : "";
}

如果您在 URL 的 ID 之后(例如 www.mysite.com/sales/32),那么您可以这样做:

public static bool GetIdFromUri(string uriAddress, out int id)
{
    var uri = new Uri(uriAddress);

    string lastSegment = uri.Segments.Last();

    if (!string.IsNullOrWhiteSpace(lastSegment) && int.TryParse(lastSegment, out var paramId))
    {
        id = paramId;
        return true;
    }

    id = -1;
    return false;
}

使用包装器组件保持关注点分离完整

向组件添加查询 URL 的功能将限制该组件的可重用性,因为它现在依赖于特定格式的 URL。

一个解决方案是为我们正在构建的组件创建一个额外的包装器 Blazor 组件。

然后,该包装器组件将负责从页面的 URL 中提取值(例如使用上述方法),或者可以使用 Blazor 的 JS Interop 从页面中检索数据,然后将这些值传递给执行工作的实际 Blazor 组件的值。

这允许原始组件继续使用参数并允许该组件可重用。它还提供了更好的关注点分离,并且如果可以选择将参数直接传递给组件 return(在这种情况下,可以简单地删除包装器组件)[=26=,则避免以后需要打开一个完整的组件]

在此 on this github issue.

上有更多关于所有这些的讨论

ASP.NET Core 3.1 从您的 MVC 视图中,您可以使用 param- 将参数传递给服务器/Server-Prerenders 组件

例如

<div class="mb-4">
    <component type="typeof(TestStorables)"
               render-mode="Server"
               param-UserId="@Model.UserId"
               param-AccountId="@Model.AccountId"
               param-Environment="@Model.Environment"
               param-Title="@Convert.ToString("Test Storable")"
               param-PartitionKey="@Model.AccountId"
               param-Limit="10" />

</div>