Converting Number to Specific Culture from C# - c#

I have an ASP.NET MVC app. My app has a Razor view that generates some JavaScript. That block of code looks like this:
<script type="text/javascript">
#if (Model == null)
{
var amount = 0;
}
else
{
<text>var amount = #Convert.ToString(Model.DailyAmount.Value);</text>
}
...
</script>
When a user's culture is set to Germany ("de-DE"), the view gets rendered as:
var amount = 0,00;
DailyAmount is a decimal? Notice how the value that gets rendered (0,00) has a comma to represent a decimal. However, I want to always render the value as 0.00 instead. How do I do this?
Thank you!

Specify exact culture for your amount - i.e.:
#Convert.ToString(Model.DailyAmount.Value, CultureInfo.InvariantCulture)

Related

Razor Format Decimal? value in view

I'm currently working on an ASP.NET MVC 4.6 application. I try to format a Decimal? property to a correct string format.
My property looks like this:
public decimal? Amount{ get; set; }
The data from the database looks like this: 10000,99
My desired outpout should actually be: € 10.001
no decimal values and no , (comma) is allowed.
In my Razor view I currently use:
#String.Format("{0:N0}", Model.Amount)
This works almost fine, though I get this result: € 10 000 which is wrong unfortunately.
Do you know hot to solve this in ASP.NET MVC Razor? Desired output € 10.001
Thank you!!!!
String.Format() has an overload which accepts IFormatProvider. Simply pass the desired number format there:
var c = new System.Globalization.CultureInfo(""); // create InvariantCulture
c.NumberFormat.NumberGroupSeparator = ".";
var s = String.Format(c, "{0:N0}", 10000.99);

Decimal symbol issue in MVC, C#?

