dotnet / dotnet/aspnetcore

Blazor static SSR support to override ParsableConverter for mapping non invariant DateTime values

Open
#56,485 0 comments 0 reactions 0 assignees View on GitHub
area-blazor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Is your feature request related to a problem? Please describe the problem.

I've been migrating one ASP.Net WebForms app which supports to choose the editable date format.

The current Blazor InputDate components doesn't support the same thing - because it uses the current OS formatting settings to format the displayed editable date values.

I figured out that in my case this is not possible due to the ParsableConverter design, which uses InvariantCulture to map form data to model property values:
[ParsableConverter.cs#L15](https://github.com/dotnet/aspnetcore/blob/94259788d58e16ba753900b4bf855a6aee08dcb1/src/Components/Endpoints/src/FormMapping/Converters/ParsableConverter.cs#L15)
`if (T.TryParse(value, **reader.Culture**, out result!))`

reader.Culture is set in the [HttpContextFormValueMapper.cs#L132](https://github.com/dotnet/aspnetcore/blob/94259788d58e16ba753900b4bf855a6aee08dcb1/src/Components/Endpoints/src/FormMapping/HttpContextFormValueMapper.cs#L132)
```
using var reader = new FormDataReader(
dictionary,
**CultureInfo.InvariantCulture,**
buffer.AsMemory(0, options.MaxKeyBufferSize),
formFiles)
```

### Describe the solution you'd like

Allow to override ParsableConverter from the user code to change this line of code:
`if (T.TryParse(value, **reader.Culture**, out result!))`
to
`if (T.TryParse(value, **CultureInfo.CurrentUICulture**, out result!))`

ParsableConverter and other referenced classes are **internal**. So it is not possible to override it in a user code now.

MVC and Razor Pages allows to do it via defining custom ModelBinderProviders.

For Interactive Blazor SSR we could do it by overriding [TryParseValueFromString](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.forms.inputdate-1.tryparsevaluefromstring?view=aspnetcore-8.0#microsoft-aspnetcore-components-forms-inputdate-1-tryparsevaluefromstring(system-string-t@-system-string@))

I see only these available options for the Blazor static SSR now:

- use a proxy model properties to bind Date values as strings

```
[Column("start_date")]
//[Display(Name = nameof(Resources.CommonCaptions.StartDate), ResourceType = typeof(Resources.CommonCaptions))]
//[DateRange]
public DateTime? StartDate { get; set; }

private string? _startDateValue = null;
[Display(Name = nameof(Resources.CommonCaptions.StartDate), ResourceType = typeof(Resources.CommonCaptions))]
[DataType(DataType.Date)]
[DateRange]
public string? StartDateValue
{
get => _startDateValue ?? $"{StartDate:d}";
set
{
_startDateValue = null;

if (string.IsNullOrEmpty(value))
StartDate = null;
else if (DateTime.TryParse(value.Trim(), out var dt))
StartDate = dt;
else
_startDateValue = value;
}
}

```
As a result - too much code for each DateTime model property

- Implement a custom InputDate component which will bind a hidden field value formatted using a universal date format.
A visible input will allow to enter a date in any configured format.
A hidden field value is updated on a visible field change (via client side JS code)
So, it repeats the binding logic of the [input type="date"] but allows end users to enter date values using a custom date format.
It's a more attractive and convenient way to use it right now.

### Additional context

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.