在ASP.net MVC中加载相关数据 [英] Loading related data in ASP.net MVC

查看:144
本文介绍了在ASP.net MVC中加载相关数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

东西很简单,但我正在寻找最好的方法。我有一个电影实体,每个电影只能使用一个语言(一个查询表,英文,法语等)。现在我试图加载电影创建页面,电影视图模型中查找中的所有可用语言:

 命名空间Project.ViewModels {
public class Movie {

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

public string标题{get;组; }

public string Rating {get;组; }
public string Director {get;组; }
public string Plot {get;组; }
public string Link {get;组; }
public string主演{get;组; }
public int DateCreated {get;组; }

public string类型{get;组; }

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

//导航属性
public virtual MovieLanguage Language {get;组; }
}
}

MovieLanguage视图模型:

 命名空间MAKANI.ViewModels {
public class MovieLanguage {

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

public string语言{get;组; }

public virtual ICollection< Movie>电影{get;组;
}
}

控制器动作:

  public ActionResult MovieCreate(){


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

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

在View页面中,我有

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

我在View中收到此错误:
'System.Web .Mvc.HtmlHelper'没有适用的名为DropDownList的方法,但似乎有一个扩展名。扩展方法无法动态调度。考虑转换动态参数或调用扩展方法而不使用扩展方法语法



不确定问题可能是什么?



另一个有关此方法的问题:




  • 首先应为MovieLanguage实体创建视图模型,知道它只将服务器作为查找表(所以它不需要任何创建/编辑/删除操作,只能列出/读取可能),我应该在这种情况下直接依赖于EF实体?


解决方案

语言集合属性>电影 ViewModel和SelectedLanguage属性,以便在表单提交时获取所选的语言ID。您的ViewModel不需要具有您的域模型的所有属性。 只有View需要的属性。

  public class Movie 
{
public int ID {set; get;}
public string标题{set; get;}
//其他相关属性。

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

public Movie()
{
语言=新列表< SelectListItem& ;
}
}

现在您的 GET 动作,创建您的 Movie ViewModel的对象,并设置Languages Collection属性并将其发送到View。尝试避免使用ViewBag传递这样的数据。 ViewBag 使我们的代码变脏。为什么不能完全使用强类型的ViewModels?

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

// To DO:我建议您抽象代码以从DB
//获取语言到其他方法,以便您的操作方法将为
// skinny和该方法可以在不同的地方调用。
var enLanguages = db.MoviesLanguages.ToList();
vm.Languages = =来自m in enLanguages
选择新的SelectListItem {
Text = m.Language,
Value = m.ID.ToString()
};

return View(vm);
}

在您的视图中,强烈类型为我们的电影 ViewModel,使用DropDownListFor Hemml助手方法

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

现在,当您发布表单时,您将获得所选的languageId, code> SelectedLanguage 您的ViewModel的属性

  [HttpPost] 
public ActionResult CreateMovie(电影模型)
{
如果(ModelState.IsValid)
{
//在这里检查model.SelectedLanguage属性。
//保存和重定向(PRG模式)
}
//您需要重新加载语言,因为HTTP是无状态的。
return View(model);
}


Something very simple but I am looking for the best way to do it. I have a Movie entity, each Movie can be in one Language only(a lookup table with English, French,etc...). Now I'm trying to load all the available languages in the lookup in the Movie Create Page, the Movie View Model:

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

The MovieLanguage View model:

namespace MAKANI.ViewModels {
    public class MovieLanguage {

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

        public string Language { get; set; }

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

The controller action:

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

And in the View page i have

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

Howver I am getting this error in the View: 'System.Web.Mvc.HtmlHelper' has no applicable method named 'DropDownList' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax

Not sure what the problem might be?

Another questions regarding this approach:

  • Should a create a view model for the MovieLanguage entity in the first place, knowing that it servers only as a lookup table(so it doesnt require any Create/Edit/Delete action, Only List/Read maybe), should I be depending on the EF entities directly in that case?

解决方案

Have a Languages Collection Property in your Movie ViewModel and a SelectedLanguage Property to get the selected Language ID when the form submits. It is not necessary that your ViewModel should have all the properties like your domain model. Have only those properties which the View needs.

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

Now in your GET Action, Create an object of your Movie ViewModel and set the Languages Collection property and send that to the View. Try to avoid using ViewBag for passing data like this. ViewBag makes our code dirty.Why not use the strongly typed ViewModels to its full extent ?

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

And in your view which is strongly typed to our Movie ViewModel, use the DropDownListFor Hemml helper method

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

Now when you post the form, you will get the selected languageId in the SelectedLanguage Property of your ViewModel

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

这篇关于在ASP.net MVC中加载相关数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