Add DateOnly and TimeOnly to MVC Model Binding#45243
Conversation
TanayParikh
left a comment
There was a problem hiding this comment.
Congrats on your first PR in aspnetcore! 🎉
|
Adding the blocked label pending the approval and resolution of #45376. |
| options.ModelBinderProviders.Add(new CollectionModelBinderProvider()); | ||
| options.ModelBinderProviders.Add(new ComplexObjectModelBinderProvider()); | ||
| options.ModelBinderProviders.Add(new DateOnlyModelBinderProvider()); | ||
| options.ModelBinderProviders.Add(new TimeOnlyModelBinderProvider()); |
There was a problem hiding this comment.
Can these new IModelBinderProviders ever get hit outside of unit tests? I cloned this PR and added the following lines to MvcSandbox's HomeController.
[ModelBinder]
public TimeOnly Time { get; set; }And then made a request to /?Id=3&Time=12:34:56%20PM and added breakpoints. The Time got populated by the TryParseModelBinderProvider added by @brunolins16 in #40233. Since that's added before these providers, it gets first crack at binding DateOnly and TimeOnly.
For this reason and to maintain back compat, we put TryParseModelBinderProvider after DateTimeModelBinderProvider. Even if we remove the TryParseModelBinderProvider, the SimpleTypeModelBinderProvider would handle this first as well using TypeConverter.
Since we don't have any back compat concerns for DateOnly and TimeOnly, I'm not sure we need these. It does allow customizing DateTimeStyles if you construct the providers yourself and add them manually, but I don't like having to maintain providers for each possible type.
There was a problem hiding this comment.
@halter73 Are there any differences in behavior between the TryParse implementation and the concrete modelbinders? Or any other concern like perf? If the TryParse implementation supports all of them, should we get rid of the DateTime and DateTimeOffset modelbinders?
There was a problem hiding this comment.
I would like to get rid of the DateTime and DateTimeOffset model binders, but I don't think it's worth potentially breaking working code. @brunolins16 What do you think?
There was a problem hiding this comment.
@halter73 I do not think most people will change those binders directly. We can remove them from 8.0, make an announcement in preview1 and see if someone is broken by it.
There was a problem hiding this comment.
As reported here , it could potentially be break and was decided (I don't have the historical reason) to create specific binders for them even though the simpletypebinder supported them a long ago. That said I believe this is a worthy investigation and we don't need to delete them and instead just remove the default registration and let the binder available for manual registration.
There was a problem hiding this comment.
Here is a potential reason why the specific binders were created #34591 (comment)
Great point, this was an essential part of getting DateTime binding correct. That being said, DateTimeStyles.AdjustToUniversal is not supported for DateOnly and TimeOnly so the same requirement is not there.
There was a problem hiding this comment.
Yeah, the only benefit I see in have those two new binders, is allow users to customize the DateTimeStyles creating their own ModelBinderProviders.
There was a problem hiding this comment.
Suggestion 💡: What if we add those two new Binder to allow users customization, without the Providers (no registration), and let the TryParse/Converter binder do the work by default.
There was a problem hiding this comment.
These are the DatetimeStyles when using the TryParse binder:
aspnetcore/src/Shared/ParameterBindingMethodCache.cs
Lines 130 to 135 in 5c62d0f
There was a problem hiding this comment.
Yep, DateTimeStyles.AllowWhiteSpaces is what I currently have for these proposed providers. While writing them I found that the only supported styles for TimeOnly and DateOnly were the ones pertaining to white space, but I can't seem to find a doc page to back that up.
Also, do you think there's any gain/loss when TryParse is used over any of the other providers/binders? I see that TryParse goes before SimpleType.
Thanks for that but those types are already |
|
Hi @brunolins16. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
|
Sorry closed by mistake. |
@brunolins16 Yep, sounds like I need to make that docs PR regardless of the outcome of this one. |
| } | ||
| else if (type == typeof(DateOnly)) | ||
| { | ||
| model = DateOnly.Parse(value, valueProviderResult.Culture, _supportedStyles); |
There was a problem hiding this comment.
I recommend the TryParse here to avoid the exception
| } | ||
| else if (type == typeof(TimeOnly)) | ||
| { | ||
| model = TimeOnly.Parse(value, valueProviderResult.Culture, _supportedStyles); |
There was a problem hiding this comment.
I recommend the TryParse here to avoid the exception
|
Closing this PR since TryParseModelBinder already covers this use case with no additional API required |
Add DateOnly and TimeOnly to MVC Model Binding
Adds nullable
DateOnlyandTimeOnlyto list of model binding simple types.Description
Part of the effort tracked in #34591 to add
DateOnlyandTimeOnlysupport to Model binding as well as Blazor/regular routing.The logic almost exactly matches the implementation for
DateTimewith the exception ofDateTimeStyles.AdjustToUniversalbeing included as a supported style as this style is not supported by theDateOnlyandTimeOnlytypes.On the completion and merge of this PR, I will create an additional PR to add
DateOnlyandTimeOnlyto our list of supported types.