在编辑Post Action上将ViewModel绑定到Controller - (使用无参数构造函数)获取null

时间:2015-08-18 07:50:42

标签: c# .net asp.net-mvc entity-framework asp.net-mvc-5

作为开发者asp.net网站,我创建了项目。并使用DataBase First方法将其用于控制​​器创建。

有两个EF数据模型对象:Personal和PersonalDetails。

using System;
using System.Collections.Generic;

public partial class personalDetails
{
    public int personID { get; set; }
    public Nullable<bool> rehber { get; set; }
    //many others, removed for easy to understand

}

public partial class personal
{
    public personal()
    {
        this.passportDetails = new HashSet<passportDetails>();
    }
    public string name { get; set; }
    public string surname { get; set; }
    public int ID { get; set; }

    public Nullable<short> politicalPartyID { get; set; }
    public Nullable<short> familyStatusID { get; set; }

    public virtual familyStatus familyStatus { get; set; }
    public virtual politicalParties politicalParties { get; set; }

}

对于业务逻辑,有必要创建viewModel,因为在视图中有个人字段和personalDetils对象的某些字段。我添加了viewModel类。

 public class SocialViewModels
{

    public personalDetails personalDetails { get; private set; }

    public personal personal { get; private set; }
    public SelectList marriageStatus { get; private set; }

    public SelectList partyList { get; private set; }
    public SocialViewModels()
    {

    }
    public SocialViewModels(personalDetails _personalDetails, personal _personal,  IEnumerable _marriageStatus, IEnumerable _partyList)
    {
        personalDetails = _personalDetails;
        personal=_personal;
        marriageStatus = new SelectList(_marriageStatus, "ID", "familyStatusName", personal.familyStatusID);
        partyList = new SelectList(_partyList, "ID", "partyName", personal.politicalPartyID);
    }

}

此ViewModel适用于获取详细信息操作。控制器和视图如下:

public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        personalDetails personalDetails = db.personalDetails.Find(id);
        SocialViewModels svm = new SocialViewModels(personalDetails, personalDetails.personal, db.familyStatus, db.politicalParties);

        if (personalDetails == null)
        {
            return HttpNotFound();
        }
        return View(svm);
    }

详情视图:

 @model kadrws.ViewModels.SocialViewModels

@Html.DisplayFor(model => model.personal.familyStatus.familyStatusName)

@Html.DisplayFor(model => model.personal.politicalParties.partyName)

@Html.DisplayFor(model => model.personalDetails.rehber)

<p>
    @Html.ActionLink("Redaktə et", "Edit", new { id = Model.personal.ID })
</p>

但编辑帖子方法有问题:

 // GET: personalDetails/Edit/5
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        personalDetails personalDetails = db.personalDetails.Find(id);
        SocialViewModels svm = new SocialViewModels(personalDetails, personalDetails.personal, db.familyStatus, db.politicalParties);

        if (personalDetails == null)
        {
            return HttpNotFound();
        }
        return View(svm);

    }

    // POST: personalDetails/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "personID,rehber, partyID, familyStatusID")] SocialViewModels scm )
    {
        if (ModelState.IsValid)
        {
               //do 
        }
        ViewBag.personID = new SelectList(db.personal, "ID", "name", scm.personal.ID);
        return View(scm);
    }

修改视图:

@model kadrws.ViewModels.SocialViewModels
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.personalDetails.personID)

    @Html.DropDownList("personal_familyStatusID", Model.marriageStatus)

    @Html.DropDownList("personal_politicalPartyID", Model.partyList)

    @Html.EditorFor(model => model.personalDetails.rehber)

    <input type="submit" value="Save" class="btn btn-default" />

}

问题是,SocialViewModels为null。 enter image description here

我也会在Google中搜索类似的行为。打这个就像问题一样。请帮助了解此代码中的问题...

1 个答案:

答案 0 :(得分:0)

首先,属性marriageStatuspartyList将为null,因为它们是SelectList的类型(并且您不会为每个属性的每个属性生成表单控件集合中的{1}} - 也不应该)。但是,您会生成名为SelectListItem<select>的{​​{1}}元素,但您的模型不包含具有这些名称的属性。

其次,属性personal_familyStatusIDpersonal_politicalPartyIDpersonal,因为您已包含personalDetails属性,该属性明确排除(它必须为null

然而,您误解了视图模型是什么以及如何使用它。它不仅仅是一个包含多个数据模型实例的类,它应该只包含您在视图中显示/编辑的属性。根据您在表单中包含的4个控件,您的视图模型应为

[Bind]

附注:请勿在{{1​​}}属性上设置Bind(Include = "personal, personalDetails")]。如果您需要返回视图,因为public class SocialViewModels { public int ID { get; set; } public Nullable<bool> Rehber { get; set; } public int MarriageStatus { get; set; } public int Party { get; set; } public SelectList MarriageStatusList { get; set; } public SelectList partyList { get; set; } } 无效,那么您永远无法重新填充它们

然后在GET方法中,初始化视图模型的新实例,从数据模型设置其属性并将其返回到视图

private

旁注:你的命名非常混乱(一分钟为SelectList,然后是ModelState,所以不确定我是否正确解释了它。

然后在视图中

public ActionResult Details(int? id)
{
  ....
  personalDetails personalDetails = db.personalDetails.Find(id);
  ....
  SocialViewModels model = new SocialViewModels()
  {
    ID = personalDetails.personID,
    Rehber = personalDetails.rehber,
    MarriageStatus = personalDetails.personal.familyStatusID,
    ....
    MarriageStatusList = new SelectList(db.familyStatus, "ID", "familyStatusName"),
    ....
  };
  return View(model);
}

在POST方法中

familystatus