在控制器中编辑后,ModelState不验证嵌套模型

时间:2015-06-04 15:15:06

标签: c# asp.net-mvc entity-framework

我已经嵌套了像这两样的ViewModels:

public class FirstViewModel
{
    public SecondViewModel SecondViewModel { get; set; }
}

public class SecondViewModel
{
    [Range(1, 12)]
    public int month { get; set; }
}

如果我放month = 13;然后拨打ModelState.IsValid(在控制器中),则验证始终为true

修改

这是控制器:

public ActionResult Create()
{
    return PartialView(new FirstViewModel);    
}

public HttpStatusCodeResult Create (FirstViewModel viewModel){

    viewModel.SecondViewModel = new SecondViewModel();
    viewModel.SecondViewModel.month = 13;

    if (ModelState.IsValid)
    {
        return new HttpStatusCodeResult(200);
    }
    else
    {
        return new HttpStatusCodeResult(304);
    }
}

我正在对问题进行抽象,这些不是真正的变量。

3 个答案:

答案 0 :(得分:3)

您的问题表明您在控制器中“调用ModelState.Validate”。没有这样的方法,所以我假设你的意思是if (ModelState.IsValid)

模型绑定过程的第一步是初始化方法的参数,在您的情况下是FirstViewModel的新实例。然后根据表单数据,路由值,查询字符串值等设置模型的值,并将与模型属性相关的任何验证错误添加到ModelState

随后修改模型中属性的值对ModelState没有影响,因此如果month的初始值有效,则ModelState.IsValid将返回true,而不管设置{{ 1}}

如果您想重新验证模型,则需要使用TryUpdateModel返回viewModel.SecondViewModel.month = 13;,指示更新是否成功

bool

答案 1 :(得分:0)

由于FirstViewModel类的SecondViewModel属性为null,因此不会对其进行验证。尝试向属性添加必需属性:

public class FirstViewModel
{
    [Required]
    public SecondViewModel SecondViewModel { get; set; }
}

public class SecondViewModel
{
    [Range(1, 12)]
    public int month { get; set; }
}

修改

根据您的更新,我同意@StephenMuecke。您无法自己实例化一个类,并期望框架为您验证它。在这种情况下,您正在寻找TryUpdateModel,或者您必须让框架为您实例化该类。您需要在请求中的某处传递SecondViewModel.month = 13,以便查看该操作。

答案 2 :(得分:0)

您可以使用this

随时验证模型
Validator.TryValidateObject().

或仅针对一个属性,请参阅this

Validator.TryValidateProperty()

假设你有课程地址

public class Address
{
    [Required]
    public string Address2 { get; set; }
    [Required]
    public string ZipCode{ get; set; }
}

您可以使用此代码段验证您的对象。所有错误都将出现在“结果”变量中。

var addresse = new Address() { Street = null, ZipCode = null};
var context = new ValidationContext(addresse, null, null);
var results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(addresse, context, results, true);