作成操作と編集操作の両方に単一の剃刀ビューを使用できますか?
はいの場合、どうすればこれを達成できますか?
お勧めしません。
通常の MVC GET/POST ワークフローのプロセス、リクエスト、およびワークフローには多くのことが関係しているため、これはかなり長い答えになるはずです。必要最小限の情報と、同じビューの使用をお勧めしない理由について、ご質問にお答えします。
まず、なぜですか?
私の提案するアプローチは、異なるアクション/ビューを持つが、共通のコードを共有することです:
両方のビューを通常どおり作成します。
コードが重複しますが、すべてのコードが同じというわけではありません。たとえば、作成アクションで ID を送信したくない場合があります。これは質問とは直接関係ありませんが、同じビューを使用すると、これは、特に過剰転記または一括割り当ての場合には推奨されません。一括割り当ての詳細については、こちらを参照してください (ここではアーキテクチャル アプローチを使用しています)。
それでは、コントローラーで何を受け取るかから始めましょう。この場合、継承を使用しましたが、それが唯一の戦略ではありません。
バインディング モデル
public class UpdateBindingModel : CreateBindingModel {
// since we are not using the same binding model,
// we can have a "real" validation rules on our update binding and view.
[Required]
public int? Id {get;set;}
}
public class CreateBindingModel {
// no id here prevent overposting.
[Required]
public string Name {get;set;}
[Required]
public int? CountryId {get;set;}
}
これにより、作成および編集に送信するデータが必要最小限であり、他に何もないことが確認されます。
次に、ビューに送信されるビュー モデルを見てみましょう。この例では、値を選択するために使用されるが、選択された値のみがコントローラーに投稿 (リスト) されるべきではないリストを含めます。
モデルを見る
public class CreateViewModel : CreateBindingModel {
public IEnumerable<SelectListItem> CountryList {get;set;}
}
public class UpdateViewModel : UpdateBindingModel {
public IEnumerable<SelectListItem> CountryList {get;set;}
}
ご覧のとおり、これにより多くの柔軟性が得られますが、重複したコード (両方のビューのビュー モデルに必要な追加情報) がいくつかありますが、これはいくつかの方法で軽減できます (ニーズ/コンテキストに応じて)。
@Html.Action("GetCountryList");
CreateUpdateViewModel
を使用し、ビュー内の余分なプロパティを破棄UpdateBindingModel
しますが、対応するモデルを POST に投稿します。@Html.EditorFor
パーシャルの代わりに使用することをお勧めします。これにより、Model Binder はコードに追加の変更を加えることなく動作します)コントローラーのアクションは次のようになります。
コントローラ
[HttpGet]
public ActionResult Create(){
ViewData.Model = new CreateViewModel();
return View();
}
[HttpPost]
public RedirectToRouteResult Create(CreateBindingModel binding) {
// check valid model state and create data
return RedirectToAction("Index");
}
[HttpGet]
public ActionResult Update(int id) {
var objectToEdit = service.GetObjectToEdit(id);
ViewData.Model = new UpdateViewModel(objectToEdit);
return View();
}
[HttpPost]
public RedirectToRouteResult Update(UpdateBindingModel binding) {
// check valid model state and update data
return RedirectToAction("Index");
}
そしてあなたの意見:
ビュー
Update.cshtml
<form action="Update">
@Html.HiddenFor(Model.Id);
@Html.Partial("EditFieldsPartial")
<button>delete</button> // no delete button on create.
<button>create new</button> // you can have a create new instead of update.
</form>
Create.cshtml
<form action="Create">
@Html.Partial("EditFieldsPartial")
</form>
注:コードは不完全であり、簡潔さと明確さのためにほとんどの場合ヘルパーを使用していません。コピーペーストしないでください:D
ビューは、同じモデルを使用して、作成操作と編集操作で確実に共有できます。ただし、よく考えることを強くお勧めします。多くの場合、編集操作用に別のビューを使用する必要があり (たとえば、編集できない入力を非表示にするなど)、一部の (またはほとんどの) 値を共有している可能性があるにもかかわらず、モデルがわずかに異なる可能性があります。これらの違いにより、ビューでいくつかの条件が発生し、作成中か編集中かがチェックされ、コードが混乱する可能性があります。 結論:ビューを共有するかどうかを決定する前に、編集画面が作成画面とどの程度異なるかを考えてみてください。