简体   繁体   中英

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

When adding Blazor components to an existing MVC or Razor page it's really useful to be able to pass parameters into the Blazor components, for example to pass the parameters in the MVC page's URL (such as an ID) onto the component.

Up until Core 3 Preview 9 this was possible for server rendered components using this syntax:

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

But from Preview 9 onward parameters can only be passed to statically rendered Blazor components .

The components still need to know information from the outer MVC page, how can this be achieved?

Update

This facility for passing parameters to all types of top level components is now back as of .NET Core 3.1 Preview 1, as discussed in this blog post by Dan Roth:

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 })) ```

Original Answer

This functionality has been removed, hopefully temporarily, due to performance issues around the stateful prerendering of pages .

Retrieving URL parameters and IDs in Blazor components

Hopefully the facility to pass parameters straight to the component will return, but in the meantime parameters from the outer MVC page's URL can be retrieved in the Blazor component by injecting the NavigationManager (formerly known as the IUriHelper ) into the component:

@Inject NavigationManager navigationManager;

You can then access the named parameters from the URL with this kind of approach as discussed here :

 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() : ""; }

Of if you're after the ID from a URL (eg www.mysite.com/sales/32 ) then you could do something like this:

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;
}

Using a wrapper component to keep the separation of concerns intact

Adding functionality to query the URL into a component will limit that component's re-usability as it is now dependent on the URL being in a certain format.

One solution to that is to create an extra wrapper Blazor component for the component we're building.

That wrapper component would then be responsible for either extracting values from the page's URL (using the approaches above for example), or could use Blazor's JS Interop to retrieve data from the page and would then pass those values on to the actual Blazor component that does the work.

That allows the original component to keep using parameters and will allow that component to be reusable. It also gives a better separation of concerns and avoids the need to open up a completed component later should the option to pass parameters directly to the component return (in which case the wrapper component can simply be deleted)

There's more discussion of all of this on this on this github issue .

ASP.NET Core 3.1 From your MVC view you can use param- to pass parameter to Server / Server-Prerenders component

For eg

<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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM