ASP.NET MVC model binder parse decimal differently

2019-07-11 00:26发布

问题:

The server is hosting Asp.net mvc3 app and the Browser culture is set to da (Danish)

GET request url: /get?d=1.1  (note that the decimal separator is .)
return: da;1,1   (note that the decimal separator is ,)

GET request url: /get?d=1,1  (the decimal separator is ,)
return: Exception Details: System.ArgumentException: The parameters dictionary contains a null entry for parameter 'd' of non-nullable type 'System.Decimal' for method 'System.Web.Mvc.ContentResult get(System.Decimal)' in 'Intranet.Controllers.OrderController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

But given the same input to a post request, the results are exactly opposite.

POST request url: /get2    (form data d=1.1)
return: Exception ...

POST request url: /get2    (form data d=1,1)
return: da;1,1

I suppose the POST request is working as expected. But why does the GET request behave differently? How does the default model binder work in this case.

回答1:

When you send the data through a post, the locales take effect. When you send the data through a GET, it always uses the invariant locale.

It seems this is done because you could copy and paste an URL, and send it to someone in another country. If the language of the browser was considered when a parameter is included in the URL (GET) the URL would break (it's more obvious if you think about date formats than decimal separators).

Among other places, it's mentioned here by a member of the .Net team: http://forums.asp.net/t/1461209.aspx/1?Nullable+DateTime+Action+Parameters+Parsed+in+US+format+irrespective+of+locale+