Decimal symbol issue in MVC, C#? - 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)

Related

blazorise numeric edit group separating

I'm trying to use blazorise numeric edit group separating attribute. as it is said in it's documentation it should be possible to use it, but as I tried, it's not working.
I would appreciate it if you can help me to use blazorsie components to separate digits define thousands.
for example, when I'm entering value 12345678, it shows 12,345,678
thanks in advance
NumericEdit component does not have a GroupSeparator parameter. The GroupSeparator parameter is on the NumericPicker component:
<NumericPicker #bind-Value="#paymentDocumentCreateCommand.TotalPrice" GroupSeparator="," />
NumericPicker was added in Blazorise version 1.0.0.
NumericPicker vs NumericEdit
Workaround:
You can use the TextEdit component and apply a format when you convert the number to string.
<TextEdit #bind-Text="#TotalCost" />
<p>#_totalCost</p>
#code {
private double _totalCost = 1234567890;
private string TotalCost
{
get
{
return _totalCost.ToString("#,#");
}
set
{
_totalCost = string.IsNullOrEmpty(value) ? 0 : double.Parse(value);
}
}
}
Custom binding formats
You can create a custom input component that does this conversion internally.

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

Converting Number to Specific Culture from 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)

formatting ajax.actionlink text to display

I have a decimal data type in my model and an annotation to format it so it adds commas after 3 digits:
[DisplayFormat(DataFormatString = "{0:#,###0.00}" + " (USD)")]
public decimal PaidAmount { get; set; }
when I have any DisplayFor(m => m.PaidAmount) the formatting displays correctly (1,200.00 USD). However, in Ajax.ActionLink the first argument takes a string for the text to display so I can't use a lambda expression (m => m.PaidAmount). When I do:
Ajax.ActionLink(Model.PaidAmount.ToString(), //rest of link params)
the formatting doesn't apply to the link text, it shows just a bunch of numbers without commas (1200.00 USD, note there is no comma after the 1)
my guess is that using the capital 'M'odel version of model loses its annotation properties, is there a way to go around this and apply the formatting to the ajax.actionlink?
You can use
#Ajax.ActionLink(string.Format("{0:#,##0.00 USD}", Model.PaidAmount), ...)
Note I think you mean 0:#,##0.00 not 0:#,###0.00 (i.e. 10,200.00 USD, not 1,0200.00 USD)
Data annotations will not work in this case as they are checked in HtmlHelpers and won't affect regular ToString.
You can create an extension method to format your number an call it in your view:
public static class Extensions
{
public static string ToCurrency(this decimal number)
{
return number.ToString("{0:#,###0.00}") + " (USD)";
}
}
In you view: (don't forget to reference the Extensions class either directly in the view or in web.config under views folder)
Ajax.ActionLink(Model.PaidAmount.ToCurrency(), //rest of link params)

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/

Categories