Validation 导致远程验证失败的复合视图模型对象

Validation 导致远程验证失败的复合视图模型对象,validation,asp.net-mvc-3,Validation,Asp.net Mvc 3,我在这个项目中的一些表单中使用了复合视图模型的模式。它工作得很好 在本例中,我有一个VendorAddress视图模型。我在这个项目中的一些地方使用了Address(es),所以我创建了可以重用的视图和Address模型对象。然后我决定我要对州代码和邮政编码进行彻底检查,所以我决定尝试使用远程验证,并针对数据库中存储的一组表检查州代码和邮政编码 问题是我没有为我请求的字段(在本例中为State和PostalCode)将值返回到远程操作方法。我相信这是因为MVC框架为输入的id的复合或子类型命名为

我在这个项目中的一些表单中使用了复合视图模型的模式。它工作得很好

在本例中,我有一个VendorAddress视图模型。我在这个项目中的一些地方使用了Address(es),所以我创建了可以重用的视图和Address模型对象。然后我决定我要对州代码和邮政编码进行彻底检查,所以我决定尝试使用远程验证,并针对数据库中存储的一组表检查州代码和邮政编码

问题是我没有为我请求的字段(在本例中为State和PostalCode)将值返回到远程操作方法。我相信这是因为MVC框架为输入的id的复合或子类型命名为mangleing,在这种情况下,它将命名为“Address\u Line1”、“Address\u State”和“Address\u PostalCode”

最终我的问题是,是否有一种方法可以关闭基本视图模型对象中预先挂起的“Address_”,使MVC框架可以在表单的后面将其放入对象中

    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; }
}
公共类AddressViewModel
{
[脚手架立柱(假)]
public int AddressId{get;set;}
[必需(ErrorMessage=“请输入第一个地址行”)]
公共字符串Line1{get;set;}
公共字符串第2行{get;set;}
公共字符串第3行{get;set;}
[必需(ErrorMessage=“请输入城市名称”)]
公共字符串City{get;set;}
[必需(ErrorMessage=“请输入状态2字母代码”)]
[第(2)款]
[远程(“检查状态”、“验证”,AdditionalFields=“PostalCode”)]
公共字符串状态{get;set;}
[必需(ErrorMessage=“请输入邮政编码”)]
[远程(“CheckZip”,“Validation”,AdditionalFields=“State”)]
[显示(Name=“邮政编码”)]
公共字符串PostalCode{get;set;}
公共字符串国家{get;set;}
}
公共类VendorContactViewModel
{
public int VedorContactId{get;set;}
public int ContactVendorId{get;set;}
public int ContactId{get;set;}
[必需]
[显示(Name=“联系人类型”)]
公共字节ContactTypeId{get;set;}
公共字符串ContactType{get;set;}
[必需]
[显示(Name=“联系人信息”)]
公共字符串ContactInfo{get;set;}
[显示(姓名=“联系人标签”)]
公共字符串ContactLabel{get;set;}
公共IEnumerable联系人类型{get;set;}
}
然后在渲染后的表单中,它如下所示:

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

我收到了远程调用,但参数“State”和“PostalCode”中没有任何内容,因此启动了不引人注目的例程,但我认为它不知道在哪里查找数据,即使我在标注的字段中键入了一些内容。正如您在呈现的代码中看到的,id=“Address\u State”和data val remote additionalfields=“.State、.PostalCode”

谢谢你的时间和努力


Irv

尝试指定前缀,以帮助模型绑定器将
地址.PostalCode
地址.State
请求值正确绑定到相应的操作参数:

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

我遇到了这个问题,但需要在多个具有不同前缀的视图中使用相同的ViewModel。我最终编写了javascript,修改了jQuery远程验证规则,使其不包含任何前缀:

$('[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;
});
$('[data val remote]')。每个(函数(){
//覆盖远程规则数据,以便它将不带前缀的属性名称发送到服务器
var remoteRule=$(this).rules().remote;
var newData={};
var keys=Object.keys(remoteRule.data);
对于(变量i=0;i
谢谢Darin,我已经找到了答案,但这基本上是正确的答案。虽然您也确实需要绑定上的属性,比如[bind(Prefix=“Address.State”)]字符串状态……谢谢Darin。。你太棒了……)