2012-04-23 63 views
0

我遇到了驗證字段的問題,看起來驗證失敗,但沒有完成要求。我會盡力包含所有信息,所以對於這樣一個冗長的問題帖子道歉!模型綁定顯示錯誤,提供了足夠的數據

已經創建的ViewModel是一個DTO對象,其中只包含足夠的信息來操作用戶輸入的任何數據。由於項目的未知數,我的觀點模型稍微複雜得多,將是理想的...

public class UpdateViewModel 
{ 
    public UpdateViewModel() 
    { 
     WorkingPeriods = new List<WorkingPeriod>(); 
     LeavePeriods = new List<LeavePeriod>(); 
    } 

    public Guid UserID { get; set; } 
    public DateTime From { get; set; } 
    public DateTime Until { get; set; } 
    public DateTime Selected { get; set; } 

    public IEnumerable<WorkingPeriod> WorkingPeriods { get; set; } 
    public IEnumerable<LeavePeriod> LeavePeriods { get; set; } 

    public class WorkingPeriod 
    { 
     public int ID { get; set; } 
     public DateTime Date { get; set; } 
     public TimeSpan? StartTime { get; set; } 
     public TimeSpan? EndTime { get; set; } 
    } 

    public class LeavePeriod 
    { 
     public int ID { get; set; } 
     public DateTime Date { get; set; } 
     public int LeaveTypeID { get; set; } 
     public Guid? Reference { get; set; } 
     public string Period { get; set; } 
     public TimeSpan? UserDefinedPeriod { get; set; } 
    } 
} 

我有一個觀點,即有幾個靜態助手的助手是能夠產生HTML代表信息的存在。輸出HTML類似於:

<li class="editorRow"> 
    <input type="hidden" name="LeavePeriods.index" autocomplete="off" value="8a5522c6-57fe-40a2-95bc-b9792fbe04d3" /> 
    <input id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__ID" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].ID" type="hidden" value="4" /> 
    <input id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__Date" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].Date" type="hidden" value="23/04/2012 00:00:00" /> 
    <select class="leaveTypeDropdown" id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__LeaveTypeID" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].LeaveTypeID"> 
     <option value="">- please select -</option> 
     <option selected="selected" value="2">Annual Leave</option> 
     <option value="34">Public Holiday</option> 
     <option value="1">Sickness</option> 
    </select> 
    <div class="leavePeriodRadio"> 
    <input checked="checked" id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__ALL" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].Period" type="radio" value="ALL" /><label for="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__ALL">Full Day</label> 
     <input id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__AM" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].Period" type="radio" value="AM" /> <label for="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__AM">AM</label> 
     <input id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__PM" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].Period" type="radio" value="PM" /> <label for="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__PM">PM</label> 
     <input class="other-user-period" id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__Other" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].Period" type="radio" value="Other" /> <label for="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__Other">Other</label> 
     <span class="user-defined" style="display:none"> 
      Duration: <input class="timepicker" id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__UserDefinedPeriod" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].UserDefinedPeriod" type="text" value="" /> 
     </span> 
    </div> 
</li> 

當用戶提交使用Ajax的形式(通過Ajax.BeginForm結構設置)(MVC3 & JQuery的是參與)出現問題。

@using (Ajax.BeginForm("Index", "Timesheet", new AjaxOptions() 
    { 
     HttpMethod = "POST", 
     LoadingElementId = "loading", 
     UpdateTargetId = "contentPane", 
     OnComplete = "SaveCompleted", 
    })) 
  • 如果用戶省略了字段(它們是完全有權這樣做),他們收到的消息:The UserDefinedPeriod field is required.
  • 或者,如果他們輸入有效的TimeSpan值(例如「12:00」),則會得到:The value '12:00' is not valid for UserDefinedPeriod.
  • 如果他們輸入了一個無效的字符串(例如「Boris」),該值將被清除,並且它們會顯示上面的字段所需消息,就好像它們沒有輸入任何內容。 (假設:值被清除,我相信,因爲「鮑里斯」不能被儲存在一個TimeSpan?,因此不能被運回視圖)

使用斷點和檢查對各種事物的價值,我已經結束瞭如下:

  • 該值存在於Request.Form中,並且可以與其他分組一起看到。
  • 該值存在於模型中,可以通過使用VS中的斷點檢查該值。
  • ModelState.IsValid正在返回false,因爲Model.LeavePeriods.UserDefinedPeriod有1個錯誤,與最後顯示給用戶的錯誤相同。

僅供參考,控制器是:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] 
public class TimesheetController : Controller 
{ 
    [HttpPost] 
    public ActionResult Index(UpdateViewModel updates, User currentUser) 
    { 
     if (!ModelState.IsValid) 
     { 
      // error with model, so lets deal with it and return View(); 
     } 
     // continue with parsing and saving. 
    } 
} 

,最讓我困惑這個問題的事情是,我有一個是建立在對身體無問題類似的方式與其他盒 - 如兩在WorkingPeriod枚舉中的TimeSpan? s。我想我在哪裏可以看到什麼是問題。我嘗試將ViewModel的期望值從TimeSpan?更改爲正常string,但沒有可察覺的差異(即使錯誤消息相同)。

我猜測問題出在我以下詳述的範圍之外(儘管控制器和模型相對是香草,所以我迷失在其他地方看)或者還有更多的東西我不明白模型綁定(有很多我不明白模型綁定已經!)。

回答

0

我已經設法解決這個問題,但我不太清楚爲什麼我修復了它,修復了它。

基本上,在UpdateViewModel內,我將「UserDefinedPeriod」更改爲「OtherPeriod」。

public class LeavePeriod 
{ 
    public int ID { get; set; } 
    public DateTime Date { get; set; } 
    public int LeaveTypeID { get; set; } 
    public Guid? Reference { get; set; } 
    public string Period { get; set; } 
    public TimeSpan? OtherPeriod { get; set; } 
} 

那麼顯然改變了所有的代碼引用到其他地方在我的代碼,包括視圖:

<span class="user-defined" style="display:none"> 
    Duration: <input class="timepicker" id="LeavePeriods_8a5522c6-57fe-40a2-95bc-b9792fbe04d3__OtherPeriod" name="LeavePeriods[8a5522c6-57fe-40a2-95bc-b9792fbe04d3].OtherPeriod" type="text" value="" /> 
</span> 

然後,這似乎解決這個問題。我不確定改變工作的具體原因是什麼 - 所以我對任何可能導致它仍然存在的意見持開放態度。然而,這種調整對我來說是一個解決方案,並且可能適用於將來有此問題的任何其他人。

相關問題