如何将ViewModel与DropDownListFor一起使用

时间:2014-11-25 16:36:22

标签: c# asp.net-mvc

MVC.NET的新手(和C#一般......并且正在开发)并尝试围绕ViewModels。我有一个非常基本的要求。我有ActorUseCaseProject个实体。要创建新的UseCase,我想要一个DropDownListFor ActorsProject位于同一UseCase的视图。项目id位于URL中。我一直关注此How to bind a selectlist with viewmodel?,但我遇到了错误:

DataBinding: 'System.Web.Mvc.SelectListItem' does not contain a property with the name 'ActorId'.

此外,我并不确切知道如何使用POST方法进行映射 - 我很高兴现在手动执行此操作而不使用AutoMapper

视图模型:

 public class UserGoalsStepViewModel
{
    public enum GoalLevel
    {
        Summary, UserGoal, SubGoal,
    }

        public int ProjectId { get; set; }
        public int ActorId { get; set; }
        public SelectList ActorList { get; set; }
        public string Title { get; set; }
        public GoalLevel Level { get; set; }

        public UserGoalsStepViewModel ()
        {

        }


}

更新:控制器: 已更新,以反映以下评论中讨论的更改。

发生了什么: 1.在GET中创建视图时正确填充模型(ProjectId,Level和ActorList的值是正确的,actorId是' 0'并且Title是null。全部按预期方式。 2.在POST上,标题设置为" 5" (实际上是所选actor的Id,ActorId = 0仍然,Level得到正确的值而ProjectId失去了它的值。所以,显然我需要对SelectList定义做一些事情,但是我是不确定为什么ProjectId迷路了?

// GET: UseCases/Create
    public ActionResult Create(int id)

    {

        ViewBag.projectId = id;

        //Populate the ViewModel
        UserGoalsStepViewModel model = new UserGoalsStepViewModel()
        {
            ProjectId = id,
            ActorList = new SelectList(db.Actors.Where(a => a.projectID == id), "id", "Title"),

        };

        return View(model);
    }

    // POST: UseCases/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "ProjectId,ActorId,Title,Level")] UserGoalsStepViewModel model, int id)
    {

        ViewData["Actors"] = new SelectList(db.Actors.Where(a => a.projectID == id), "id", "Title");


        if (ModelState.IsValid)
        {

            //Create a use case object to map to, which can then be saved in the DB

            UseCase uc = new UseCase();
            uc.ProjectID = model.ProjectId;
            uc.ActorID = model.ActorId;
            uc.Level = (Level)model.Level;
            db.SaveChanges();
            return RedirectToAction("Index", new { id = model.ProjectId });
        }

        return View(model);
    }

查看:

@Html.DropDownListFor(model => model.Title, new SelectList(Model.ActorList, "ActorId", "Title"), new { @class = "form-control" })

2 个答案:

答案 0 :(得分:2)

尝试:

@Html.DropDownListFor(model => model.Title, Model.ActorList, new { @class = "form-control" })

而不是:

@Html.DropDownListFor(model => model.Title, new SelectList(Model.ActorList, "ActorId", "Title"), new { @class = "form-control" }

问题是您尝试在DropDownListFor中创建Selectlist,但Model.ActorList已经 一个SelectList

代码中可能存在其他问题,但这应该会让您超越该特定错误。

<强>更新

您POST的Controller方法应如下所示:

public ActionResult Create(UserGoalsStepViewModel model)
{
    // what are we updating? assume it's a project
    var p = from db.Projects.Where(x => x.Id == model.id;

    p.SomeProperty = model.SomeProperty;
    db.SaveChanges();
}

NB-为了简洁起见,我删除了一些额外的检查 - 显然你想要添加绑定限制,模型状态检查,空检查等。

更新2

当您发布数据时Title=5,因为标题控件是您的选择列表,而5是所选值。 ActorId = 0因为您可能没有包含此值的表单控件,ProjectId也是如此?如果没有看到View代码,就无法确定。

答案 1 :(得分:0)

这是我在帖子上做的... ....向VM添加Post方法。

public class UserGoalsStepViewModel{  

  // in the ctor initiailze properites...

  public string SelectedValue {get;set;}
  public IEnumerable<SelectListItem> DDL {get;set;}

public void Post(){
    DoSomethingWith(SelectedValue)

}

这需要在View ...

中使用强类型绑定进行正确绑定
@model UserGoalStepViewModel
@Html.DropDownListFor(x=>model.SelectedValue, model.DDL)

控制器(帖子的动作方法)

[HttpPost]
public ActionResult(UserGoalsStepViewMdoel vm){
      if(ModelState.IsValid){
             vm.Post();
             ModelState.Clear(); // if you want to show changed properties in view.

       }
       return View(vm);
}

最后一件事,确保你想要发回控制器的所有内容都在BeginForm内...... MVC有这样的习惯,就是你只需要给你发回你强烈的控制器动作方法的内容,如果你没有&#39 ; t得到BeginForm内部的所有内容,它将看起来像#34;丢失数据&#34; ......