Datetimes with unspecified Kind are giving my endpoints some problems. So I want to apply a converter globally to make any unspecified kind datetimes to local. I was able to do this for all datetimes being read from json with JsonConverter<DateTime>
but since url/query parameters aren't json they don't get the conversion. Is there a way to do this for url/query parameters as well before it hits the endpoint logic or do I need to do it in each endpoint?

- 197
- 1
- 3
- 17
-
Are you using MVC? You can use a custom `ModelBinder` if so... See also [Parse QueryString into strongly typed object](https://stackoverflow.com/q/37703540/215552) and [Parse and modify a query string in .NET Core](https://stackoverflow.com/q/29992848/215552) – Heretic Monkey Feb 03 '21 at 18:53
1 Answers
Your issue can be solved by custom model binding
which is a kind of cross-cutting concerns
. The idea of cross-cutting concerns
is to find a common extensibility point in a pipeline to inject some code to do something without repeating or spreading the code everywhere. So here you can use a custom IModelBinder
which should always works. However as recommended by Microsoft, in this case you have a string representation of DateTime
, you need to convert that to DateTime
. This should be done with TypeConverter
instead which is even simpler than using a custom IModelBinder
. You can create a custom TypeConverter
for your DateTime
string (obtained from the query string, route data, ...) to deal with some specific format of DateTime
.
Here is just an example:
public class CustomDateTimeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return typeof(DateTime?).IsAssignableFrom(destinationType) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
//your custom logic to parse a DateTime from your specific format here
//For a simple and funny example, I use the word "today"
if(value?.ToString() == "today")
{
return DateTime.Today;
}
return base.ConvertFrom(context, culture, value);
}
}
Now you need to register this custom type converter for DateTime
such as in the ConfigureServices
method in Startup.cs
(can be put in static methods as well):
TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(CustomDateTimeConverter)));
Now suppose your model property (of DateTime
or DateTime?
) name is Date
, the following query string should send the DateTime.Today
to your model property:
?date=today

- 61,710
- 16
- 105
- 130