web-dev-qa-db-ja.com

Asp.Net Coreで日付バインディングのカルチャを設定する方法は?

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を送信しています。

デバッグ中にコントローラーで送信されたビューモデルを見ると、英国形式で送信された場合、日付はnullですが、米国形式を使用した場合は問題ありません。つまり、6/22/2017nullを提供しますが、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コアバインダーに指示するにはどうすればよいですか?

追伸ターゲットフレームワーク.NetCoreApp 1.1の* .csprojプロジェクトファイルを使用してVS2017にいます

11
trailmax

いくつかのこと。そのようなミドルウェアに新しい設定オブジェクトをプッシュできるかどうかはわかりません(おそらく可能です)が、ほとんどの場合、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();
}

第二に。ミドルウェアの順序は非常に重要です。 UseMvcの前にUseRequestLocalizationへの呼び出しが発生することを確認してください。実際には、具体的な理由がない限り、おそらくパイプラインの最初のものでなければなりません。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

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

最後に、パイプラインからすべてのプロバイダーを削除してみてください(そのうちの1つはCookieプロバイダーです。このCookieを使用する理由を推測することはできませんが、試してみましょう)。

Configureメソッドで、RequestCultureProvidersリストのclearを呼び出します。これにより、文化を設定するものが他にないことが保証されます。

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/

18
MindingData

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)
    }
11
Johann Medina