I'm using MVC 5.0
I set the culture in config:
<system.web>
<globalization uiCulture="fa-IR" culture="fa-IR" />
</system.web>
I have a model as the following:
public class MyModel
{
[DisplayName("NbatPersent")]
[Range(0, 100)]
public double NbatPersent{ get; set; }
}
MVC shows the NbatPersent value in View like 22/5 and when I wanna submit form the form validator alert me The field NbatPersent must be a number.. It can't convert 22/5 to 22.5
It will be OK if I enter 22.5 but if the property has a value it convert . to /
How can I convert all numeric properties' culture to en-US to show value like 22.5 not like 22/5.
Edit:
I'm using #Html.TextBoxFor to show the decimal property because of user should be change it.
You are getting a client side validation error as a result of jquery.validate.js which uses the following to validate the value (which only allows the . character as the decimal separator.
number: function(value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
},
You can use the jquery.validate.globalize.js plugin (refer this article for more detail) or you can add your own script to modify the validator, for example (include this after jquery.validate.js)
$.validator.methods.number = function (value, element) {
return this.optional(element) || $.isNumeric($(element).val().replace('/', '.'));
}
Try to set the view format explicitly
#Html.DisplayFor(x => string.Format("{0:0.00}", x.NbatPersent));
else you can write a custom editor template for the double type (~/Views/Shared/EditorTemplates/double.cshtml):
#model double?
#Html.TextBox("", Model.HasValue ? Model.Value.ToString("#,##0.000#") : "")
and then in your view:
#Html.EditorFor(x => x.NbatPersent)

Getting null datetime value from view to controller when i change CultureInfo

net mvc, i have a controller which gets a datetime parameter from view using jquery datepicker and then i pass
the value to the controller using json ,
it all works fine, except when i change language cultureInfo to German in my case, the value of datetime parameter is always null.
This is the controller:
public JsonResult GetDetails(DateTime? from, DateTime? to)
{
//Do something..
}
The model:
public class UsagesModel
{
public DateTime From
{
get;
set;
}
public DateTime To
{
get;
set;
}
}
The view in which data gets chosen and then pass to controller:
<input type="text" id="from" value="#Model.From.ToString("dd/MM/yyyy")" class="datepicker" />
<input type="text" id="to" value="#Model.To.ToString("dd/MM/yyyy")" class="datepicker" />
$("#filter").click(function (e) {
fromdate = $("#from").val();
todate = $("#to").val();
$.getJSON('#Response.ApplyAppPathModifier(#Url.Action("GetDetails"))', {
'from': StringToJSONDate(fromdate),
'to': StringToJSONDate(todate)
}, function (groupusages) {
.....Do Something....
}).error(function (xhr, textStatus, errorThrown) {
//document.location.href = "/Login";
});
});
//function for parsing data to json
function StringToJSONDate(stringDate) {
var dateParts = stringDate.split("/");
var date = new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
return date.toJSON();
}
What can i do, where is the problem because it works fine in english and french culture. Please help me!
One thing you could do is to change your method signature to do something like this. You could spend a lot of time working on getting the right format for your mvc app for different cultures.
public JsonResult GetDetails(string from, string to)
{
var fromDate = DateTime.Parse(from);
var toDate = DateTime.Parse(to);
//Do something..
}
As Khan mentioned in his comment, you could make this a DateTime.ParseExact() so that you don't run into other culture issues.
https://msdn.microsoft.com/en-us/library/System.DateTime.ParseExact(v=vs.110).aspx
I do not know the exact change, but it may be because of a difference in the date/time format that Germany uses versus English and French speaking locations. I would try adding in a few alerts from the javascript to see at various points that you have a value there and then see where it gets screwy. I suspect the value still comes through but is not happy with the date formatting, should be a quick fix with some .split("/") and .join("/") function calls and addressing the index of the array

Decimal numbers in ASP.NET MVC 5 app

I have a problem with decimal numbers.
If I use .(dot) instead of ,(comma) in the textbox it comes null in controller.
I know its a language issue because in spanish we use comma instead of dot for decimals but I need to use dot.
It is possible to change this?
It is strange because in controller I have to use .(dot) for decimals i.e:
I can do float x = 3.14 but I can not do float x = 3,14 so I do not understand this... In some cases I have to use dot... In others I have to use comma...
This is my code:
In model:
[Display(Name = "Total")]
public double Total { get; set; }
In view:
#Html.EditorFor(model => model.Total, new { id = "Total", htmlAttributes = new {#class = "form-control" } })
In controller:
public ActionResult Create([Bind(Include = "ID,Codigo,Fecha,Trabajo,Notas,BaseImponible,Iva,Total,Verificado,FormaDePagoID,ClienteID")] Presupuesto presupuesto)
{
Thanks everybody. I found this code from Phil Haack that works pretty well.
Create a class in any folder of your project
public class ModelBinder
{
public class DecimalModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
object result = null;
// Don't do this here!
// It might do bindingContext.ModelState.AddModelError
// and there is no RemoveModelError!
//
// result = base.BindModel(controllerContext, bindingContext);
string modelName = bindingContext.ModelName;
string attemptedValue =
bindingContext.ValueProvider.GetValue(modelName).AttemptedValue;
// Depending on CultureInfo, the NumberDecimalSeparator can be "," or "."
// Both "." and "," should be accepted, but aren't.
string wantedSeperator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;
string alternateSeperator = (wantedSeperator == "," ? "." : ",");
if (attemptedValue.IndexOf(wantedSeperator) == -1
&& attemptedValue.IndexOf(alternateSeperator) != -1)
{
attemptedValue =
attemptedValue.Replace(alternateSeperator, wantedSeperator);
}
try
{
if (bindingContext.ModelMetadata.IsNullableValueType
&& string.IsNullOrWhiteSpace(attemptedValue))
{
return null;
}
result = decimal.Parse(attemptedValue, NumberStyles.Any);
}
catch (FormatException e)
{
bindingContext.ModelState.AddModelError(modelName, e);
}
return result;
}
}
}
Add this to Application_Start() method in Global.asax
ModelBinders.Binders.Add(typeof(decimal), new ModelBinder.DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new ModelBinder.DecimalModelBinder());
Now use decimal type instead of float or double and everything will go fine !!
Thank you mates see you around !.
Your controller uses C#. The language specific states that . is the decimal separator. Period. It's not language specific, that's just it.
Your database or UI (which uses the server's language settings) might use another decimal separator than the default (US) language setting C# uses. That's why you have to use , as separator there.
you would need to use a custom model binder.
See this blog post http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx/
If you want your comma(,) separated decimal input in UI as per UI culture, to be converted to dot(.) to bind to C# decimal number, you can go for Asp.Net MVC's custom model binder, where take the comma separated decimal string and replace the comma with a dot and then assign to the C# decimal property.
The advantage is, its reusable across the application, where you might be having recurring scenarios for decimal conversions.
Hope following links could help you:
ASP.Net MVC Custom Model Binding explanation
http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx
http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx/

custom unobtrusive date validators for dates

Maybe it's just the way my mind works, but I have a very hard time understanding how you're supposed to do custom unobtrusive validators. The C# part is easy enough, but the jqueryui adapters are where i get lost.
I've been trying to make a validator that requires a date to be a certain amount of time in the past. I use this for age validation, to make sure someone has entered a date that is 18 years in the past.
I finally decided to just make it a remote validator, that way the validation uses the same code both client and server side. Still, i'd be interested in the jquery to make this work.
I wish the Data Annotation Extensions had date functions.
You can find a lot of information in Brad Wilson's blog article about unobtrusive validation with asp.net mvc, including creating custom validators.
Based on the following html (should be the output of the TextBox helper)
<input type="text" name="Age"
data-val="true"
data-val-required="This field is required"
data-val-minage="You should be 18 years or older, go get your parents!"
data-val-minage-value="18" />
<input type="submit"/>
You can add the following javascript to get things validated on the client side:
// Extend date with age calculator
Date.prototype.age = function (at) {
var value = new Date(this.getTime());
var age = at.getFullYear() - value.getFullYear();
value = value.setFullYear(at.getFullYear());
if (at < value) --age;
return age;
};
// Add adapter for minimum age validator. Wrap in closure
(function ($) {
$.validator.unobtrusive.adapters.addSingleVal("minage", "value");
} (jQuery));
// Add client side minimum age validator
$.validator.methods.minage = function (value, element, params) {
// If no value is specified, don't validate
if (value.length == 0) {
return true;
}
var dob = new Date(Date.parse(value));
if (dob.age(new Date()) < params || dob == 'Invalid Date') {
return false;
}
return true;
};
Credits for the age calculator are due to Dave
The one thing missing here is globalization, but I figured it was out of the question's scope. btw very easy to implement using the jquery Globalize plugin
Hope this helps

Categories