Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP:NET MVC 4根据另一个属性的当前值对属性进行动态验证_C#_Asp.net Mvc_Validation - Fatal编程技术网

C# ASP:NET MVC 4根据另一个属性的当前值对属性进行动态验证

C# ASP:NET MVC 4根据另一个属性的当前值对属性进行动态验证,c#,asp.net-mvc,validation,C#,Asp.net Mvc,Validation,我在寻找一种方法来根据同一模型中另一个属性的当前值动态验证属性时遇到了一个问题。我搜索了很多,没有找到答案或类似的例子 在我的模型中,我有一个邮政编码属性和一个countryID属性。在每个不同国家的DB中,我有一个不同的正则表达式来验证邮政编码。 然后,使用countryID,我可以从DB中获取apropiate regex,以验证相应国家的邮政编码 因此,在我的模型中,根据当前countryID的值,我希望对zip字段进行验证 我尝试创建自定义验证属性“ZipValidation(count

我在寻找一种方法来根据同一模型中另一个属性的当前值动态验证属性时遇到了一个问题。我搜索了很多,没有找到答案或类似的例子

在我的模型中,我有一个邮政编码属性和一个countryID属性。在每个不同国家的DB中,我有一个不同的正则表达式来验证邮政编码。 然后,使用countryID,我可以从DB中获取apropiate regex,以验证相应国家的邮政编码

因此,在我的模型中,根据当前countryID的值,我希望对zip字段进行验证

我尝试创建自定义验证属性“ZipValidation(countryID)”,但在模型中,它不允许将另一个属性的值作为参数:

public class AddressViewModel
{
    ...
    [Display(Name = "Country ID")]
    public Guid? countryID { get; set; }

    [Required]
    //[ZipValidation(countryID)] does not compile because of the countryID
    [Display(Name = "Zip")]
    public string zip { get; set; }

}

知道如何实现这一点吗?

您需要在这里创建自己的验证属性。。。
正如Rodrigo所说,在属性的构造函数中,您将传递验证属性也将使用的属性的名称(在您的案例中为countryID)。然后,您将使用反射获取该属性的值,并知道您可以进行验证。这一切都会很好,即使有一点运气和很多技能,你也可以使它可重用,但是如果你想要客户验证,你需要自己实现它。这是一个很长的故事,我看到您从哪里获得了理解整个过程的适当参考,因此我将向您介绍我从中学到的内容:

这有点低技术,如果您有时间和意愿,您可能应该研究使用验证属性,但为了完整性,这是一个可行的解决办法。在你的行动后:

[HttpPost]
public ActionResult MyAwesomePostAction(AddressViewModel model)
{
    if (!ValidationUtil.IsValidZipCode(model.zip, model.countryID))
    {
        ModelState.AddModelError("zip", "Not a valid zip code for your chosen country.");
    }

    if (ModelState.IsValid)
    {
        ...
    }

    return View(model);
}

我假设某个库将验证存储在控制器之外。这样,在您的操作中就不会有太多无关的代码,如果您需要再次执行此操作,您不必重复验证逻辑。

我最终按照Jonesy的建议使用
[Remote]
验证属性,并在控制器中使用Json和Ajax解决了这个问题。是这样的:

public class AddressViewChannelModel
{
    ....
    [Display(Name = "CountryID")]
    public Guid? countryID  { get; set; }

    [Required]
    [Remote("ValidateZipCode", "Address", AdditionalFields = "countryID")]
    [Display(Name = "Zip")]
    public string zip { get; set; }
}

public class AddressController : Controller
{
  ...
    public JsonResult ValidateZipCode(string zip, string countryID)
    {
        ValidationRequest request = new ValidationRequest();
        request.CountryID = Guid.Parse(countryID);
        request.Zip = zip;

        ValidationResponse response = new ValidationResponse();
        response = _addressApi.ZipValidation(request);

        if(response.IsSuccessful == false)
        {
            return Json("Not a valid zip code for your chosen country!"),  JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    }
}

有一个
[Remote]
验证属性。通常用于在允许用户注册之前检查用户名是否存在。你可以用它来达到这个目的。您可以实现customvalidator,但不传递值,您将传递属性名称,并在验证程序代码中获取属性值并验证邮政编码。下面是Rodrigo建议的方法示例: