如何在 Asp.Net Core 中为日期绑定设置文化?

Posted

技术标签:

【中文标题】如何在 Asp.Net Core 中为日期绑定设置文化?【英文标题】:How to set culture for date binding in Asp.Net Core? 【发布时间】:2017-11-25 01:53:14 【问题描述】:

我有一个带有 MVC 的 Asp.Net Core 应用程序。我正在提交一个带有日期的表格。

表格看起来(大致)如下:

@model EditCustomerViewModel
<form asp-action="Edit">
    <input asp-for="ServiceStartDate" class="form-control" type="date" />
    <input type="submit" value="Update" class="btn btn-success" />
</form>

控制器动作是:

[HttpPost]
public async Task<IActionResult> Edit(EditCustomerViewModel viewModel)

    // do stuff
    return RedirectToAction("Index");

查看模型是:

public class EditCustomerViewModel

    public Guid Id  get; set; 

    [DataType(DataType.Date)]
    public DateTime ServiceStartDate  get; set; 

    [DataType(DataType.Date)]
    public DateTime? ServiceEndDate  get; set; 

    // etc.

我在英国,所以日期不是美国格式:dd/MM/YYYY。所以默认情况下我提交6/22/2017

在调试期间查看控制器中提交的视图模型时,如果以英国格式提交,则日期为空,但如果使用美国格式则可以。即6/22/2017 给了我null,但22/6/2017 绑定到正确的日期。

我已尝试将此添加到 Startup.cs,但没有任何区别:

var supportedCultures = new[]  new CultureInfo("en-GB") ;
app.UseRequestLocalization(new RequestLocalizationOptions

    DefaultRequestCulture = new RequestCulture("en-GB"),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
);
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-GB");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-GB");
CultureInfo.CurrentCulture = new CultureInfo("en-GB");
CultureInfo.CurrentUICulture = new CultureInfo("en-GB");

我检查了 HTTP 标头,并且发布了正确的标头:

Accept-Language: en-GB,en

我做错了什么?如何告诉 MVC Core binders 以 UK 格式绑定日期?

附言我在 VS2017 上使用 *.csproj 项目文件,目标框架为 .NetCoreApp 1.1

【问题讨论】:

这两个github.com/aspnet/Localization/issues/136,jerriepelser.com/blog/…你是不是已经遇到过 另外yyyy/MM/dd 总是有效的。如果一切都失败了。 @Nkosi 与CurrentCultureCurrentUiCulture 的所有舞蹈似乎对日期绑定没有任何影响。我可能会走你提到的第二种格式的道路 @Nkosi 是的,已经整理好了 - 我首先让自己感到困惑,但在剥开所有层之后它起作用了。 "如果以英国格式提交,日期为空,但如果使用美国格式则很好。即 2017 年 6 月 22 日给我空,但 22/6/2017 绑定到正确的日期" -我猜你得到了“ie”之后的部分混在一起。 【参考方案1】:

有几件事。我不确定您是否可以像这样将新的设置对象推送到中间件中(您可能可以),但大多数时候我都看到它在 ConfigureServices 方法中像这样使用:

public void ConfigureServices(IServiceCollection services)

    services.Configure<RequestLocalizationOptions>(options =>
    
        options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en-NZ");
        options.SupportedCultures = new List<CultureInfo>  new CultureInfo("en-US"), new CultureInfo("en-NZ") ;
    );

    services.AddMvc();

第二。中间件的顺序非常重要。确保您对 UseRequestLocalization 的调用发生在 UseMvc 之前。事实上,它可能应该是您管道中的第一件事,除非有特定的原因不能这样做。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseRequestLocalization();
    app.UseMvc();

最后,您能否尝试从管道中删除所有提供程序(其中一个是 cookie 提供程序。我无法理解您为什么会拥有此 cookie,但让我们尝试一下)。

在您的配置方法调用中清除 RequestCultureProviders 列表。这应该确保没有其他东西可以设置文化。

public void ConfigureServices(IServiceCollection services)

    services.Configure<RequestLocalizationOptions>(options =>
    
        options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en-GB");
        options.SupportedCultures = new List<CultureInfo>  new CultureInfo("en-GB") ;
        options.RequestCultureProviders.Clear();
    );

    services.AddMvc();

更多信息:http://dotnetcoretutorials.com/2017/06/22/request-culture-asp-net-core/

【讨论】:

感谢您对此进行调查。我已经尝试过您的建议,请阅读文章。事实上,我最初的注册是在错误的地方。我已经将它移到所有与 MVC 相关的注册之上,它并没有改变任何事情。这些文化似乎不会影响 MVC 绑定请求日期的方式。 啊啊啊……它正在工作。对日期有点困惑 - 一旦清除了所有周围的东西 - 我得到了正确的日期绑定。 我在 Debian 上使用带有 nginx 的 Net Core。当我使用 dotnet app.dll 直接在命令行上启动时,日期在 POST 上运行良好,但是当我将应用程序作为 systemd 服务启动时,格式会发生变化。这个答案对我很有效,CultureInfo("pt-BR") 这对我有用,我使用的是 net6,当 BodyRequest 中的 DateTime 值总是转换为 dd/MM/yyyy HH.mm.ss 时感到困惑,但我需要的格式是 en-GB 格式=> HH:mm:ss【参考方案2】:

aspnet core 2.0 的更新答案

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    
        var supportedCultures = new[]  new CultureInfo("es-CO") ;
        app.UseRequestLocalization(new RequestLocalizationOptions
        
            DefaultRequestCulture = new RequestCulture("es-CO"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        );

        // other configurations after (not before)
    

【讨论】:

这适用于我 ASP.NET Core 3.1。谢谢!可惜模型对象中DisplayFormat中指定的DataFormatString在绑定时不遵守ApplyFormatInEditMode=true。

以上是关于如何在 Asp.Net Core 中为日期绑定设置文化?的主要内容,如果未能解决你的问题,请参考以下文章

在 Azure 中为 ASP.NET Core Web 应用设置 SQL 连接字符串

如何在 Telerik Grid 中为 ASP.NET MVC 绑定图像

如何在 ASP.NET Core 中为 gRPC 服务添加全局异常处理 ?

如何在asp.net core razor pages 2.2中设置日期格式和文化

如何在 asp.net core 3.1 中为每种类型的请求启用 Cors

如何在 ASP.NET Core 中为同一接口配置不同的实现