デフォルトのモデル バインディングを使用してフォーム パラメータをアクションのパラメータである複雑なオブジェクトにバインドすると、フレームワークは最初のリクエストに渡された値を記憶します。つまり、そのアクションへの後続のリクエストは最初と同じデータを取得します。パラメーター値と検証状態は、関連のない Web 要求間で保持されます。
これが私のコントローラーコードです(service
アプリのバックエンドへのアクセスを表します):
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Create()
{
return View(RunTime.Default);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(RunTime newRunTime)
{
if (ModelState.IsValid)
{
service.CreateNewRun(newRunTime);
TempData["Message"] = "New run created";
return RedirectToAction("index");
}
return View(newRunTime);
}
私の .aspx ビュー ( ViewPage<RunTime
> として厳密に型指定されたもの) には、次のようなディレクティブが含まれています。
<%= Html.TextBox("newRunTime.Time", ViewData.Model.Time) %>
これは、モデルのプロパティを自動バインドするためDefaultModelBinder
のクラスを使用します。
ページにアクセスし、有効なデータを入力します (例: time = 1)。アプリは新しいオブジェクトを時間 = 1 で正しく保存します。次に、もう一度押して、別の有効なデータ (時間 = 2 など) を入力します。ただし、保存されるデータは元のものです (たとえば、時間 = 1)。これは検証にも影響するため、元のデータが無効であった場合、今後入力するすべてのデータが無効と見なされます。IIS を再起動するか、コードを再構築すると、永続化された状態がフラッシュされます。
この問題は、独自のハードコーディングされたモデル バインダーを作成することで解決できます。その基本的な単純な例を以下に示します。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([ModelBinder(typeof (RunTimeBinder))] RunTime newRunTime)
{
if (ModelState.IsValid)
{
service.CreateNewRun(newRunTime);
TempData["Message"] = "New run created";
return RedirectToAction("index");
}
return View(newRunTime);
}
internal class RunTimeBinder : DefaultModelBinder
{
public override ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
// Without this line, failed validation state persists between requests
bindingContext.ModelState.Clear();
double time = 0;
try
{
time = Convert.ToDouble(bindingContext.HttpContext.Request[bindingContext.ModelName + ".Time"]);
}
catch (FormatException)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName + ".Time", bindingContext.HttpContext.Request[bindingContext.ModelName + ".Time"] + "is not a valid number");
}
var model = new RunTime(time);
return new ModelBinderResult(model);
}
}
何か不足していますか?最初のデータが 1 つのブラウザーに入力され、2 番目のデータが別のブラウザーに入力された場合に問題を再現できるため、ブラウザー セッションの問題ではないと思います。