【问题标题】:Some Required fields not working on ViewModel MVC3一些必填字段不适用于 ViewModel MVC3
【发布时间】:2012-10-16 15:24:40
【问题描述】:

控制器动作:

 [AjaxRequestOnly, HttpPost, Authorize]
    public ActionResult AddCreditCard(CustomerCreditCardModelView cc) {
        if (!ModelState.IsValid) {
            Response.StatusCode = 400;
            return Content(Newtonsoft.Json.JsonConvert.SerializeObject(ModelState.Values.SelectMany(v => v.Errors).Select(e=>e.ErrorMessage)));
        }
        // .... do something ...        
    }

模型视图:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using CheckoutVC.CheckoutServiceReference;
using Newtonsoft.Json;

public class CustomerCreditCardModelView {

    [Display(Name = "Número")]
    [Required(ErrorMessage = "El Número es requerido")]
    [StringLength(20, MinimumLength = 12, ErrorMessage = "El número parece ser incorrecto")]
    [JsonIgnore, ScriptIgnore]
    public string CardNumber { get; set; }

    [Display(Name = "Código de seguridad")]
    [Required(ErrorMessage = "El Código de seguridad es requerido")]
    public string CardSecurityCode { get; set; }

    [Display(Name = "Nombre en la tarjeta")]
    [Required(ErrorMessage = "El Nombre en la tarjeta es requerido")]
    public string NameOnCard { get; set; }

    [Display(Name = "Dirección de cobro")]
    [Required(ErrorMessage = "La Dirección de cobro es requerida")]
    public string BillingAddress { get; set; }

    [Display(Name = "Mes de vencimiento")]
    [Required(ErrorMessage = "El Mes de vencimiento es requerido")]
    public int ExpirationMonth { get; set; }

    [Display(Name = "Año de vencimiento")]
    [Required(ErrorMessage = "El Año de vencimiento es requerido")]
    public int ExpirationYear { get; set; }

    [Display(Name = "Documento")]
    [Required(ErrorMessage = "El documento es requerido")]
    public string Document { get; set; }

    [Display(Name = "Tipo de tarjeta")]
    public int IdCreditCard { get; set; }

    public int IdCustomer { get; set; }
    public bool IsDeleted { get; set; }
    public int IdCustomerCreditCard { get; set; }
    public CustomerCreditCardModelView() {

    }

请求负载:

{"idCreditCard":1,"nameOnCard":"fdsa","billingAddress":"fdsa"}

请求响应:

["El Número es requerido","El Código de seguridad es requerido","El documento es requerido"]

如您所见,除了 int ExpirationMonth 和 int ExpirationYear 应该返回验证错误(必需)之外,一切都运行良好,但它们没有。

其实modelstate只有6个key....

是什么导致了这种行为?我想将 expireMonth 和 expirationYear 考虑到 [Required] DataAnnotation 属性。

这里肯定发生了同样的事情:mvc model validation required not working on all fields

编辑:阅读有关该问题的 cmets 发现问题出在使用上,而不是我的情况。我包括了使用部分。

【问题讨论】:

  • 当您尝试验证时,屏幕上是否隐藏了某些内容?
  • 服务器端验证不起作用。
  • 如果我在请求有效负载中添加类似 expireMonth: null 的内容,则数据注释有效。这太疯狂了。

标签: c# asp.net-mvc validation data-annotations


【解决方案1】:

这可能是因为ExpirationMonthExpirationYear 属性是整数值。 Integer 是值类型,因此不能为 null,默认值为 0,从 RequiredAttribute 的角度来看是正确的。

您可以做的是将类型从int 更改为int?,使其可以为空。

Nullable Types

您的视图模型:

public class CustomerCreditCardModelView {

    [Display(Name = "Número")]
    [Required(ErrorMessage = "El Número es requerido")]
    [StringLength(20, MinimumLength = 12, ErrorMessage = "El número parece ser incorrecto")]
    [JsonIgnore, ScriptIgnore]
    public string CardNumber { get; set; }

    [Display(Name = "Código de seguridad")]
    [Required(ErrorMessage = "El Código de seguridad es requerido")]
    public string CardSecurityCode { get; set; }

    [Display(Name = "Nombre en la tarjeta")]
    [Required(ErrorMessage = "El Nombre en la tarjeta es requerido")]
    public string NameOnCard { get; set; }

    [Display(Name = "Dirección de cobro")]
    [Required(ErrorMessage = "La Dirección de cobro es requerida")]
    public string BillingAddress { get; set; }

    [Display(Name = "Mes de vencimiento")]
    [Required(ErrorMessage = "El Mes de vencimiento es requerido")]
    public int? ExpirationMonth { get; set; }

    [Display(Name = "Año de vencimiento")]
    [Required(ErrorMessage = "El Año de vencimiento es requerido")]
    public int? ExpirationYear { get; set; }

    [Display(Name = "Documento")]
    [Required(ErrorMessage = "El documento es requerido")]
    public string Document { get; set; }

    [Display(Name = "Tipo de tarjeta")]
    public int IdCreditCard { get; set; }

    public int IdCustomer { get; set; }
    public bool IsDeleted { get; set; }
    public int IdCustomerCreditCard { get; set; }
    public CustomerCreditCardModelView() {

    }
}

另一种方法是使验证更加严格,从名称ExpirationMonthExpirationYear 我认为RangeAttribute 适合您。

【讨论】:

  • 它们是 int 是有原因的,如果我不发送请求,我希望得到无效的验证。这不是问题。实际上问题在于服务器端验证接受输入,即使这些值没有定义。
  • 这就是问题所在。 0 是有效整数。模型验证用于验证模型。它与请求无关,这是不同的责任。诠释?当 ModelBinder 根据请求创建对象时(如果请求不包含该属性的任何信息),(即 Nullable)将为 null。
  • 好的,所以服务器端对所需 int 的验证甚至不检查模型是否接收到 int 值。因此,您可以使用提琴手轻松通过模型验证......听起来有点糟糕的设计。
  • 好吧试验了一下,我发现了它是如何工作的,看起来模型绑定器在针对请求中的任何数据注释进行测试之前做了一个新对象(当然是默认值)。我明白为什么会这样,但对我来说仍然不太好,而且有点反直觉。仍然认为你不能为我的眼睛做一个巨大的安全漏洞所需的数据注释是很糟糕的。
  • 爱你!您的回答在这里解决了我的“错误”:stackoverflow.com/questions/33710919/…
猜你喜欢
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 2014-03-17
  • 2016-08-16
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多