2011-12-15 10 views
3

RoomTypeレコードを作成しようとしています。各RoomTypeには、各言語の説明であるRoomTypeInfosのコレクションがあります。次に、各RoomTypeInfoは言語レコードに関連付けられます。MVC3を使用してポストアクション後にネストされたモデルが失われる

RoomTypeを作成するには、言語ごとに1つのRoomTypeInfoを使用してオブジェクトをプリロードします。

GETアクション:

// 
// GET: /RoomType/Create/IdHotel 
[HttpGet] 
public ActionResult Create(int id) 
{ 
    List<Language> _Languages = __roomTypeRepository.GetLanguages().ToList<Language>(); 
    RoomType roomType = new RoomType { IdHotel = id }; 
    roomType.RoomTypeInfos = new System.Data.Linq.EntitySet<RoomTypeInfo>(); 
    foreach (Language Language in _Languages) 
    { 
     roomType.RoomTypeInfos.Add(new RoomTypeInfo { Language = Language }); 
    } 
    return View(roomType); 
} 

POSTアクション:

// 
// POST: /RoomType/Create/ 
[HttpPost] 
public ActionResult Create(RoomType roomType) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      __roomTypeRepository.InsertRoomType(roomType); 
      return RedirectToAction("Index", new { id = roomType.IdHotel }); 
     } 
     else 
     { 
      return View(roomType); 
     } 
    } 
    catch 
    { 
     return View(roomType); 
    } 
} 

だから、モデルが有効ではないか、例外がキャッチされた後のアクションで、私はエラーを取得する場合は、@ Model.Language Languageがnullになったので、ビューの.Name。

@model DataAccess.RoomTypeInfo 
@Html.HiddenFor(model => model.Id) 
@Html.HiddenFor(model => model.IdRoomType) 
@Html.HiddenFor(model => model.IdLanguage) 
<fieldset> 
    <legend>@Model.Language.Name</legend> 
    <div class="editor-label"> 
     @Html.LabelFor(model => model.Name) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Name) 
     @Html.ValidationMessageFor(model => model.Name) 
    </div> 
    <div class="editor-label"> 
     @Html.LabelFor(model => model.Descripcion) 
    </div> 
    <div class="editor-field"> 
     @Html.TextAreaFor(model => model.Descripcion, new { Class = "wysiwyg" }) 
     @Html.ValidationMessageFor(model => model.Descripcion) 
    </div> 
</fieldset> 

そしてRoomTypeエディタテンプレート:RoomTypeInfoエディタテンプレートの

コード

@model DataAccess.RoomType 
@Html.HiddenFor(model => model.Id) 
@Html.HiddenFor(model => model.IdHotel) 
<h3> 
    Información Básica 
</h3> 
<div class="editor-field"> 
    @Html.EditorFor(model => model.RoomTypeInfos) 
    @Html.ValidationMessageFor(model => model.RoomTypeInfos) 
</div> 

私は言語テーブルを照会し、各RoomTypeInfo.Languageに再びそれを設定することによって、それを固定したが、回避策のように感じる場合。

この場合のベストプラクティスは何ですか?

+0

これらの異なるRoomTypeInfoビューをレンダリングするRoomTypeビューのcshtmlコードも投稿できますか? – danludwig

+0

ルームタイプビューが追加されました。 – Smet1960

答えて

2

これにはBeginCollectionItem HTML helper authored by Steve Sandersonを使用します。部分ビューでは、すべての入力フィールドを@using(Html.BeginCollectionItem("RoomTypeInfos"))にラップします。

バックグラウンドでは、入力要素の名前とIDが変更され、デフォルトのモデルバインダーで認識され、ルートViewModel(ケースのRoomType)に追加されます。あなたのコードのための

例:あなたは言語がPOST後にnullでないことを確認する場合は

@model DataAccess.RoomTypeInfo 
@using (Html.BeginCollectionItem("RoomTypeInfos")) 
{ 
    Html.HiddenFor(model => model.Id) 
    Html.HiddenFor(model => model.IdRoomType) 
    Html.HiddenFor(model => model.IdLanguage) 
    <fieldset> 
     <legend>@Model.Language.Name</legend> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
      @Html.ValidationMessageFor(model => model.Name) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Descripcion) 
     </div> 
     <div class="editor-field"> 
      @Html.TextAreaFor(model => model.Descripcion, new { Class = "wysiwyg" }) 
      @Html.ValidationMessageFor(model => model.Descripcion) 
     </div> 
    </fieldset> 
} 

また、あなたが隠しフィールドとして追加する必要があります

@Html.HiddenFor(m => m.Language.Name) 

このようにして、デフォルトモデルバインダーによってモデルにバインドされます。 HTTP POST(ある種の入力フィールドで)を介してデータを送信しない場合は、モデル&ビューを返す前にPOSTアクションメソッドで再ポピュレートする必要があります。

+0

@ Html.HiddenFor(m => m.Language.Name)はエラーを部分的に修正しましたが、新しい言語レコードを作成しようとしていますので、言語オブジェクトに必須の属性がないためLINQ例外が発生します。また、BeginCollectionItemは私のために働いていないようです。 – Smet1960

+0

ドメインエンティティをコントローラ内で直接使用していますか?もしそうなら、他の必要な属性を満たすために、@ Html.HiddenFor(m => m.Language.PropName)でそれらを渡す必要があります。これは、エンティティからビューモデルレイヤーを分離する必要がある理由です(オートマッパーを使用して翻訳します)。 BeginItemCollectionで試してみてください。 "CollectionName"引数は、ルートエンティティタイプのCollectionNameと一致しなければならないことに注意してください。 – danludwig

+0

残りを追加し、新しい言語レコードを作成するようになりました。 – Smet1960

関連する問題