Controller Action:
[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 ...
}
ModelView:
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() {
}
Request Payload:
{"idCreditCard":1,"nameOnCard":"fdsa","billingAddress":"fdsa"}
Request Response:
["El Número es requerido","El Código de seguridad es requerido","El documento es requerido"]
As you can see, everything works perfectly except that int ExpirationMonth and int ExpirationYear should return a validation error (required) but they doesnt.
Actually, modelstate have only 6 keys….
What can be causing this behaviour? I want to expirationMonth and expirationYear takes into consideration the [Required] DataAnnotation attribute.
Pretty sure is the same happening here: mvc model validation required not working on all fields
EDIT: Reading the comments on that question see that the problem was the using, not my case tho. I included the using part.
This is probably because
ExpirationMonthandExpirationYearproperties are integer values. Integer is value type so it cannot be null, the default value will be 0 which is correct from the RequiredAttribute’s point of view.What you can do is to change the type from
inttoint?so it can be null.See Nullable Types.
Your viewmodel:
Another approach is to make the validation more strict, from the names
ExpirationMonthandExpirationYearI think the RangeAttribute is appropriate for you.