0

私は MVC を初めて使用し、この問題に数日間苦労しています。

フォームをサーバーにポストするとき、値は常に null です。コレクション/リストを使用してモデル自体を使用しようとしましたが、最後に試したアプローチはViewModelを使用することでした。

私が達成しようとしている目標は、ユーザーがサインアップしているイベントへの出席をマークすることです。正しい出席情報を取得してビューに送信しています。チェック ボックスをオンにして、ブール値の Attend.Attended を更新します。デバッグ中、Post アクションの先頭にブレーク ポイントを置きます。モデル、コレクション/リスト、ViewModel は常に null です。

モデル:

public class Attend
{
  [Key]
  public int AttendID { get; set; }

  public virtual UserProfile User { get; set; }

  public virtual Event Event { get; set; }

  public Boolean SignedUp { get; set; }

  public Boolean Attended {get; set; }

}

public class Event
{
  [Key]
  public long EventID { get; set; }

  [Required]
  [DisplayName("When is this event?")]
  public DateTime DateScheduled { get; set; }

  public DateTime DateCreated { get; set; }

  [DisplayName("Event Category")]
  public String Category { get; set; }

  [Required]
  [DisplayName("Location")]
  public String Location { get; set; }

  public string Comments { get; set; }

  [Required]
  [DisplayName("Event Name")]
  public string EventName { get; set; }

  [Required]
  [DisplayName("Event Description")]
  public string EventDescription { get; set; }

  public virtual ICollection<Attend> Attends { get; set; }
}

コントローラ:

    //
    // GET: /Event/Attendance
    [HttpGet]
    public ActionResult Attendance(long id)
    {
        try
        {
            var model = new AttendanceViewModel();

            if (db == null)
                return HttpNotFound();

            if (Request.UrlReferrer != null && Request.UrlReferrer.AbsoluteUri != null)
                ViewBag.ReferrerUrl = Request.UrlReferrer.AbsoluteUri;
            else
                ViewBag.ReferrerUrl = Url.Action("Index");

            model.Attending = db.Attends.ToList();

            ViewBag.myID = id;
            return View(model);
        }
        catch (Exception ex)
        {
            Log.Error(ex.Message, ex);
            return HttpNotFound();
        }
    }

    //
    // POST: /Event/Attendance
    [HttpPost]
    public ActionResult Attendance(AttendanceViewModel Attending, long id)
    {

       //POST ACTION...
    }

意見:

model CottagesOfHope.ViewModels.AttendanceViewModel

@{
    ViewBag.Title = "Attendance";
}

<h2>Mark Attendance</h2>


@using (Html.BeginForm())
{
    <fieldset>
        <legend>Attendance</legend>
        <table>
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Attendance</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var j in Model.Attending)
                {
                    if (j.Event.EventID == ViewBag.myId)
                    {
                        <tr>
                           <td>@j.User.FirstName @j.User.LastName</td>
                           <td>@Html.EditorFor(model => j.Attended)</td>
                       </tr>
                    }
                }
            </tbody>
        </table>
        <p>
            <input type="submit" value="Submit" />
        </p>
    </fieldset>
}

ビューモデル:

public class AttendanceViewModel
{
    public virtual List<Attend> Attending { get; set; }
}

前に言ったように、これがデータを正しくバインドしようとした最後のアプローチでした。どんな助けでも大歓迎です。
前もって感謝します!

4

2 に答える 2

0

BeginForm必要なパラメータをメソッドに渡していないようです。これを試してください:

@using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post)) {...}

これの代わりに:

@using (Html.BeginForm()) {...}

"ControllerName"はコントローラの"ActionName"名前で、 はコントローラ アクションの名前です。詳しくはこちらをご覧ください

params を指定しないと、結果の html は次のようになります。

<form action="/" method="post"></form>

ただし、params を指定すると、html は次のようになります。

<form action="/ControllerName/ActionName" method="post"></form>
于 2013-05-28T16:34:30.647 に答える
0

したがって、実際には2つの問題がありました。

  1. コントローラーでリストをフィルターする必要があるときに、ビューでリストをフィルターしていました。
  2. foreach ループがリストに対して正しく機能しない場合があることを読みました。繰り返しごとに for ループを使用してリストにインデックスを付けることが推奨されます。

更新されたコントローラー:

[HttpPost]
    public ActionResult Attendance(ViewModels.AttendanceViewModel a)
    {
        try
        {
        foreach (var j in a.Attending)
        {
            //Needed to filter by EventID here
            Attend attends = db.Attends.Where(e => e.AttendID == j.AttendID).Single();

            attends.Attended = j.Attended;
        }
        db.SaveChanges();
        return RedirectToAction("Index", "Event");
        }
        catch (Exception ex)
        {
            Log.Error(ex.Message, ex);
            return HttpNotFound();
        }
    }

ビューの更新:

@model CottagesOfHope.ViewModels.AttendanceViewModel

@{
   ViewBag.Title = "Attendance";
 }

<h2>Mark Attendance</h2>


@using (Html.BeginForm())
{
<fieldset>
    <legend>Attendance</legend>
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Attendance</th>
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.Attending.Count(); i++)
            {
                <tr>
                       <td>@Model.Attending[i].User.FirstName 
                           @Model.Attending[i].User.LastName</td>
                       <td>@Html.CheckBoxFor(model => Model.Attending[i].Attended)</td>
                        @Html.HiddenFor(model => Model.Attending[i].AttendID)
                   </tr>
            }
        </tbody>
    </table>
    <p>
        <input type="submit" value="Submit" />
    </p>
</fieldset>
}
于 2013-05-28T23:33:17.160 に答える