Compound View Model object causing a remote validation failure

I used a template of complex presentation models for several forms in this project. It works very well.

In this case, I have a VendorAddress view model. I use addresses (addresses) in several places in this project, so I created an address view model object that I can reuse. Then I decided that I wanted to do a very thorough check of state codes and postal codes, so I decided that I would try to use remote check and check the status and postal code using a stored set of tables in the database.

The problem is that I am not getting the value back to the remote action methods for the fields I am asking for (in this case, State and PostalCode). I believe that this is because the name used by the MVC framework for compound or subtypes for the id (s) for inputs, in this case creates names like "Address_Line1" and "Address_State" and "Address_PostalCode".

Ultimately, I have a question: is there a way to disconnect the preselected "Address_" from the base view model object so that the MVC structure can put it in the object after the form message?

public class AddressViewModel { [ScaffoldColumn(false)] public int AddressId { get; set; } [Required(ErrorMessage = "Please enter the first address line")] public string Line1 { get; set; } public string Line2 { get; set; } public string Line3 { get; set; } [Required(ErrorMessage = "Please enter a city name")] public string City { get; set; } [Required(ErrorMessage = "Please enter a state 2 letter code")] [StringLength(2)] [Remote("CheckState", "Validation", AdditionalFields = "PostalCode")] public string State { get; set; } [Required(ErrorMessage = "Please enter a postal code")] [Remote("CheckZip", "Validation", AdditionalFields = "State")] [Display(Name = "Zip / Postal Code")] public string PostalCode { get; set; } public string Country { get; set; } } public class VendorContactViewModel { public int VedorContactId { get; set; } public int ContactVendorId { get; set; } public int ContactId { get; set; } [Required] [Display(Name = "Contact Type")] public byte ContactTypeId { get; set; } public string ContactType { get; set; } [Required] [Display(Name = "Contact Info")] public string ContactInfo { get; set; } [Display(Name = "Contact Label")] public string ContactLabel { get; set; } public IEnumerable<SelectListItem> ContactTypes { get; set; } } 

then in the form after rendering it looks like this:

  <input type="text" value="" size="2" name="Address.State" maxlength="2" id="Address_State" data-val-required="Please enter a state 2 letter code" data-val-remote-url="/Validation/CheckState" data-val-remote-additionalfields="*.State,*.PostalCode" data-val-remote="&amp;#39;State&amp;#39; is invalid." data-val-length-max="2" data-val-length="The field State must be a string with a maximum length of 2." data-val="true" class="input-validation-error"> 

I receive a remote call, but there is nothing in the "Status" and "Postal code" parameters, so unobtrusive procedures are started, but I think that he does not know where to look for data, even if I have something in the superimposed fields. As you can see in the rendered code id = "Address_State" and data-val-remote-Additionalfields = ". State, .PostalCode"

Thank you for your time and efforts,

Irva

+7
source share
2 answers

Try specifying a prefix to help the model’s middleware properly bind the Address.PostalCode and Address.State request values ​​to their respective action parameters:

 public ActionResult CheckState( [Bind(Prefix = "Address.State")]string State, [Bind(Prefix = "Address.PostalCode")]string PostalCode ) { ... } 
+10
source

I ran into this problem, but I needed to use the same ViewModel in several views with different prefixes. I ended up writing javascript that changed the jQuery validation rules, so they did not include the prefix:

 $('[data-val-remote]').each(function () { // overwrite the remote rule data so that it sends non-prefixed property name to the server var remoteRule = $(this).rules().remote; var newData = {}; var keys = Object.keys(remoteRule.data); for (var i = 0; i < keys.length; i++) { var nonPrefixedPropertyName = $(keys[i].split('.')).last()[0]; newData[nonPrefixedPropertyName] = remoteRule.data[keys[i]]; } remoteRule.data = newData; }); 
0
source

All Articles