>我有一个问题,我将两个模型传递到一个视图模型中。在特定视图中,我只想检查两个属性的验证,一个属性来自视图模型中的每个模型。
但是,这两个模型都包含其他属性,每个属性都有自己的数据批注,这意味着在满足所有批注之前,即使它们不在表单上,也不会提交表单。
所以我需要找到一种方法来只检查两个模型中特定属性的验证,但如果它通过验证检查,仍然将整个对象保存到数据库中。
代码示例
模型
public class FirstModel
{
public int Id { get; set; }
[Required]
public string Prop2 { get; set; }
[Required]
public DateTime Prop3 { get; set; }
}
public class SecondModel
{
public int Id { get; set; }
[Required]
public string Prop2 { get; set; }
[Required]
public int Prop3 { get; set; }
}
public class ThirdModel
{
public int Id { get; set; }
[Required]
public FirstModel FirstModel { get; set; }
[Required]
public SecondModel SecondModel { get; set; }
}
查看模型
public class ThirdFormViewModel
{
// maybe I can do something here?
public FirstModel FirstModel { get; set; }
public SecondModel SecondModel { get; set; }
}
控制器后操作
[HttpPost]
public ActionResult CreateThirdModel(ThirdModel newThirdModel)
{
var firstModel = _context.FirstModels.Single(c => c.Id == newThirdModel.Id);
var secondModel = _context.SecondModels.Single(c => c.Id == newThirdModel.SecondModel.Id);
if (!ModelState.IsValid)
{
var viewModel = new ThirdFormViewModel
{
FirstModel = firstModel,
SecondModel = secondModel
};
return View("ThirdModelForm", viewModel);
}
var thirdModel = new ThirdModel
{
FirstModel = firstModel,
SecondModel = secondModel,
};
_context.ThirdModels.Add(thirdModel);
_context.SaveChanges();
return RedirectToAction("Index");
}
视图
@model MyProject.ViewModels.ThirdFormViewModel
@using (Html.BeginForm()
{
<div class="form-group">
@Html.TextBoxFor(m => m.FirstModel.Prop2)
</div>
<div class="form-group">
@Html.TextBoxFor(m => m.SecondModel.Prop3)
</div>
<button type="submit" class="btn btn-primary">Save</button>
}
您可以使用 ModelState.Remove 删除要验证的属性。
由于您的第三个视图模型包含其他两个模型的属性,因此属性名称应该类似于FirstModel.Prop2
,这可以通过ModelState.Values
在调试器中进一步检查
例:
ModelState.Remove("FirstModel.Prop2");
ModelState.Remove("SecondModel.Prop2");
如果是我,我会创建多个视图模型,而不是直接传递对象,以便您可以更好地控制此类场景的操作。我通常尝试为传递的所有数据创建视图模型。似乎您必须映射大量实体,但它可以防止实体模型变得混乱。您可以控制从视图中验证所需的任何内容,因为 DTO 对象未在其他任何地方共享。可以将数据批注保留在实体对象中以用于实体框架。
有时您可能希望使对象在视图模型上成为必需的,但不要在实体或类似的东西中。
如果您的对象很大,您可以使用自动映射器来帮助映射对象,从而减少您的工作量。
查看模型
public class FirstViewModel
{
public int Id { get; set; }
public string Prop2 { get; set; }
public DateTime Prop3 { get; set; }
}
public class SecondViewModel
{
public int Id { get; set; }
public string Prop2 { get; set; }
public int Prop3 { get; set; }
}
public class ThirdFormViewModel
{
public FirstViewModel FirstModel { get; set; }
public SeconViewdModel SecondModel { get; set; }
}
删除ModelState.IsValid检查并自己验证数据。如果您只需要验证 2 个属性,这看起来是更简单的方法