Attribute in Dataannotations for Currency

Asked

Viewed 1,767 times

6

I would like to format with Dataannotation currency but standard

in the model:

[Column("cur_mensalidade")]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C0}")]
public decimal? Mensalidade { get; set; }

but does not accept the comma. even in web.config

 <system.web>
    <globalization uiCulture="pt" culture="pt-BR" enableClientBasedCulture="false" />

inserir a descrição da imagem aqui

I have tried creating a regular expression to format

[RegularExpression(@"^\d+(\.|\,)\d{2}$", ErrorMessage = "{0} valor incorreto.")]
  • You refer to the comma referring to "coins"?

  • this. is in a pattern us

3 answers

5

You can implement a ModelBinder for that reason.

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;
    }
}

And in his Global.asax in the Application_Start() just add the DecimalModelBinder:

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

References:

  • got it, but damn it, isn’t there something simpler like a dataannotations? a regular expression?

  • @Dorathoto You can create a new attribute to do this validation, which would almost in the same. This way you create only once and applies to all fields.

  • create this public class class Decimalmodelbinder?

  • @Dorathoto Exactly

  • Error CS1503 Argument 2: cannot Convert from 'WMB.Bibliotecas.Decimalmodelbinder' to 'System.Web.Modelbinding.Imodelbinder' Global.asax.Cs 21|

  • You are using the reference of System.Web.ModelBinding.IModelBinder, and not your project. Modify the using ... that will work. Remembering that this is for the server, if you want to modify the validation in client also, you should see the other answer too.

Show 1 more comment

1


According to the image, who is validating the input is the browser, and not your app. See and it did not create a <input type="number" />. Because if it is, it is out of your control to format, as it will depend on the culture of the browser, and maybe Windows.

In this case, you will have to manually create the HTML input field, such as <input type="text" /> and then format it in another way - javascript or backend, as you prefer.

I’ve used the jQuery Mkoneymask. A lib jQuery made by a brazuca. Gives a bizú and see if it solves your need.

  • if I set the decimal pattern how to make it not change to type=number

  • @Dorathoto, Na View, just don’t use Html Helper.

  • 1

    Thiago, @Dorathoto just remembering that you can overwrite the Html Helper with what you want, for example: @Html.TextBoxFor(model => model.Question, new {@class="form-control", @data_val="false", @type="password"}). Example

1

This validation should be done via jquery. Create a jquery.validade.ptbr.js file

$.validator.methods.range = function (value, element, param) {
var globalizedValue = value.replace(",", ".");
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);}$.validator.methods.number = function (value, element) { return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);}

And put it on the view. In dataannotation, as globalization is already set to en-br not need to put all this information, I only leave as decimal? and it works.

But in your case, the problem is the validation in the client does not even enter the controller. That’s why you have to solve the javascript.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.