Skip to content

[FromBody]/ JSON binding doesn't use Culture from RequestCultureProviders #9994

@ruchanb

Description

@ruchanb

Describe the bug

Culture derived from RequestCultureProviders is not being implemented in JSON Input binding.
The culture received is being used in query string, application/x-www-form-urlencoded binding but not working with application/json.

To Reproduce

https://github.com/ruchanb/AspNetCoreCultureModelBind
This is standard new project build with addition of

var supportedCultures = new System.Collections.Generic.List<CultureInfo>
            {
                new CultureInfo("en-US"),
                new CultureInfo("es-MX")
            };

            var requestLocalizationOptions = new RequestLocalizationOptions
            {
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures,
            };
            //requestLocalizationOptions.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
            requestLocalizationOptions.RequestCultureProviders.Insert(0, new JsonRequestCultureProvider());
app.UseRequestLocalization(requestLocalizationOptions);

provider

public class JsonRequestCultureProvider : RequestCultureProvider
    {
        public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }
            var header = httpContext.Request.Headers["culture"];
            var culture = header.Count == 0 ? "en-US" : header[0]; // Use the value defined in config files or the default value
            var uiCulture = culture;
            return Task.FromResult(new ProviderCultureResult(culture, uiCulture));
        }
}

Controller

 [Route("api/[controller]/[action]")]
    public class ValuesController : ControllerBase
    {
        [HttpGet]
        public IActionResult Date1(DateTime date)
        {
            return Ok(date);
        }
        [HttpPost]
        public IActionResult Date2(DateModel model)
        {
            return Ok(model);
        }
        [HttpPost]
        public IActionResult Date3([FromBody]DateModel model)
        {
            return Ok(model);
        }
}
public class DateModel
    {
        public DateTime Date { get; set; }
}

Here are some cURL commands to run when we start the application

curl http://localhost:20991/api/values/date1?date=5/15/2019
curl http://localhost:20991/api/values/date1?date=15/5/2019 -H "culture: es-MX"
curl http://localhost:20991/api/values/date2 -X POST -d "Date=5/15/2019"
curl http://localhost:20991/api/values/date2 -X POST -d "Date=15/5/2019" -H "culture: es-MX"
curl http://localhost:20991/api/values/date3 -X POST -d "{\"Date\":\"5\/15\/2019\"}" -H "Content-Type: application/json"

curl http://localhost:20991/api/values/date3 -X POST -d "{\"Date\":\"15\/5\/2019\"}" -H "culture: es-MX" -H "Content-Type: application/json"

Expected behavior

The expected behavior is to return date in ISO format, with 5 as Month, 15 as Day and 2019 as Year.

All the commands pass except the last one with application/json content-type and es-MX as culture. Here it takes the input as invalid.

Additional context

I am running the project on asp.net core 2.2 visual studio 2017. Issue is replicated also on 2.1 and 1.1 versions as I have checked.

I am aware this could, not be a bug, if so please provide information on how can I implement this behavior.
Related SO question: https://stackoverflow.com/questions/55951070/datetime-input-to-deserialize-from-users-culture-instead-of-servers-asp-net-c

Metadata

Metadata

Assignees

No one assigned

    Labels

    affected-fewThis issue impacts only small number of customersarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-model-bindinghelp wantedUp for grabs. We would accept a PR to help resolve this issueseverity-majorThis label is used by an internal tool

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions