【问题标题】:ViewModel is Null on HTTPPostHTTPPost 上的 ViewModel 为 Null
【发布时间】:2013-05-28 13:26:11
【问题描述】:

我是 MVC 的新手,几天来我一直在努力解决这个问题。

当我将表单发回服务器时,这些值始终为空。我尝试过使用模型本身,使用集合/列表,而我尝试的最后一种方法是使用 ViewModel。

我要实现的目标是标记用户注册的活动的出席情况。我正在获取正确的出席信息并将它们发送到视图。我将选中复选框以更新布尔值 Attend.Attended。在调试过程中,我会在 Post 操作的开头放置一个断点,并且模型、集合/列表、ViewModel 每次都为空。

型号:

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; }
}

就像我之前所说的,这是我尝试正确绑定数据的最后一种方法。任何帮助将不胜感激。
提前致谢!

【问题讨论】:

    标签: c# asp.net-mvc-4 http-post


    【解决方案1】:

    看起来您没有将任何必需的参数传递给 BeginForm 方法,试试这个:

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

    而不是这个:

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

    其中"ControllerName" 是控制器的名称,"ActionName" 是控制器操作的名称。查看更多here

    如果不指定参数,生成的 html 将如下所示:

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

    但是当您指定参数时,html 将如下所示:

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

    【讨论】:

    • 一个同学,我真的想通了。您的解决方案是有道理的,但实际上并没有帮助。即使我没有输入这些参数,它仍然会进入那个 ActionResult。我不确定是不是因为我的 HttpGet 使用了相同的 Action 和 Controller 并且它只是假设它。谢谢你的意见。
    【解决方案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>
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多