dotnet / dotnet/roslyn

Support string literal attributes for RenderFragment parameters

Open
#85,662 2 comments 0 reactions 0 assignees View on GitHub
Area-Razor Area-Razor-Compiler untriaged
Dominant language
C#
Stars
20.7k
Forks
4.3k
PR merge metrics
PR metrics pending

Description

### Summary

Allow a Blazor component parameter of type `RenderFragment` to be supplied using a string literal attribute:

```razor

```

Given:

```csharp
[Parameter, EditorRequired]
public RenderFragment Title { get; set; } = default!;
```

Razor should treat the literal as an encoded text fragment, equivalent to:

```razor

Connection lost

```

### Motivation

Templated components often expose named `RenderFragment` parameters such as `Title`, `Subtitle`, or `EmptyContent`. Named template elements work well for rich content, but they're verbose when the caller only needs to supply text.

A component author can enable literal syntax today by defining a union containing `string` and `RenderFragment`, but that introduces a named union type and requires the component to switch over its cases. If the component only needs content to render, a union is unnecessary ceremony.

### Current behavior

A literal is treated as a C# expression and doesn't compile:

```razor

```

An explicit string expression also can't be converted to `RenderFragment`:

```razor

```

Callers must use a fragment expression or named template element instead.

### Proposed behavior

For parameters typed as `RenderFragment` or `RenderFragment?`, lower a literal attribute to an encoded text fragment, semantically equivalent to:

```csharp
(RenderFragment)(builder => builder.AddContent(0, "Hello world"))
```

The value must be rendered as text, not raw markup. Rich content should continue to use named template syntax or an explicit `RenderFragment`.

Initially, this could be limited to literal attributes on non-generic `RenderFragment` parameters. `RenderFragment`, arbitrary string expressions, and mixed C#/markup attributes can remain out of scope.

dotnet/roslyn#84247, which implemented dotnet/razor#13188, provides related compiler precedent for identifying component parameters that accept string literals.

### Related work

- Literal attributes for unions containing a `string` case: dotnet/razor#13188
- Union-typed template parameters: dotnet/roslyn#85657
- Component attributes with complex content: dotnet/roslyn#85412

Contributor guide

Open the contributing guide

Research direction

Start by reading the related precedent in dotnet/roslyn#84247 and the linked dotnet/razor#13188 work, then compare the behavior described for literal component attributes here. Done means non-generic RenderFragment and RenderFragment? parameters accept literal attributes as encoded text fragments while generic fragments and richer expressions remain out of scope.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.