Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prerendering server components with parameters is not supported #13721

Open
tstaa opened this issue Sep 5, 2019 · 13 comments

Comments

@tstaa
Copy link

commented Sep 5, 2019

I'm trying to use the component in my CSHTML view (existing MVC app):
@(await Html.RenderComponentAsync<NewJobComponent>(RenderMode.ServerPrerendered, new { Job = Model }))

I understand why, but what's the alternative in order to pass anything to the component? Since I cannot do the following in my CSHTML file:
<NewJobComponent Job="Model" />

@Eilon Eilon added the area-blazor label Sep 5, 2019

@mkArtakMSFT

This comment has been minimized.

Copy link
Member

commented Sep 6, 2019

Thanks for contacting us.
We currently have no support for this. We will park this issue in the backlog to collect more feedback from community.

@mkArtakMSFT mkArtakMSFT added this to the Backlog milestone Sep 6, 2019

@Dimexoid

This comment has been minimized.

Copy link

commented Sep 6, 2019

The only way I've found for now is parsing a URL like http://sitename/blazorcomponent?myparam=123 this way:

@Inject NavigationManager navMan;
..

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

@leMicin

This comment has been minimized.

Copy link

commented Sep 6, 2019

We have a scenario where we plan to progressively transition our CMS application from MVC to use mostly Razor components. One of our use cases is a FormComponent that our CMS admins can configure with their own questions. When we call the RenderComponentAsync, I expect to have a way to tell my component which FormId I want to render. The majority of our use cases require the functionality of telling the component whatto render.

Html.RenderComponentAsync<FromComponent>(RenderMode.ServerPrerendered, new { FormGuid = content.ContentGuid })
@tomRedox

This comment has been minimized.

Copy link

commented Sep 7, 2019

We have a similar situation to @leMicin:

We're swapping parts of an existing MVC app to Blazor components. In many cases we have code on an a Razor Page or MVC page that looks like this:

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

where the SaleId was a parameter in the URL of the page.

I'm really grateful to @Dimexoid for the idea for retrieving that value in the component itself, but that limits the re-usability of the components as it is now reliant on existing in a page that has a URL with parameters with certain names. The original approach seems cleaner to me.

Also, if we were creating components inside a loop on a Razor page we'd want to be able to pass the ID of the list item into the Blazor component.

What's the logic behind removing the option of passing in the model?

@leMicin

This comment has been minimized.

Copy link

commented Sep 7, 2019

@tomRedox They explained it on this issue : #12245 . There was a performance problem with the solution as it was. I can understand why the solution was not working.

I wonder why the parameters can't be sent to the client with the Document, and when the client connects to the server, it passes the parameters to the server. This will make so the server does not use expensive CPU / Memory until the client successfully connects.

Removing it without offering an alternative will make it pretty much impossible for us to transition projects, which is sad because I was excited for Blazor.

@tomRedox

This comment has been minimized.

Copy link

commented Sep 7, 2019

@leMicin ahhh.. thank you, I hadn't seen that.

For our use case where we have a low number of users with a system running on an intranet, I think we're pretty unlikely to encounter the issues mentioned in #12245.

I remember when React started getting traction in the enterprise, a lot of that was due to being able to introduce it into existing codebases. It seems a real shame to limit that here, it seems like there must be some way to pass the values of the parameters without incurring the pre-rendering issues.

@mikoskinen

This comment has been minimized.

Copy link

commented Sep 8, 2019

Ah, losing the option to pass parameters to components is a real shame. As others, we were using Blazor to progressively convert our existing Razor Pages application into a more dynamic experience.

@edgolub

This comment has been minimized.

Copy link

commented Sep 10, 2019

I'm trying not to build an SPA, as blazor seems to force me to do.

This feature would have been great for that purpose.

@Draphster

This comment has been minimized.

Copy link

commented Sep 10, 2019

I'll throw my hat in with everyone else in the thread. I was trying to use Blazor to create a more dynamic experience for my MVC application rather then investing in Angular/React. That's severely hindered by removing the ability to pass in parameters. I may be able to over come it with some additional coding on the Blazor component, but it lessens the separation of concerns of MVC and I thought one of the goals of Blazor was to work with existing Microsoft technologies, not forcing them into a new one. Like @leMicin I was using this for a low usage internal intranet app, and I don't forsee the issues in #12245.

@tomRedox

This comment has been minimized.

Copy link

commented Sep 11, 2019

Thinking about it a bit more, one potential answer here is to create an extra 'mvc wrapper' Blazor component for the component we're building. The wrapper would then be responsible for either extracting values from the page's URL, 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 would allow the original component to keep using parameters and help that component to continue to be resusable.

Then if the option to pass in parameters returns then the inner component can stay unchanged and we can just delete the wrappers.

That would at least keep a reasonable separation of concerns and avoid the need to open up a completed component later.

@mkArtakMSFT mkArtakMSFT modified the milestones: Backlog, 5.0.0-preview1 Sep 11, 2019

@schmitch

This comment has been minimized.

Copy link

commented Sep 18, 2019

actually this + the fact that OnInitializedAsync is called twice, makes blazor not that useful for many scenarios. I wanted to enhance one of our products with blazor but it's hard to do so, when we either can't support PreRendering or we need to have a performance offset by calling everything twice.

@tomRedox

This comment has been minimized.

Copy link

commented Sep 18, 2019

@mkArtakMSFT now this has a milestone set, does that mean this feature will return on 5.0.0-preview1, or just that it's up for consideration at that time? I'm wondering whether to design components on the assumption that we will ultimately be able to pass values to them via parameters in future?

@tstaa

This comment has been minimized.

Copy link
Author

commented Sep 18, 2019

This makes transition from MVC to Blazor very difficult.
And I think it should be considered at least for 3.1 instead of 5.0!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants
You can’t perform that action at this time.