0

我在我的视图模型中设置了验证,如下所示:

[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,但似乎只有视图中填充的模型项是。对此的最佳做法是什么?隐藏字段/会话数据?

4

3 回答 3

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);
}
于 2013-11-12T23:20:20.970 回答
1

要了解为什么必须重建模型的某些部分,您需要考虑当模型绑定器从您的视图中传递数据时,幕后发生了什么。ASelectList就是一个很好的例子。

假设您有一个视图模型,如下所示:

public class EmployeesViewModel
{
    public int EmployeeId { get; set; }
    public SelectList Employees { get; set; }
    // other properties
}

这里,EmployeeId表示从Id中选择EmployeeSelectList。所以让我们假设你有一个像这样的控制器动作,它填充SelectList数据并将数据传递给视图:

public ActionResult Index()
{
    var model = new EmployeesViewModel();
    model.Employees = new SelectList(/* populate the list */);
    return View(model);
}

现在让我们假设有一个用户出现,导航到这个视图,从列表中选择一个员工,然后将数据 POST 回服务器。发生这种情况时,从该表单提交的唯一内容 . HTTP 不需要将所有其他选项从服务器传输到服务器,因为 a)它们尚未被选中,并且 b)您已经在服务器上拥有该数据。Id employeeSelectList

于 2013-11-12T23:24:05.663 回答
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);
     }
}
于 2013-11-12T23:26:39.503 回答