当前位置:  开发笔记 > 编程语言 > 正文

更改ASP.NET Core中DateTime解析的默认格式

如何解决《更改ASP.NETCore中DateTime解析的默认格式》经验,为你挑选了3个好方法。

我在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将按预期进行解析.



1> 小智..:

有同样的问题.虽然在请求正文中传递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将按预期进行解析.



2> 小智..:

我想在响应中格式化日期,并在ConfigureServices方法中执行以下操作:

services.AddMvc()
.AddJsonOptions(options =>
{
    options.SerializerSettings.DateFormatString = "mm/dd/yy, dddd";
});

希望有所帮助.



3> Shahab..:

考虑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)));

推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有