Khi tôi sử dụng mô hình mặc định ràng buộc để ràng buộc tham số biểu mẫu cho đối tượng phức tạp là tham số cho một hành động, khuôn khổ ghi nhớ các giá trị được chuyển đến yêu cầu đầu tiên, có nghĩa là mọi yêu cầu tiếp theo đối với hành động đó sẽ nhận được dữ liệu giống như lần đầu tiên. Các giá trị tham số và trạng thái xác thực được duy trì giữa các yêu cầu web không liên quan.ASP.NET MVC Beta 1: DefaultModelBinder giữ nguyên trạng thái tham số và xác thực giữa các yêu cầu không liên quan
Đây là mã điều khiển của tôi (service
đại diện cho quyền truy cập vào các back-end của ứng dụng):
[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);
}
xem aspx của tôi (gõ mạnh như ViewPage<RunTime
>) chứa chỉ thị như:
<%= Html.TextBox("newRunTime.Time", ViewData.Model.Time) %>
Điều này sử dụng lớp DefaultModelBinder
, là meant to autobind my model's properties.
Tôi nhấn trang, nhập dữ liệu hợp lệ (ví dụ: thời gian = 1). Ứng dụng lưu chính xác đối tượng mới với thời gian = 1. Sau đó, tôi nhấn lại lần nữa, nhập dữ liệu hợp lệ khác (ví dụ: thời gian = 2). Tuy nhiên, dữ liệu được lưu là dữ liệu gốc (ví dụ: thời gian = 1). Điều này cũng ảnh hưởng đến việc xác thực, vì vậy nếu dữ liệu gốc của tôi không hợp lệ, thì tất cả dữ liệu tôi nhập trong tương lai được coi là không hợp lệ. Khởi động lại IIS hoặc xây dựng lại mã của tôi sẽ xóa trạng thái tồn tại.
Tôi có thể khắc phục sự cố bằng cách viết trình kết nối mô hình mã hóa cứng của riêng tôi, một ví dụ ngây thơ cơ bản được hiển thị bên dưới.
[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);
}
}
Tôi có thiếu gì đó không? Tôi không nghĩ rằng đó là vấn đề phiên trình duyệt vì tôi có thể tái tạo vấn đề nếu dữ liệu đầu tiên được nhập vào một trình duyệt và dữ liệu thứ hai trong một trình duyệt khác.
Điều EXACT này đã xảy ra với tôi trước đây. Phải mất một thời gian dài tôi mới hiểu được. Trong tương lai, hãy để MvcContrib đăng ký bộ điều khiển của bạn bằng cách sử dụng các phương thức mở rộng WindsorContainer của chúng. –
Mẹo hay - cảm ơn Ben. Bạn nên đặt nó như là một câu trả lời chứ không phải là một bình luận để có được một cuộc bỏ phiếu và một đánh dấu màu xanh lá cây! –
Cảm ơn Alex, tôi đã đánh đầu của tôi chống lại vấn đề chính xác này cho hầu hết các buổi chiều. –