Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

My controller looks like this:

 public class PortefeuilleController : Controller
    {
            public ActionResult Create()
            {
                return View(new PortefeuilleViewModel{Saldo = 0.0});
            }
    }

My create view looks like this:

@model PortefeuilleViewModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>PortefeuilleViewModel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Naam)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Naam)
            @Html.ValidationMessageFor(model => model.Naam)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Saldo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Saldo)
            @Html.ValidationMessageFor(model => model.Saldo)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

And my PortefeuilleViewModel looks like this:

public class PortefeuilleViewModel
{
    [DisplayName("Naam")]
    [Required(ErrorMessage = "Gelieve een naam in te voeren")]
    public string Naam { get; set; }

    [DisplayName("Saldo")]
    public double Saldo { get; set; }
}

My problem lies with the "Saldo" field. I want to validate it as follows:

Leaving the field empty should be valid (because my code-behind will change "" into "0.0" and save that value in the database). But, for example, both '19,99' and '19.99' should also be passed as being valid. All the rest is invalid.

I don't really know how I can pull this off. I already found this article: http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx But that didn't solve (the second part of) my problem at all...

Any help would be greatly appreciated. Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
294 views
Welcome To Ask or Share your Answers For Others

1 Answer

OK, so you have validation activated at 2 levels: server side and client side. Let's first deal with the server side validation issue.

The first thing when working with money (which is what I suppose the Saldo field represents is to use decimals, not doubles). So the first change would be:

[DisplayName("Saldo")]
public decimal Saldo { get; set; }

OK, now let's adapt a little the Haacked model binder to your situation (accepting . and , as decimal separator as well as empty values)

public class DecimalModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (string.IsNullOrEmpty(valueResult.AttemptedValue))
        {
            return 0m;
        }
        var modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try
        {
            actualValue = Convert.ToDecimal(
                valueResult.AttemptedValue.Replace(",", "."), 
                CultureInfo.InvariantCulture
            );
        }
        catch (FormatException e)
        {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

which of course will be registered in Application_Start:

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

At this stage we have solved the server side validation issue. As far as the client side validation is concerned you could use the jQuery globalization plugin that Microsoft released. Scott Hanselman has also blogged about it. So once you install it you could force the client side culture and override the $.validator.methods.number method which is responsible for performing the client side validation:

$.validator.methods.number = function (value, element) {
    // TODO: return true or false if value is a valid decimal
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...