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

モデルの一部を再構築する必要がある理由を理解するには、ビューからデータがモデル バインダーに渡されるときに内部で何が起こっているかを考える必要があります。ASelectListはまさにその典型です。

次のようなビュー モデルがあるとします。

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

ここで、はから選択された をEmployeeId表します。したがって、次のようなコントローラー アクションがあり、データを入力してビューに渡すとします。IdEmployeeSelectListSelectList

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

ここで、ユーザーがやって来て、このビューに移動し、リストから従業員を選択し、データをサーバーに POST したとします。これが発生すると、そのフォームから送信される唯一のもの Id employee . HTTP が他のすべてのオプションを からSelectListサーバーに転送する必要はありません。これは、a) オプションが選択されておらず、b) そのデータが既にサーバー上にあるためです。

于 2013-11-12T23:24:05.663 に答える
1

私はあなたの質問を理解しているかどうかわかりません...これが失われたフィールドに入力する方法です:モデルの人口を2つの部分に分割します:編集可能な小道具(サーバーにポストバックされる要素)と編集不可能な(ポストバックで失われる)

// 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 に答える