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

Closed
tstaa opened this issue Sep 5, 2019 · 23 comments
Closed

Prerendering server components with parameters is not supported #13721

tstaa opened this issue Sep 5, 2019 · 23 comments
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one ✔️ Resolution: Duplicate Resolved as a duplicate of another issue

Comments

@tstaa
Copy link

tstaa 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 Includes: Blazor, Razor Components label Sep 5, 2019
@mkArtakMSFT
Copy link
Member

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
@mkArtakMSFT mkArtakMSFT added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Sep 6, 2019
@Dimexoid
Copy link

Dimexoid 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
Copy link

leMicin 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
Copy link

tomRedox 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
Copy link

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

If you can't have the parameters on the server because we are unsure if the client will actually open a connection, then that means the parameters need to be sent from the client on the opening of the connection.

The parameters should be sent to the client with the Document, and when the client connects to the server, it sends 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
Copy link

tomRedox 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
Copy link

mikoskinen 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
Copy link

edgolub 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
Copy link

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

tomRedox 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
Copy link

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

@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
Copy link
Author

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

@mkArtakMSFT
Copy link
Member

@tomRedox assuming we will find a good solution here, yes, this will be part of 5.0.

@DrDave-M
Copy link

I'd like to chime in and say I was very surprised to see this error... What is the point of a component that you can't pass a parameter to? If even just an Id value...
@(await Html.RenderComponentAsync<PplComponent>(RenderMode.ServerPrerendered, new { Id = 1 }))
I was very excited to use server side blazor to render complex forms and "wizards" in my MVC app, rather than using signalR and typescript. But this kinda stops that idea...

@tomRedox
Copy link

@DrDave-M as I understand it the parameter feature hasn't been removed because it's thought to be unnecessary, it got pulled as part or removing the facility for stateful pre-rendering.

That change was made close to the final release date for Core 3, so I guess there wasn't time to give this further attention at that point.

I've tagged @rynowak into this conversation back on #12245 too.

@mkArtakMSFT
Copy link
Member

It seems there has been a lot of activity on this thread. We're going to try (not a promise) to bring this in 3.1 as part of #14433

@mkArtakMSFT mkArtakMSFT added the ✔️ Resolution: Duplicate Resolved as a duplicate of another issue label Sep 25, 2019
@fireinthemountain
Copy link

I was hoping to use Blazor in my applications. Sadly, I would use tutorial examples that use parameters, only to fail. The lack of ability to pass parameters from MVC views or razor pages is a deal killer for my organization.

@tomRedox
Copy link

tomRedox commented Oct 3, 2019

The code for passing parameters to prerendered server components has now been restored and will reappear in 3.1. See #14433.

@ccit-spence
Copy link

Should this work with 3.1.100-preview1-014459?

@vitalragaz
Copy link

vitalragaz commented Oct 20, 2019 via email

@ccit-spence
Copy link

I am still getting this using the CLI on a Mac.
@(await Html.RenderComponentAsync<CommentInput>(RenderMode.ServerPrerendered, new { RelatedId = Model.Data.Id}))
InvalidOperationException: Prerendering server components with parameters is not supported.

@mkArtakMSFT
Copy link
Member

@ccit-spence what's the SDK you're using? Most probably you've got something wrong in your setup.
If, however, you think you're running into an issue caused by the framework, please file a new issue and provide as much details as possible, so we can try to reproduce it.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one ✔️ Resolution: Duplicate Resolved as a duplicate of another issue
Projects
None yet
Development

No branches or pull requests