Open KennethHoff opened 8 months ago
@KennethHoff thanks for contacting us.
If we wanted, we could do this with an analyzer that simply checks the properties you are passing match those expected by the component. No need to do runtime changes if the editing experience is what we are looking to match.
The other way to do this would be to take an expression in the form of
() => new CustomerComponent
{
Value = a,
Other = b
}
and rewrite it to just emit new { Value = a, Other = b }
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.
@KennethHoff Regards to BL0005: Component parameter should not be set outside of its component
:
Component parameters should be assigned to as part of the component initialization or as part of SetParametersAsync. Assigning a value to a parameter from an external source results in the value being overwritten the next time the component renders.
Given that you render the HTML on the server side, is that warning actually relevant? I've tested the same approach with HTMX and see no runtime issues myself.
Background and Motivation
ASP.Net Core 8 introduced the
RazorComponentResult<T>
which allows a developer to render Razor Components from normal endpoints. This is very useful for for example HTMX as it allows you to create very simple endpoints like this, which will return a pre-rendered Razor Component as raw HTML over the wire.However, there is one huge problem with the ergonomics here when it comes to parameter passing, as you have to pass in dynamic objects, like the following:
Without any further context you might not realize the problem, but here's the component:
As you can see, this will not function as you'd expect - in fact, it will throw at runtime. The reason is that I passed in
AuthorId
when I should've passed inUserId
. You might think, "Oh, I'll just pass in a model of typeSomeRandomComponent
" (I certainly did..), but that will give you this compiler error (https://learn.microsoft.com/en-us/aspnet/core/diagnostics/bl0005):So the only solution we have is to pass in an anonymous object and pray we did it right.
This is not only a problem for when you forget to add a prop, but also when you forget to remove a prop, as if the component doesn't have a prop with the name you specified, you also get a runtime error:
There is also the problem with the fact that - as you can see in the third image (The one with the Component code), I have
[EditorRequired]
on the parameter, but the component renders just fine - no warning or anything - despite me not passing it in (in the first example)Proposed API
I don't have any specific APIs in mind, but in an ideal world I'd love for there to be an overload that works something like this:
Usage Examples
Alternative Designs
RazorComponentResult<T>
constructors and warns you (with quick fixes) whenever you don't address all errors (Removes invalid ones, and adds all parameters, as well as type-checks them)RazorComponentResult<T>
for each Component:Risks
The proposed API presumably cannot be implemented; I just mentioned what would I consider more-or-less ideal. Assuming we go that direction, then the component parameter assignment logic would presumably need to be rewritten somewhat, which could be quite a huge undertaking.