Reputation: 17176
I have Simple model with one decimal property:
public class Model {
public decimal Quantity { get;set; }
}
In my view I have:
@Html.TextBoxFor(m => m.Quantity)
@Html.ValidationMessageFor(m => m.Quantity)
The thing is that when I try to post value with decimal part (like 1.5, 2.5 etc.) I get validation errors on client or server sides depending which NumberDecimalSeparator
I use. If I post 1,5
I get client side validation error (the data-val-number one) or if I post 1.5
I get server side model validation error - "The value '1.5' is not valid for Quantity."
. I tried to set NumberDecimalSeparator
manually on Application_Start()
in Global.asax but it didn't help.
var currentCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
currentCulture.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentCulture;
When I manually added some values to the database and tried to edit them, the value in TextBox is displayed with dot "."
, but when I try to save another value with the dot I get server side validation error. What could be the reasons? Why didn't manual culture info update work?
// EDITS:
My approach with changing currentCulture.NumberFormat.NumberDecimalSeparator
works but only if I do it each time on Application_BeginRequest()
:
protected override void Application_BeginRequest(object sender, System.EventArgs e)
{
var currentCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
currentCulture.NumberFormat.NumberDecimalSeparator = ".";
currentCulture.NumberFormat.NumberGroupSeparator = " ";
currentCulture.NumberFormat.CurrencyDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentCulture;
base.Application_BeginRequest(sender, e);
}
Why doesn't it work on application start?
Upvotes: 3
Views: 2614
Reputation: 3055
There is an excellent blogpost about this issue. I answered this already to a similar question.
The approach I used is to extend the jQuery validator. It is based on this blogpost. I setted the culture in the metadata to BE-nl. Since this is a pure Dutch website, I don't do any checks further on.
$(function () { // Look in metatag what culture we want // and set this as culture for the client side. var data = $("meta[name='accept-language']").attr("content"); Globalize.culture(data.toString()); // Don't validate on keyup event because it will mess up // the cursor when replacing values in a textbox. $('form').each(function () { var validator = $(this).data('validator'); if (validator) { validator.settings.onkeyup = false; } }); // Belgianize/sanitize the numbers inserted // 1 000 000 => 1000000 // 1.00 => 1,00 $.validator.methods.number = function (value, element) { var s = value.replace(/\ /g, '').split('.').join(','); if (s.split(',').length < 3) { var number = Globalize.parseFloat(s); if (!isNaN(number)) { $(element).val(s); return this.optional(element) || true; } } return this.optional(element) || false; }; });
I think I used this jQuery library for the globalization
Upvotes: 1
Reputation: 2786
I think it's logical that it's not working in Application_Start
because you set culture per thread.
You can set culture globally in your web.config:
<configuration>
<system.web>
<globalization uiCulture="en-GB" culture="en-GB" />
</system.web>
</configuration>
But if you want (as in your example) to have Russian culture but with different decimal separator, then I think Application_BeginRequest()
might be a good candidate. According to documentation:
Occurs as the first event in the HTTP pipeline chain of execution when ASP.NET responds to a request.
But you need to be careful, because this event is fired on literally every request.
I solved the similar problem not so long ago. In my case user had a possibility to switch between cultures. So every user culture was saved in database and because of that we used Initialize
method of controller instead of Application_BeginRequest()
. Then we set all the rules for client validation based on current thread culture.
I think such functionality can be also moved to filter like in this answer.
Upvotes: 3