我是ASP.NET MVC的新手,并尝试研究如何验证AlphaViewModel
类型的视图模型,它是Create
控制器方法的参数。
视图模型如下。
public class AlphaViewModel
{
[HiddenInput]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
bool HasBeta { get; set; }
public BetaViewModel Beta { get; set; } = new BetaViewModel(); // Always initialize otherwise null exception when trying to set its values.
}
public class BetaViewModel
{
[HiddenInput]
public string Id { get; set; }
[Required]
public string Location { get; set; }
[Required]
public string Area { get; set; }
}
我想通过相同的UI使用相同的Save按钮设置上面的所有属性。
但是,Beta
属性在AlphaViewModel
中是可选的,因此它可以为null。如果Beta
属性不为null,则其所有属性(Location
,Area
)都是必需的。
在用户界面中,我可以设置一个复选框,将HasBeta
设置为false,然后不显示BetaViewModel
的字段。但是,在这种情况下,ASP.NET-MVC的验证仍在解决,Location
和Action
字段在UI中收到警告消息,表明它们尚未设置。
一种选择是关闭BetaViewModel
属性的验证,例如在ModelState
为alphaViewModel.Beta
时为BetaViewModel
,但这依赖于将字段名称作为字符串传递。
当alphaViewModel.Beta
为空时,是否有其他方法可以阻止验证curl https://install.meteor.com/ | sh
字段?
答案 0 :(得分:2)
您需要先从= new BetaViewModel();
媒体资源中删除Beta
。如果请求包含模型的任何名称/值对,DefaultModelBinder
将在POST方法中初始化AlphaViewModel
。
由于BetaViewModel
,它会初始化= new BetaViewModel()
。由于它不是null
,因此Location
和Area
属性会触发验证,ModelState
无效。
但是,您的实施还存在其他问题。假设用户检查HasBeta
属性并开始输入Location
的值,然后实现他们的错误并取消选中该复选框。由于表单控件是隐藏的,因此您不会收到客户端验证错误(默认情况下不会验证隐藏的输入),但现在会为Beta.Location
发送名称/值对。这反过来会初始化BetaViewModel
,因为尚未为Area
输入值,ModelState
无效。假设您在这种情况下返回视图,用户不知道发生了什么,因为错误消息也是隐藏的(他们只是一直按下提交按钮,直到他们沮丧地放弃)。
如果未选中该复选框,您可以在提交之前添加一个脚本来禁用BetaViewModel
输入或确保它们具有null
值。
另一种选择是使用条件验证属性,例如foolproof [RequiredIf]
。然后使用包含所有属性的单个模型
public class AlphaViewModel
{
[HiddenInput]
public int Id { get; set; }
....
bool HasBeta { get; set; }
// Include properties from BetaViewModel
[HiddenInput]
[RequiredIf("HasBeta ", true)]
public string Id { get; set; }
[RequiredIf("HasBeta ", true, ErrorMessage = "...")]
public string Location { get; set; }
[RequiredIf("HasBeta ", true, ErrorMessage = "...")]
public string Area { get; set; }
}