我在我的viewmodel中进行了设置验证,如下所示:
[Required(ErrorMessage = "This field is required.")]
[StringLength(25, MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[System.Web.Mvc.CompareAttribute("Password", ErrorMessage = "Password must be the same")]
public string ConfirmPassword { get; set; }
当我提交表单时,我会检查ModelState.IsValid
是否无效,然后返回原始视图,但这样做会丢失我在模型中的原始数据。
[HttpPost]
public ActionResult Form(MemberAddViewModel viewModel, string returnUrl)
{
if (ModelState.IsValid)
{
...
}
return View("Form", viewModel);
}
我原本希望将viewModel
传递回原始View
,但似乎只有视图中填充的模型项。这是什么最佳做法?隐藏字段/会话数据?
答案 0 :(得分:1)
我不确定我是否承担了你的问题...这就是我填充丢失字段的方式:我将模型人口划分为两部分:可编辑道具(被发布回服务器的元素)和不可编辑的(丢失的)在回发上)
// View model
public class MyModel
{
public MyModel() { }
public MyModel(Entity e, ContractTypes[] ct)
{
// populate model properties from entity
ContractTypeId = e.ContractTypeId;
// and call magic method that'll do the rest my model needs
PopulateNonEditableFields(ct);
}
public void PopulateNonEditableFields(
Dictionary<int, string> ContractTypes [] ct)
{
// populate dictionaries for DDLs
ContractTypesList = new SelectList(..., ct,...);
}
// model properties
public ContractTypeId { get; set; }
public SelectList ContractTypesList { get; set; }
}
// controller action
[HttpPost]
public ActionResult Action(MemberAddViewModel viewModel)
{
if (ModelState.IsValid)
{
...
}
// user input stays as-is but need to populate dictionaries and evrithing
// that was lost on postback
viewModel.PopulateNonEditableFields(context.ContractTypes.GetAll());
return View("Form", viewModel);
}
答案 1 :(得分:1)
要了解为什么必须重建模型的某些部分,您需要考虑模型绑定器从视图中传递数据时发生的事情。 SelectList
就是一个很好的例子。
假设您有一个视图模型如下:
public class EmployeesViewModel
{
public int EmployeeId { get; set; }
public SelectList Employees { get; set; }
// other properties
}
此处,EmployeeId
代表Id
中所选Employee
的{{1}}。所以我们假设你有一个这样的控制器动作,它填充SelectList
并将数据传递给视图:
SelectList
现在让我们假设用户出现,导航到此视图,从列表中选择一个员工,并将数据POST回服务器。发生这种情况时,唯一从该表单提交的内容是 public ActionResult Index()
{
var model = new EmployeesViewModel();
model.Employees = new SelectList(/* populate the list */);
return View(model);
}
的 Id
。 HTTP不需要将所有其他选项从employee
传输到服务器,因为a)它们尚未被选中,b)您已经在服务器上拥有该数据。
答案 2 :(得分:1)
据我了解,您在视图模型中有数据,而不是通过表单发回。出现这种情况可能有很多正当理由。
另一种方法是始终手动创建视图模型,然后通过调用TryUpdateModel
使用回发值更新它。调用TryUpdateModel
将做两件事:使用控制器的值提供程序设置模型的公共属性,然后对模型运行验证检查。
[HttpPost]
public ActionResult Action(int id, string returnUrl)
{
MemberAddViewModel viewModel = CreateViewModel(id); // Populates with
// intial values
if(TryUpdateModel(viewModel))
{
// If we got here, it passed validation
// So we continue with the commit action
// ...
}
else // It failed validation
{
return View("Form", viewModel);
}
}