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

従来の ASP とは異なり、MVC は軽量であり、隠しフィールドにすべてのオブジェクトを格納するわけではありません。つまり、次のような場合です。

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

通常の ASP では、これらのオブジェクトのコレクションをドロップダウン リストにマップし、ポスト バックで、結果で参照された元のオブジェクトを取得できます。MVC は、これらのオブジェクトを保存していないため、この方法では機能しません。したがって、目的のオブジェクトが必要な場合は、渡された ID を使用して、目的の結果を再取得する必要があります。

モデルのプロパティの次の EditorTemplate を想像しCustomerIdてください。

@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 に答える