0

非常に単純なことですが、私はそれを行うための最良の方法を探しています。私はMovieエンティティを持っていますが、各Movieは1つの言語のみにすることができます(英語、フランス語などのルックアップテーブル)。今、私はムービー作成ページ、ムービービューモデルのルックアップで利用可能なすべての言語をロードしようとしています:

namespace Project.ViewModels {
    public class Movie {

        [Key]
        public int ID { get; set; }

        public string Title { get; set; }

        public string Rating { get; set; }
        public string Director { get; set; }
        public string Plot { get; set; }
        public string Link { get; set; }
        public string Starring { get; set; }
        public int DateCreated { get; set; }

        public string Genre { get; set; }

        [Display(Name = "Language")]
        public int LanguageID { get; set; }

        // Navigational Properties
        public virtual MovieLanguage Language { get; set; }
    }
}

MovieLanguageビューモデル:

namespace MAKANI.ViewModels {
    public class MovieLanguage {

        [Key]
        public int ID { get; set; }

        public string Language { get; set; }

        public virtual ICollection<Movie> Movies { get; set; }
    }
}

コントローラのアクション:

public ActionResult MovieCreate() {


    using (MAKANI.Models.Entities db = new MAKANI.Models.Entities()) {

        List<Models.MoviesLanguages> enLanguages = db.MoviesLanguages.ToList();

        IEnumerable<SelectListItem> selectList =
                   from m in enLanguages
                   select new SelectListItem {                              
                       Text = m.Language,
                       Value = m.ID.ToString()
                   };
        ViewBag.SelectLanguage = selectList.ToList();

        return View();
    }          
}

そして、表示ページで私は持っています

    <div class="editor-field">
        @Html.DropDownList("Language", ViewBag.SelectLanguage);            
    </div>

ただし、ビューでこのエラーが発生します: 'System.Web.Mvc.HtmlHelper'には'DropDownList'という名前の適用可能なメソッドがありませんが、その名前の拡張メソッドがあるようです。拡張メソッドを動的にディスパッチすることはできません。動的引数をキャストするか、拡張メソッド構文なしで拡張メソッドを呼び出すことを検討してください

問題が何であるかわからない?

このアプローチに関する別の質問:

  • そもそもMovieLanguageエンティティのビューモデルを作成する必要がありますが、それはルックアップテーブルとしてのみ機能することを知っています(したがって、作成/編集/削除アクションは必要ありません。おそらくリスト/読み取りのみ)。その場合、EFエンティティは直接ですか?
4

1 に答える 1

1

ViewModel に Collection プロパティと SelectedLanguage プロパティを用意して、フォームの送信時に選択された言語 ID を取得しますLanguagesMovieViewModel がドメイン モデルのようなすべてのプロパティを持つ必要はありません。ビューが必要とするプロパティのみを持ちます。

public class Movie 
{
  public int ID { set;get;}
  public string Title { set;get;}
  //Other Relevant Properties also.

  public IEnumerable<SelectListItem> Languages { set;get;}
  public int SelectedLanguage { set;get;}

  public Movie()
  {
     Languages =new List<SelectListItem>();
  }
}

GETアクションで、ViewModel のオブジェクトを作成しMovie、Languages コレクション プロパティを設定して、それをビューに送信します。このようなデータを渡すために ViewBag を使用しないようにしてください。ViewBag私たちのコードを汚いものにします。強く型付けされた ViewModel を最大限に活用してみませんか?

public ActionResult CreateMovie()
{
  var vm=new Movie();    

  // TO DO : I recommend you to abstract code to get the languages from DB 
  //         to a different method so that your action methods will be
  //         skinny and that method can be called in different places.
  var enLanguages = db.MoviesLanguages.ToList();
  vm.Languages= = from m in enLanguages
               select new SelectListItem {                              
                   Text = m.Language,
                   Value = m.ID.ToString()
               };

  return View(vm);
}

ViewModel に強く型付けされたビューではMovie、DropDownListFor Hemml ヘルパー メソッドを使用します。

@model Movie
@using(Html.Beginform())
{
    @Html.DropDownListFor(x => x.SelectedLanguage, 
            new SelectList(Model.Languages, "Value", "Text"), "Select Language")
   <input type="submit" />
}

SelectedLanguageフォームを投稿すると、ViewModelのプロパティで選択した languageId が取得されます。

[HttpPost]
public ActionResult CreateMovie(Movie model)
{
   If(ModelState.IsValid)
   {
       //check model.SelectedLanguage property here.
      //Save and Redirect (PRG pattern)
   }
   //you need to reload the languages here again because HTTP is stateless. 
   return View(model);
}
于 2012-09-04T12:47:20.103 に答える