我在ASP.NET核心控制器中得到一个日期,如下所示:
public class MyController:Controller{ public IActionResult Test(DateTime date) { } }
该框架能够解析日期,但只能以英文格式.当我通过04.12.2017作为日期参数时,我的意思是2017年12月4日.这将被解析为英文日期,所以我的日期对象获得2017年4月12日的价值.我尝试仅使用这篇文章添加德语,并且这个,但没有成功.
ASP.NET Core需要做什么才能以正确的德语格式自动解析日期?
更新 I尝试设置RequestLocalizationOptions
services.Configure(opts => { var supportedCultures = new[] { new CultureInfo("de-DE"), }; opts.DefaultRequestCulture = new RequestCulture("de-DE"); // Formatting numbers, dates, etc. opts.SupportedCultures = supportedCultures; // UI strings that we have localized. opts.SupportedUICultures = supportedCultures; });
还是行不通.我打电话给example.com/Test?date=12.04.2017并在我的调试器中得到了这个:
public IActionResult Test(DateTime date) { string dateString = date.ToString("d"); // 04.12.2016 string currentDateString = DateTime.Now.ToString("d"); // 14.01.2016 return Ok(); }
小智.. 11
有同样的问题.虽然在请求正文中传递DateTime工作正常(因为Json转换器处理此工作人员),但将查询字符串中的DateTime作为参数传递具有一些文化问题.
我不喜欢"改变所有请求文化"的方法,因为这可能会影响其他类型的解析,这是不可取的.
所以我的选择是使用IModelBinder覆盖默认的DateTime模型绑定:https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding
我做了什么:
1)定义自定义绑定器(使用'out'参数的c#7语法):
public class DateTimeModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext)); // Try to fetch the value of the argument by name var modelName = bindingContext.ModelName; var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); if (valueProviderResult == ValueProviderResult.None) return Task.CompletedTask; bindingContext.ModelState.SetModelValue(modelName, valueProviderResult); var dateStr = valueProviderResult.FirstValue; // Here you define your custom parsing logic, i.e. using "de-DE" culture if (!DateTime.TryParse(dateStr, new CultureInfo("de-DE"), DateTimeStyles.None, out DateTime date)) { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "DateTime should be in format 'dd.MM.yyyy HH:mm:ss'"); return Task.CompletedTask; } bindingContext.Result = ModelBindingResult.Success(date); return Task.CompletedTask; } }
2)为您的活页夹定义提供程序:
public class DateTimeModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Metadata.ModelType == typeof(DateTime) || context.Metadata.ModelType == typeof(DateTime?)) { return new DateTimeModelBinder(); } return null; } }
3)最后,注册您的提供程序以供ASP.NET Core使用:
services.AddMvc(options => { options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider()); });
现在,您的DateTime将按预期进行解析.
有同样的问题.虽然在请求正文中传递DateTime工作正常(因为Json转换器处理此工作人员),但将查询字符串中的DateTime作为参数传递具有一些文化问题.
我不喜欢"改变所有请求文化"的方法,因为这可能会影响其他类型的解析,这是不可取的.
所以我的选择是使用IModelBinder覆盖默认的DateTime模型绑定:https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding
我做了什么:
1)定义自定义绑定器(使用'out'参数的c#7语法):
public class DateTimeModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext)); // Try to fetch the value of the argument by name var modelName = bindingContext.ModelName; var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); if (valueProviderResult == ValueProviderResult.None) return Task.CompletedTask; bindingContext.ModelState.SetModelValue(modelName, valueProviderResult); var dateStr = valueProviderResult.FirstValue; // Here you define your custom parsing logic, i.e. using "de-DE" culture if (!DateTime.TryParse(dateStr, new CultureInfo("de-DE"), DateTimeStyles.None, out DateTime date)) { bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "DateTime should be in format 'dd.MM.yyyy HH:mm:ss'"); return Task.CompletedTask; } bindingContext.Result = ModelBindingResult.Success(date); return Task.CompletedTask; } }
2)为您的活页夹定义提供程序:
public class DateTimeModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Metadata.ModelType == typeof(DateTime) || context.Metadata.ModelType == typeof(DateTime?)) { return new DateTimeModelBinder(); } return null; } }
3)最后,注册您的提供程序以供ASP.NET Core使用:
services.AddMvc(options => { options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider()); });
现在,您的DateTime将按预期进行解析.
我想在响应中格式化日期,并在ConfigureServices方法中执行以下操作:
services.AddMvc() .AddJsonOptions(options => { options.SerializerSettings.DateFormatString = "mm/dd/yy, dddd"; });
希望有所帮助.
考虑TypeConverter
为您的日期时间使用自定义(来源):
using System; using System.ComponentModel; using System.Globalization; using System.Drawing; public class DeDateTimeConverter : TypeConverter { // Overrides the CanConvertFrom method of TypeConverter. // The ITypeDescriptorContext interface provides the context for the // conversion. Typically, this interface is used at design time to // provide information about the design-time container. public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) { return true; } return base.CanConvertFrom(context, sourceType); } // Overrides the ConvertFrom method of TypeConverter. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { if (DateTime.TryParse(((string)value), new CultureInfo("de-DE") /*or use culture*/, DateTimeStyles.None, out DateTime date)) return date; } return base.ConvertFrom(context, culture, value); } }
并TypeConverter
在您的媒体资源上使用属性:
[TypeConverter(typeof(DeDateTimeConverter))] public DateTime CustomDateTime { get; set; }
更新资料
根据我的经验,并感谢此答案和@zden?k评论,TypeConverter属性不起作用,您应该在Startup.cs
以下位置注册TypeConverter :
TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(DeDateTimeConverter)));