2012-04-23 16 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のようになります出力:ユーザーが(Ajax.BeginForm構造体を経由して設定)アヤックス(MVC3 & jQueryの関与している)を使用してフォームを送信したときに

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

問題が表示されます。

@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は、Model.LeavePeriods.UserDefinedPeriodに1つのエラーがあるため、falseを返します。これは、最後にユーザーに表示されるエラーと同じです。

参考のために、コントローラは次のとおりです。

[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?の私はどこに問題があるのか​​を見極めるためのアイディアが不足しています。 ViewModelの期待値をTimeSpan?から通常のstringに変更しようとしましたが、エラーメッセージは同じです。

私は、以下で詳しく説明したスコープの外にあることを推測しています(しかし、コントローラーとモデルは比較的バニラなので、どこから見えるか分かりません)私はモデルバインディングについて理解していません(モデルバインディングについてはまだ理解していません)。

答えて

0

私はこの問題を解決することができましたが、私が修正したものがなぜ修正されたのか、あまりにもわかりません。

基本的に、UpdateViewModelでは、「UserPefiod」という名前に変更されました。

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> 

これは、問題を解決するように見えました。私は変更作業の具体的な理由が何であるか分かりません - それで、何が起こったのかについてのコメントはいつでも公開しています。しかし、この微調整は私のための修正であり、今後この問題を抱える他の人にとってはうまくいくかもしれません。

関連する問題