Description
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 in UserId
. You might think, "Oh, I'll just pass in a model of type SomeRandomComponent
" (I certainly did..), but that will give you this compiler error (https://learn.microsoft.com/en-us/aspnet/core/diagnostics/bl0005):
error BL0005: Component parameter 'UserId' should not be set outside of its component.
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:
InvalidOperationException: Object of type 'MyNamespace.SomeRandomComponent' does not have a property matching the name 'AuthorId'.
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
- Roslyn Analyzer that analyzes usages of
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) - Roslyn Source Generator that creates custom
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.