Когда я использую привязку модели по умолчанию для привязки параметров формы к сложному объекту, который является параметром для действия, каркас запоминает значения, переданные первому запросу, то есть любой последующий запрос к этому действию получает те же данные первый. Значения параметров и состояние проверки сохраняются между несвязанными веб-запросами.
Вот мой код контроллера (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
, который предназначен для автоматического связывания свойств моей модели .
Я попал на страницу, введите правильные данные (например, время = 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);
}
}
Я что-то упустил? Я не думаю, что это проблема сеанса браузера, поскольку я могу воспроизвести проблему, если первые данные вводятся в одном браузере, а вторые - в другом.