簡體   English   中英

盡管沒有綁定控制器,控制器仍使用空值填充對象

[英]Controller is populating objects with null value despite them not being bound

我仍在學習有關Entity框架及其通信方式的很多知識,因此這可能很簡單,但是我似乎無法弄清楚問題出在哪里。

要設置場景,我有一個由Visual Studio生成的可正常使用的Create函數,並且已按照以下步驟在此函數中設置了值:

myObject.Id = Guid.NewGuid().ToString();
myObject.dateCreated = DateTime.Now;

這看起來很棒,並且一切正常。 問題出在我隨后嘗試編輯記錄時。

我有這個模型:

public class MyObject
{
    public string Id { get; set; }
    public string UserId { get; set; }
    public string Name { get; set;  }
    public DateTime dateCreated { get; set; }
    public Nullable<DateTime> dateModified { get; set; }
    public Boolean aDefault { get; set; }

}

(大多數情況下是自動生成的)這些控制器:

public async Task<ActionResult> Edit(string id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    MyObject myObject = await db.myObjects.FindAsync(id);
    if (myObject == null)
    {
        return HttpNotFound();
    }
    return View(myObject);
}

public async Task<ActionResult> Edit([Bind(Include = "Id,aDefault,Name")] MyObject myObject)
{
    if (ModelState.IsValid)
    {
        myObject.dateModified = DateTime.Now;
        db.Entry(myObject).State = EntityState.Modified;
        await db.SaveChangesAsync(); //db is the generated dbcontext
        return RedirectToAction("Index");
    }
    return View(myObject);
}

和(僅顯示表單上的字段)視圖:

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

<div class="form-group">
    @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
    </div>
</div>


<div class="form-group">
    @Html.LabelFor(model => model.aDefault, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        <div class="checkbox">
            @Html.EditorFor(model => model.aDefault)
            @Html.ValidationMessageFor(model => model.aDefault, "", new { @class = "text-danger" })
        </div>
    </div>
</div>

因此,當前,當我運行此代碼並轉到編輯區域時,我希望它采用“名稱”和默認值,並將它們發布到控制器,並僅修改數據庫中的相關字段。 但是,當前運行此代碼時,我得到:

datetime2數據類型到datetime數據類型的轉換導致超出范圍的值。 該語句已終止。

這使我相信我的dateCreated被設置為null。 我通過將其設置為Nullable來確認了這一點,它不再引發異常,但是當然將數據庫中的dateCreated設置為null。

我是否需要將所有屬性綁定到類似於在隱藏字段中設置ID的視圖? 我希望不要像我想的那樣只綁定相關項目。 有沒有一種方法可以排除這些一次性設置為不更新的字段?

多虧了這些評論以及過去24小時的一些研究,我才意識到主要問題是Entity Framework為我產生的問題。 這條線讓我最頭疼:

db.Entry(myObject).State = EntityState.Modified;

這會將所有屬性設置為Modifyed,因此將所有內容的值都設置為null,而所有未綁定的內容都保持為null。

我可以看到為什么另一個選擇(也許是更好的做法)可能是僅針對視圖中的必要屬性添加另一個ViewModel,但是我發現在這種情況下,控制器可能更適合實現更改的內容。 這是我修改后的方法:

public async Task<ActionResult> Edit([Bind(Include = "Id,aDefault,Name")] MyObject myObject)
{
    if (ModelState.IsValid)
    {
        db.MyObjects.Attach(myObject); //MyObjects is the DbSet
        myObject.dateModified = DateTime.Now;
        db.Entry(myObject).Property(o => o.Name).IsModified = true;
        db.Entry(myObject).Property(o => o.aDefault)IsModified = true;
        await db.SaveChangesAsync(); //db is the generated dbcontext
        return RedirectToAction("Index");
    }
    return View(myObject);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM