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

Easily passing RenderFragment children to Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper #31772

Closed
ghost opened this issue Apr 13, 2021 · 8 comments
Labels
area-blazor Includes: Blazor, Razor Components Blazor ♥ MVC Issues related to integration between Blazor and MVC/Razor pages design-proposal This issue represents a design proposal for a different issue, linked in the description feature-prerendering Issues related to prerendering blazor components
Milestone

Comments

@ghost
Copy link

ghost commented Apr 13, 2021

Summary

Currently, the Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper/component tag helper doesn't provide for children (to pass through to RenderFragment properties of the specified component):

<component type="typeof(MyComponent)" render-mode="Static" param-Key="@("Value")">
    @if (MyExampleMarkup) {
        <h1>Test 1234</h1>
    }
</component>

This throws an error; apparently, this tag helper cannot contain children (Element does not allow content and cannot have have separate end tag). After some trying, I came to this:

@{
    RenderFragment RenderHtml = __builder =>
    {
        @if (MyExampleMarkup) {
            <h1>Test 1234</h1>
        }
    };
}
<component ... param-ChildContent="@RenderHtml" />

While this works, it is not very asthetically pleasing. I'd like to propose that the component tag helper should get support for child components, just as if it were the actual component itself.

Motivation and goals

  • Razor Page code is supposed to be concise and readable; this is confusing
  • Basically a workaround that shouldn't be needed

In scope

As outlined above :) I'm proposing a design change to the Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper tag helper, in order to allow children for RenderFragment props.

Risks / unknowns

Developers might accidentally pass in children to components that don't accept RenderFragments, or too little children. As such, some kind of typing/validation is needed to ensure that, just like with a regular component, all the property requirements are ordinarily met.

Examples

See my first code snippet, which outlines the ideal syntax I'm advocating for.

@ghost ghost added the design-proposal This issue represents a design proposal for a different issue, linked in the description label Apr 13, 2021
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Apr 13, 2021
@javiercn
Copy link
Member

@GitGangGuy thanks for contacting us.

We don't support this because it's not obvious to make it work in the general case. A few examples:

  • You are prerendering a webassembly component an pass in a callback from the server.
    • That callback will be defined in the server assembly, so your webassembly code will fail at runtime.
  • Arguments need to be serializable to work with webassembly and server-side blazor
    • Render fragments are not serializable (they are delegates).

The only case where its applicable to do this is when the render mode is static, which is the only mode that can guarantee that we don't try to serialize anything.

We haven't seen a huge demand for it, so I'm going to park this in the backlog to gather more feedback about it.

@javiercn javiercn added this to the Backlog milestone Apr 14, 2021
@ghost
Copy link

ghost commented Apr 14, 2021

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@ghost
Copy link
Author

ghost commented Apr 14, 2021

@javiercn What is the difference between writing a function that returns the RenderFragment and passing that as a parameter to the component tag helper vs. passing in the RenderFragment as a child? Also, why shouldn't this work with a different render-mode other than Static?

@javiercn
Copy link
Member

@GitGangGuy We don't prevent you from passing it as a parameter, however you need to go out of your way to do so.

Passing non serializable parameters is not supported, we simply don't put additional code to enforce it because you are going to get an error already in any other cases other than static which is the least common of them.

@ghost
Copy link
Author

ghost commented Apr 14, 2021

@javiercn Why do component arguments in Razor Pages need to be serializable then? The template _Hosts.cshtml file uses the component tag helper with ServerPrerendered. If I decided to pass in a parameter for fun's sake, why shouldn't that be possible/why would that cause damage? The way I understand this is that, since the component is ServerPrerendered anyway, a SignalR connection is established, after which any potential callbacks to the server could also work just fine. Obviously, this wouldn't work with Blazor WASM, but that would be a rather simple restriction to put in place (if project.host == WASM -> throw server-side components with non-serializable arguments not allowed) ^^

@javiercn
Copy link
Member

@GitGangGuy parameters are serialized into the document and then sent back to the server when the browser starts the circuit.

@javiercn
Copy link
Member

The way I understand this is that, since the component is ServerPrerendered anyway, a SignalR connection is established, after which any potential callbacks to the server could also work just fine

The callback that you pass in during _Host.cshtml needs to get serialized into the document and then sent back to the server when the signalr connection is established and the circuit is started. Delegates are not serializable, hence why this is not allowed.

@javiercn javiercn added feature-prerendering Issues related to prerendering blazor components Blazor ♥ MVC Issues related to integration between Blazor and MVC/Razor pages labels Apr 20, 2021
@danroth27
Copy link
Member

We're tracking this as part of #6348

@ghost ghost locked as resolved and limited conversation to collaborators Nov 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components Blazor ♥ MVC Issues related to integration between Blazor and MVC/Razor pages design-proposal This issue represents a design proposal for a different issue, linked in the description feature-prerendering Issues related to prerendering blazor components
Projects
None yet
Development

No branches or pull requests

3 participants