0

一些非常简单的事情,但我正在寻找最好的方法来做到这一点。我有一个电影实体,每部电影只能使用一种语言(英语、法语等查找表)。现在我正在尝试在电影创建页面的查找中加载所有可用的语言,即电影视图模型:

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

Languages在您的ViewModel 中有一个Collection 属性Movie和一个 SelectedLanguage 属性,以便在提交表单时获取选定的语言 ID。您的 ViewModel 不必像您的域模型一样具有所有属性。仅具有视图需要的那些属性。

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>();
  }
}

现在在您的GETAction 中,创建MovieViewModel 的对象并设置 Languages Collection 属性并将其发送到 View。尽量避免使用 ViewBag 来传递这样的数据。ViewBag使我们的代码变脏。为什么不充分使用强类型 ViewModels 呢?

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" />
}

现在,当您发布表单时,您将在SelectedLanguageViewModel 的属性中获得选定的语言 ID

[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 回答