ASP.NET MVC3 双重验证(逗号、点、空)

Posted

技术标签:

【中文标题】ASP.NET MVC3 双重验证(逗号、点、空)【英文标题】:ASP.NET MVC3 double validation (comma, point, null) 【发布时间】:2011-11-09 20:34:31 【问题描述】:

我的控制器如下所示:

 public class PortefeuilleController : Controller
    
            public ActionResult Create()
            
                return View(new PortefeuilleViewModelSaldo = 0.0);
            
    

我的创建视图如下所示:

@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>

我的 PortefeuilleViewModel 看起来像这样:

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; 

我的问题在于“Saldo”字段。我想验证如下:

将该字段留空应该是有效的(因为我的代码隐藏会将“”更改为“0.0”并将该值保存在数据库中)。但是,例如,'19,99' 和 '19.99' 也应该被传递为有效。其余全部无效。

我真的不知道如何才能做到这一点。我已经找到这篇文章了:http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx 但这根本没有解决我的问题(第二部分)......

任何帮助将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

好的,所以您在 2 个级别激活了验证:服务器端和客户端。让我们首先处理服务器端验证问题。

使用金钱时的第一件事(我认为Saldo 字段代表的是使用小数,而不是双精度数)。所以第一个变化是:

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

好的,现在让我们稍微调整一下 Haacked 模型绑定器以适应您的情况(接受 ., 作为小数分隔符以及空值)

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;
    

当然会在Application_Start注册:

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

在这个阶段,我们已经解决了服务器端验证问题。就客户端验证而言,您可以使用 Microsoft 发布的jQuery globalization plugin。 Scott Hanselman 也有blogged 关于它。因此,一旦安装它,您就可以强制客户端文化并覆盖负责执行客户端验证的$.validator.methods.number 方法:

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

【讨论】:

好的,谢谢,那行得通。但只是一个问题:为什么使用小数而不是双精度? @Matthias,始终使用小数表示货币:***.com/questions/1165761/…,除非您想开始失去货币 :-) 双打使用 IEEE 754 存储,而小数存储在 10 进制中。 谢谢。我在测试时才意识到的另一件事:如果用户输入字符串而不是数字,它不会发出警告。是否有类似 [Decimal(ErrorMessage = "Please give a decimal number")] 的注释可以用来验证? @Matthias,这很奇怪。这对我来说可以。当您键入一些字符串时,将调用自定义模型绑定器,并且 Convert.ToDecimal 引发异常,该异常被拦截并显示错误消息。不是发生在你身上吗?模型绑定器没有被调用吗? 添加(如果 ModelState.IsValid)检查我的 HttpPost Edit 方法,它现在可以工作了。但是消息“值 'qsdf' 对 Saldo 无效。”显示。是否可以更改此消息?我的应用程序是荷兰语,所以我所有的错误消息也应该是荷兰语。

以上是关于ASP.NET MVC3 双重验证(逗号、点、空)的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC3 - 自定义验证属性 -> 客户端损坏

IIS7.5 中的 ASP.NET MVC3 401.1 错误

ASP.NET MVC3:ValidationType ModelClientValidationRule

如何在 ASP.NET MVC 5.2.3 和 Katana 中正确设置双重身份验证?

IIS 上的 ASP.NET MVC3 和 Windows Auth 不断重定向到 /Account/Login

Asp.Net MVC3 简单入门详解过滤器Filter