0

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

    [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 没有。任何想法为什么?这是我的第一次尝试,所以我希望我可能会犯多个错误。

4

1 回答 1

0

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

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();
}
于 2012-12-09T17:32:05.090 回答