ViewModel在HTTPPost上为Null

时间:2013-05-28 13:26:12

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

我是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>
}

ViewModel:

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

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

2 个答案:

答案 0 :(得分:0)

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

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

而不是:

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

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

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

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

但是当你指定params时,html将如下所示:

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

答案 1 :(得分:0)

所以实际上有两个问题:

  1. 当我应该在控制器中过滤它时,我正在过滤视图中的列表。
  2. 我读到foreach循环有时在列表上不能正常工作,建议在每次迭代时使用for循环并索引List。
  3. 更新了控制器:

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