2012-12-09 32 views
0

我想在MVC中使用DropdownlistFor将对象添加到我的数据库中。我可以填充下拉列表,但是当我发布表单时,我得到一个错误,因为下拉列表(这是Team对象的外键)已填充,但不是实际值。这里是我的代码:MVC中的DropdownLists

[HttpGet] 
     public ActionResult FixtureAdd() 
     { 
      IEnumerable<SelectListItem> teams = _repository.GetTeams() 
       .Select(c => new SelectListItem 
       { 
        Value = c.TeamId.ToString(), 
        Text = c.TeamName 
       }).ToList(); 

      IEnumerable<SelectListItem> weeks = _repository.GetWeeks() 
       .Select(c => new SelectListItem 
       { 
        Value = c.ToString(), 
        Text = c.ToString() 
       }).ToList(); 

      ViewBag.Teams = new SelectList(teams, "Value", "Text"); 
      ViewBag.Weeks = new SelectList(weeks, "Value", "Text"); 

      string apiUri = Url.HttpRouteUrl("DefaultApi", new { controller = "fixture", }); 
      ViewBag.ApiUrl = new Uri(Request.Url, apiUri).AbsoluteUri.ToString(); 

      return View(); 
     } 

     [HttpPost] 
     public ActionResult FixtureAdd(Fixture fx) 
     { 
      if (ModelState.IsValid) 
      { 
       try 
       { 
        //TODO: Add insert logic here 
        _repository.AddFixture(fx); 
        return RedirectToAction("FixtureAdd"); 
       } 
       catch (DbEntityValidationException dbEx) 
       { 
        foreach (var validationErrors in dbEx.EntityValidationErrors) 
        { 
         foreach (var validationError in validationErrors.ValidationErrors) 
         { 
          Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); 
         } 
        } 

        return View(fx); 
       } 
      } 
      else 
      { 
       IEnumerable<SelectListItem> teams = _repository.GetTeams() 
        .Select(c => new SelectListItem 
        { 
         Value = c.TeamId.ToString(), 
         Text = c.TeamName 
        }).ToList(); 

       ViewBag.Teams = new SelectList(teams, "Value", "Text"); 

       IEnumerable<SelectListItem> weeks = _repository.GetWeeks() 
        .Select(c => new SelectListItem 
        { 
         Value = c.ToString(), 
         Text = c.ToString() 
        }).ToList(); 

       ViewBag.Weeks = new SelectList(teams, "Value", "Text"); 

       return View(fx); 
      } 
     } 

    public IEnumerable<Team> GetTeams() 
     { 
      return _db.Teams.ToArray(); 
     } 

public partial class Fixture 
    { 
     public int FixtureId { get; set; } 
     public string Season { get; set; } 
     public byte Week { get; set; } 

     //foreign key 
     public int AwayTeamId { get; set; } 
     //navigation properties 
     public virtual Team AwayTeam { get; set; } 

     //foreign key 
     public int HomeTeamId { get; set; } 
     //navigation properties 
     public virtual Team HomeTeam { get; set; } 

     public byte? AwayTeamScore { get; set; } 
     public byte? HomeTeamScore { get; set; } 
    } 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 

    <fieldset> 
     <legend>Fixture</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Season) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Season) 
      @Html.ValidationMessageFor(model => model.Season) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Week) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.Week, (SelectList)ViewBag.Weeks) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AwayTeam.TeamId) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.AwayTeam.TeamId, (SelectList)ViewBag.Teams) 
      @Html.ValidationMessageFor(model => model.AwayTeam.TeamId) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.AwayTeamScore) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.AwayTeamScore) 
      @Html.ValidationMessageFor(model => model.AwayTeamScore) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.HomeTeam.TeamId) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.HomeTeam.TeamId, (SelectList)ViewBag.Teams) 
      @Html.ValidationMessageFor(model => model.HomeTeam.TeamId) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.HomeTeamScore) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.HomeTeamScore) 
      @Html.ValidationMessageFor(model => model.HomeTeamScore) 
     </div> 

     <p> 
      <button data-bind='click: save'>Add fixture</button> 
     </p> 
    </fieldset> 
} 

的TeamId外键字段被在后填充但TeamName没有。任何想法为什么?这是我的第一次尝试,所以我希望我可能会犯这个错误。

+0

MVC不就像ASP一样,在下拉菜单中列出对象并选择键实际上是分配对象。在提交中填充密钥后,您需要重新获取您想要的对象。 –

+0

所以我需要调用一个方法,例如GetTeamNameByTeamId在帖子上再次获取对象? – user517406

+0

在您的提交操作中,您需要重新获取您基于模型中提交的ID的对象。我会看看我是否可以发布我在谈论的答案。 –

回答

0

与传统的ASP不同,MVC是轻量级的,不会将所有这些对象存储在隐藏字段中。也就是说,如果你有以下几点:

class Customer { 
    public Int32 Id { get; set; } 
    public String Name { get; set; } 
} 

在正常的ASP,你可以这些对象的集合映射到一个下拉列表,并在背面后你会得到这是在引用的原始对象结果。 MVC不以这种方式工作,因为它不再存储这些对象。所以,如果你想要这个预期的对象,你将需要使用传递的ID并重新获取所需的结果。

图片为你的模型CustomerId属性如下EditorTemplate:

@model Int32 
@Html.DropDownListFor(x => x, new SelectList(
    Customers.GetAllCustomers().Select(y => new SelectListItem { 
    Value = y.Id, 
    Text = y.Name, 
    Selected = Model == y.Id 
    }) 
); 

,当然还有:

@Html.EditorFor(x => x.CustomerId) @* Use above EditorTemplate *@ 

然后在您提交的行动:

[HttpPost] 
public ActionResult(MyViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
    // ID was passed, re-fetch the customer based on selected id 
    Customer customer = Customers.GetById(model.CustomerId) 
    /* ... */ 
    } 
    /* ... */ 
    return View(); 
} 
+0

非常有帮助的帖子,谢谢! – user517406