2011-02-09 6 views
1

この質問はさまざまな形で質問されていますが、私の状況に合った回答はありません。私は単に私のコントローラのドロップダウンリストの選択値を取得しようとしています。ここでビューモデルを使用して選択リストの選択した値をコントローラに投稿するにはどうすればいいですか?

は私のコードは次のとおりです。

ViewModel.cs

public class ViewModel 
{ 
    public ViewModel() {} 
    public ViewModel(Contact contact, IEnumerable<State> states) 
    { 
     this.Contact = contact; 
     this.States = new SelectList(states, "Id", "Name", contact.StateId); 
    } 
    public Contact Contact {get;set;} 
    public SelectList States {get;set;} 
} 

Controller.cs

[HttpPost] 
public ActionResult Edit(ViewModel viewModel) 
{ 
    _contactService.UpdateContact(viewModel.Contact); 
    return RedirectToAction("Item", new {id = viewModel.Contact.Id}); 
} 

View.cshtml

<button type="submit" onclick="javascript:document.update.submit()"><span>Update</span></button>//aesthic usage. 
@{using (Html.BeginForm("Edit", "Controller", FormMethod.Post, new { name = "update" })) 
    { 
    @Html.HiddenFor(m => m.Contact.Id) 
    @Html.LabelFor(m => m.Contact.Name, "Name:") 
    @Html.TextBoxFor(m => m.Contact.Name) 

    <label for="state">State:</label> 
    @Html.DropDownList("state", Model.States) 
} 
} 

ことは除いてすべてが期待どおりに動作しますドロップからの値ダウンリストは、投稿されたviewModelでコントローラに渡されます。編集ページとすべてのフィールドが正しく読み込まれます。ドロップダウンは正しくバインドされ、選択した値が適切に表示されます。しかし、私が投稿すると、私は "連絡先"オブジェクトをコントローラに渡すだけです。 "States" SelectListオブジェクトはnullです。

私はviewModel contstructorで "StateId"プロパティをマッピングしようとしましたが、それはどちらも動作しませんでした。私は間違って何をしていますか?

ありがとうございました。 m.Stateが選択された値を保持している

@Html.DropDownListFor(m => m.Contact.StateId, Model.States, "-- Please select a State --"):「状態」は、あなたがこのようにそれを使用することができ、あなたのモデルの一部である場合

答えて

3

私は自分自身の質問に答えるのが嫌いですが、私が無数の回答を利用できるという複数の問題に基づいて、私は私の所見を要約すると考えました。

最初にFilipのおかげで、彼の答えは私の問題を正確には解決しなかったが、正しい方向に私を導いた。 +1

ドロップダウンリストが必要な表示と編集用のフォームを作成する場合は、いくつかの提案と問題点があります。私は自分のニーズに合わせて必要なパラメータのリストから始めます。

  1. 私の見解では、厳密に型指定されたビューが推奨されます。魔法の文字列を最小限に抑えます。
  2. ビューモデルには、できるだけ少ないロジックと無関係な要素が含まれている必要があります。データオブジェクトの収集を容易にするだけの仕事が必要です。
  3. ドロップダウンリストには、選択した値が表示されます。
  4. 選択した値は、フォーム送信時にビューモデルに簡単に戻されます。

これは明白で容易に入手できるリストのように聞こえるかもしれませんが、MVCを初めて使う人にとってはそうではありません。私はコメントを上から修正します。ここに私がしたことがあります。

ViewModel.cs

public class ViewModel 
{ 
    public ViewModel() {} 
    public ViewModel(Contact contact, IList<State> states) 
    { 
//no need to pass in a SelectList or IEnumerable, just what your service or repository spits out 
    this.Contact = contact; 
    this.States = states; 
    } 
    public Contact Contact {get;set;} 
    public IList<State> States {get;set;} 
} 

Controller.cs

public ActionResult Edit(int id) 
{ 
    var contact = _contactService.GetContactById(id); 
    var states = _stateService.GetAllStates(); 
    return View(new ViewModel(contact, states)); 
} 

public ActionResult Edit(ViewModel viewModel) 
{ 
    _contactService.UpdateContact(viewModel.Contact); 
    return RedirectToAction("Edit", new {id = viewModel.Contact.Id }); 
} 

ビュー//上記以外本当に異なる//何もないおかげで、私が使用しているこのpost

@{using (Html.BeginForm("Edit", "Controller", FormMethod.Post)) 
{ 
    @Html.HiddenFor(m => m.Contact.Id) 
    @Html.DropDownListFor(m => m.Contact.StateId, new SelectList(Model.States, "Id", "Name", @Model.Contact.StateId)) 
<input type="submit" value="Save" /> 
} 
} 
+0

dropdownvalueを選択した後でボタンをクリックしていたのですか、ポストバックをしたいドロップダウンの選択だけでしたか? – alice7

+0

連絡先エンティティを持つビューモデルを使用するこの正しい方法はありますか? – Rohit

2

は、代わりに@Html.DropDownListForを使用してみてください。

IEnumerableをモデルと混同しないように、私はViewBag/ViewDataに入れます。

これは、代わりにこのようなものになります。

@Html.DropDownListFor(m => m.Contact.StateId, (IEnumerable<string>)ViewBag.States, "-- Please select a State --")

そして、あなたはViewBag.Statesプロパティに列挙状態を初期化する必要があります。このビューを返し、あなたのアクションでは。

+0

でArtirtoに行きますViewBagとそれは期待どおりに動作したが、ちょうど別のミニviewmodelのように見える。私が投稿したコードに基づく議論のために、なぜそれらがビューモデルの一部であるときに選択リストがnullに戻るのでしょうか? – trevorc

+0

あなたのモデルでは 'SelectList'が必要なので、それはフォームが投稿するものではありません。 "state"という名前のアクションに 'string'パラメータを追加すると、選択した値が取得されます。 –

関連する問題