【问题标题】:Loading related data in ASP.net MVC在 ASP.net MVC 中加载相关数据
【发布时间】:2012-09-04 21:00:39
【问题描述】:

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

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 实体?

【问题讨论】:

  • ViewBag.SelectLanguage = selectList 试试这个。不是.ToList()

标签: asp.net asp.net-mvc entity-framework


【解决方案1】:

在您的 Movie ViewModel 中有一个 Languages 集合属性和一个 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>();
  }
}

现在在您的GET 操作中,创建您的Movie ViewModel 的对象并设置语言集合属性并将其发送到视图。尝试avoid 使用 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);
}

在您认为我们的Movie ViewModel 强类型化的视图中,使用 DropDownListFor Hemml 辅助方法

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

现在,当您发布表单时,您将在 ViewModel 的 SelectedLanguage 属性中获得选定的语言 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);
}

【讨论】:

    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多