ModelView パターンを使用した ASP MVC + Html.DropDownList() の問題
-
20-08-2019 - |
質問
最近、HTML ヘルパー ドロップダウンリストに関する質問を投稿し、機能するようにしました (ここ)。しかし今では、ビューなどで強く型付けされたメソッドにアクセスできるように、ModelView パターンに切り替える方がはるかに賢明であると判断しました。私がやったことは、次の方法で他のトピックのコードにいくつかの調整を加えたことです。
VactureFormViewModel:
public class VacaturesFormViewModel
{
public Vacatures Vacature { get; private set; }
public SelectList EducationLevels { get; private set; }
public SelectList Branches { get; private set; }
public SelectList CareerLevels { get; private set; }
Repository repository;
// Constructor
public VacaturesFormViewModel(Vacatures vacature)
{
this.Vacature = vacature;
this.repository = new Repository();
this.EducationLevels = new SelectList(repository.GetAllEducationLevels(),"ID","Name",vacature.EducationLevels);
this.Branches = new SelectList(repository.GetAllBranches(),"ID","Name",vacature.Branches);
this.CareerLevels = new SelectList(repository.GetAllCareerLevels(), "ID", "Name", vacature.CareerLevels);
}
}
Banenコントローラー:
//
// GET: /Banen/Create
public ActionResult Create()
{
Vacatures vacature = new Vacatures();
return View(new VacaturesFormViewModel(vacature));
}
//
// POST: /Banen/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Vacatures vacatureToAdd)
{
if (ModelState.IsValid)
{
try
{
// TODO: Add insert logic here
repository.AddToVacatures(vacatureToAdd);
repository.SaveChanges();
// Return to listing page if succesful
return RedirectToAction("Index");
}
catch (Exception e)
{
return View();
}
}
}
そして、私の Create.aspx ビュー (その一部):
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<p>
<label for="Title">Title:</label>
<%= Html.TextBox("Title", Model.Vacature.Title) %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="Content">Content:</label>
<%= Html.TextArea("Content", Model.Vacature.Content) %>
<%= Html.ValidationMessage("Content", "*") %>
</p>
<p>
<label for="EducationLevels">EducationLevels:</label>
<%= Html.DropDownList("EducationLevels", Model.EducationLevels)%>
<%= Html.ValidationMessage("EducationLevels", "*") %>
</p>
<p>
<label for="CareerLevels">CareerLevels:</label>
<%= Html.DropDownList("CareerLevels", Model.CareerLevels)%>
<%= Html.ValidationMessage("CareerLevels", "*")%>
</p>
<p>
<label for="Branches">Branches:</label>
<%= Html.DropDownList("Branches", Model.Branches)%>
<%= Html.ValidationMessage("Branches", "*")%>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
ガイドのために私が使用したのは、 オタクディナー ScottGu によるチュートリアル。私はここでさまざまなトピックを読みました。
私の質問は、MVC ASP が現在私が望むものではない ID 文字列を返しているため、キャリアレベル、教育レベル、ブランチ (ドロップダウンリスト) を自動的に設定できるかどうかです。SelectList の作成を次のように変更すると、
this.CareerLevels = new SelectList(repository.GetAllCareerLevels(), vacature.CareerLevels);
したがって、「ID」と「名前」がないと、どちらも保存されず(オブジェクト自体ではなく、postメソッドの文字列として返されると思います)、その隣に次のようにビューにリストされます。vacature.EducationLevels などしたがって、名前ではなくオブジェクト自体がリストされます。
最後の質問つまり、私の質問は、このアプローチを使用して私の部門、学歴レベル、キャリアレベルを設定できるかどうかということです。では、自動的ではないのでしょうか?
その場合でも、次のようなものを使用する必要があります。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection form)
{
Vacatures vacatureToAdd = new Vacatures();
// Retrieve the education level by its ID
if (!form["EducationLevels"].Equals(""))
{
Guid educationID = new Guid(form["EducationLevels"]);
vacatureToAdd.EducationLevels = repository.GetEducationLevelByID(educationID);
}
私のコントローラーでは?それとも、もっとスムーズな他のオプションはありますか。
解決
GUID を使用するように編集しました:
ドロップダウンリストでは、少し異なるアプローチを使用します。ビューモデルを機能させることは可能かもしれませんが、私にとっては次の方法の方が簡単です。
public class VacaturesFormViewModel
{
public IEnumerable<SelectListItem>EducationLevels{ get; set; }
public Guid EducationLevelID{ get; set; }
}
EducationLevelID には、ドロップダウンで選択した ID が含まれます。これは次のような見解です。
<%= Html.DropDownList("EducationLevelID", Model.EducationLevels)%>
コントローラ
IEnumerable<SelectListItem> educationLevelList =
from level in GetLevelList()
select new SelectListItem
{
Text = level .Name,
Value = level.Uid.ToString()
};
model.EducationLevels = educationLevelList ;
他のヒント
よくわかりませんが、モデルバインダーを作成する必要があると思います。(デビッド・ヘイデン 簡単なモデルバインダーを書きました)
バインドすることもできます 教育ID パラメータが自動的に:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Guid? educationID, FormCollection form)
{
Vacatures vacatureToAdd = new Vacatures();
if (educationID != null)
{
vacatureToAdd.EducationLevels =
repository.GetEducationLevelByID(educationID.Value);
}