两个数据源创建视图

问题描述:

这是我的数据模型类的样子:两个数据源创建视图

public class Employee 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public Position Position { get; set; } 
} 

public class Position 
{ 
    public string Title { get; set; } 
} 

我有一个创建视图,我想为姓和名,然后两个文本框有位置标题的下拉框。我试图做这样说:

视图(仅相关部分):

<p> 
    <label for="Position">Position:</label> 
    <%= Html.DropDownList("Positions") %> 
</p> 

控制器:

// 
// GET: /Employees/Create 

public ActionResult Create() 
{ 
    ViewData["Positions"] = new SelectList(from p in _positions.GetAllPositions() select p.Title); 

    return View(); 
} 

// 
// POST: /Employees/Create 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Employee employeeToAdd) 
{ 
    try 
    { 
     employeeToAdd.Position = new Position {Title = (string)ViewData["Positions"]}; 
     _employees.AddEmployee(employeeToAdd); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

然而,当我点击提交,我得到这个异常:

System.InvalidOperationException was unhandled by user code 
Message="There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Positions'." 

我很确定我做错了。填充下拉框的正确方法是什么?

我相信ViewData是用来将信息传递给你的视图,但它不能正常工作。也就是说,ViewData不会从Request.Form设置。我想你可能想要改变你的代码,如下所示:

// change following 
employeeToAdd.Position = new Position {Title = (string)ViewData["Positions"]}; 
// to this? 
employeeToAdd.Position = new Position {Title = (string)Request.Form["Positions"]}; 

祝你好运!

+0

P.S.你在'

+0

中缺少's'什么是for属性? – 2009-09-03 05:33:18

+0

它应该匹配标签和输入。例如,对于使用屏幕阅读器的人来说,这是为了获得更好的可访问性,因此他们知道他们应该填写什么内容。我建议的改变是否工作? – Funka 2009-09-03 06:40:00

由于未设置ViewData [“位置”],因此在Create()(WITH POST ATTRIBUTE)员工中,您正在收到此错误。这个值应该构成你的发布请求的一部分,并且在帖子从应用中获取它或者从会话/缓存中获取它时重新绑定,如果你需要重新绑定它的话。

记住ViewData仅适用于当前请求,所以对于发布请求ViewData [“职位”]尚未创建,因此此例外。

你可以做一个快速测试...重写控制器的OnActionExecuting方法,并把逻辑放在那里取位置,这样它总是可用的。这应该是需要对每个动作的数据来完成......这仅仅是在这种情况下,测试目的...

// add the required namespace for the model... 
protected override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    // add your logic to populate positions here... 
    ViewData["Positions"] = new SelectList(from p in _positions.GetAllPositions() select p.Title); 

} 

有可能对本等清洁解决方案,以及可能使用自定义的模型绑定...

您可以存储:

(string)ViewData["Positions"]}; 
在页面上hiddn标签

然后调用它像这样

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Employee employeeToAdd, string Positions) 
{ 
+0

嗯,在隐藏字段中存储的东西听起来像Webforms的东西。有没有更好的方式来做到这一点?它可能只适用于一个或两个字段,但想象一下,如果您有一个包含15个不同字段的表单,可从数据模型中获取其数据。那会变得非常难看。 – 2009-09-03 05:35:25

+0

我认为行动方法看起来不错,但我不相信隐藏的输入应该是必要的。 '字符串位置'应该根据在保管箱中选择的内容自动绑定。 – Funka 2009-09-03 06:45:52