2013-06-03 61 views
2

我有一個問題,可能只是由於我缺乏ASP.NET MVC的經驗,但它是我現在一直試圖解決的一個問題。ASP.NET MVC 4「創建」頁面提交結果無效ModelState

我有一個Code First數據庫設置,與asp.net上的第一個教程(http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4)沒有什麼不同。基本上,我遇到的問題是嘗試通過「創建」頁面在數據庫中創建新記錄時,ID設置爲0,這使得ModelState無效。

相關代碼: 型號:

public class Evt 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public string GeoDescription { get; set; } 
    public decimal Longitude { get; set; } 
    public decimal Latitude { get; set; } 
    public DateTime Date { get; set; } 
} 

控制器:

[HttpPost] 
public ActionResult Create(Evt evt) 
{ 
    if (ModelState.IsValid) // This is returning false because ID is 0 
    { 
     db.Evts.Add(evt); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(evt); 
} 

我可以根據要求添加視圖代碼爲好,但它基本上只是從模型中自動生成的代碼。

如果有人有任何想法,我將不勝感激!

感謝,

傑夫

編輯:我不引用ID在我的「創建」視圖所有,並添加它作爲一個隱藏的表單值沒有任何解決我的問題。

更新:我已經能夠規避錯誤加入

if (!ModelState.IsValid && evt.ID == 0) ModelState.Clear();

以上Createif聲明,但此刪除所有客戶端驗證和顯然不夠理想。它確實表明,記錄在插入服務器後會正確插入一個增加的ID。

回答

0

括號內如果有人在將來遇到此,這可能不是你想聽到的答案,但它是我落得這樣做。

我轉而使用顯式實體框架(數據庫優先)而不是使用Code First。這重新生成了我的模型,並隨後解決了我的問題。我不確定它爲什麼修復它,但正如我在問題描述中所說的那樣,我認爲這可能是我原本意外更改的一小部分設置或一行代碼。

我對那些有此問題並且不想放棄代碼優先的人的建議:嘗試重構您的模型或完全刪除它並創建一個具有相同屬性的新代碼。

對不起,我無法提供更多幫助。

1

它看起來像你使用EF實體類作爲ViewModels。這是不推薦的,因爲ViewModel(包含humand可讀輸入表單的數據內容)和實體(表示規範化的業務對象)之間沒有1:1的映射,只是巧合的是,您可以使用簡單EF類作爲ViewModels,但如果你這樣做,最終你會遇到這樣的問題。

有幾種可能的解決方案,最好是爲您的頁面使用專用的ViewModel。第二種方法是修改您的實體類以將int ID更改爲int? ID,因此模型綁定器不會要求指定該項目,第三個選項是在調用之前清除與成員相關的任何錯誤的模型狀態選擇ModelState.IsValid

請注意,如果您確實繼續使用您的實體類作爲視圖模型,那麼您將對Mass Assignment攻擊產生懷疑(因爲您的代碼是當前的攻擊)。這就是爲什麼專用每視圖ViewModel是最好的。

+1

你不能瓚使實體類使ID爲空,因爲它是主鍵,並且主鍵不能爲空。 –

1

正如Dai所說,推薦的方法是不要直接在您的視圖中使用您的實體。這有很多原因,但你現在正在品嚐它們。

但是,如果你不打算這樣做,你有幾個選擇。正如Dai所說,你可以清除模型狀態,但我不喜歡這種方法。這是hacky和醜陋的,真的只是不好的做法。

您還可以將[Bind(Exclude="ID")]添加到您的參數中。在這種情況下:

public ActionResult Create([Bind(Exclude="ID")] Evt evt) 

我不是真正的喜歡,要麼,但至少它不是在你的控制器刪除從ModelState中的項目一樣醜陋。

您還可以添加隱藏字段。你說你做到了這一點,並沒有解決問題,但它應該已經奏效。所以也許你做錯了什麼,比如使用錯誤的命名約定。我建議使用HiddenFor並確保它是你的BeginForm(){}

@Html.HiddenFor(x => x.ID) 
+0

其實,這是我在做隱藏字段時使用的命令和語法。我不明白爲什麼這麼多的改變應該是必要的。如果你快速瀏覽一下我發送的鏈接,那麼這個教程工作得很好(而且工作正常;這是我改編我當前的代碼的原因)。我只是假設我無意中改變了一些東西 - 無論是在數據庫配置還是其他地方 - 我根本搞不清楚在哪裏。如果它很重要,我在我的視圖中使用KendoUI,這是MVVM。 –

0

我只碰到過這樣的問題,不知道是你也一樣

我使用新的和編輯同一個頁面,所以我有這樣的:

@Html.HiddenFor(model => model.Code_Id) 

但這是編輯有用只是,所以我添加類似:

if (ViewBag.Action != "New") 
{ 
    @Html.HiddenFor(model => model.Code_Id) 
} 

和ModelState.IsValid現在是真正的