検証に失敗しているように見える検証中のフィールドに問題がありますが、完了するための要件はありません。私はすべての情報を含めようとしますので、このような長い質問投稿をお詫びします!
作成された 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" など) を入力すると、値がクリアされ、何も入力しなかったかのように上記のフィールド必須メッセージが表示されます。(仮定: 'Boris' は に格納
TimeSpan?
できないため、ビューに戻すことができないため、値がクリアされていると思います)
ブレークポイントを使用してさまざまな値を調べた結果、次の結論に達しました。
- 値は Request.Form に存在し、グループ化された他の値とともに表示できます。
- 値はモデル内に存在し、VS のブレークポイントを使用して調べることで確認できます。
- Model.LeavePeriods.UserDefinedPeriod に 1 つのエラーがあるため、 ModelState.IsValid が返さ
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.
}
}
この問題について私を最も混乱させているのは、TimeSpan?
列挙可能な WorkingPeriod 内の両方の s など、問題を引き起こさない同様の方法で構築された他のボックスがあることです。何が問題なのかを確認するためにどこを見ることができるかについてのアイデアが不足しています。ViewModel の期待値を aTimeSpan?
から通常の値に変更してみましたstring
が、認識できる違いはありません (エラー メッセージも同じでした)。
問題は、以下で詳しく説明する範囲外にあると推測しています (ただし、コントローラーとモデルは比較的単純なので、他にどこを見ればよいかわかりません)。モデル バインディングについて理解する (そして、モデル バインディングについてまだ理解していないことがたくさんあります!)。