Thông thường bạn chỉ chuyển hướng sau bài đăng thành công (không có lỗi Xác thực mẫu), nếu không bạn sẽ gửi lại trang có thông báo lỗi xác thực.
Các redirect trong mẫu PRG ngăn đôi niêm yết, do đó không có hại cho gửi lại cùng một trang (+ thông báo lỗi) vì bài đã không thành công và sẽ không được trừ khi một cái gì đó thay đổi để làm xác nhận qua.
Sửa:
Dường như bạn đang tìm kiếm thông qua ModelState
để yêu cầu (chuyển hướng) bên cạnh. Điều này có thể được thực hiện bằng cách sử dụng TempData
để lưu trữ ModelState
tối đa yêu cầu tiếp theo. FYI, TempData
sử dụng Phiên.
Điều này có thể được triển khai với ActionFilters
. Ví dụ có thể được tìm thấy trong các mã dự án MvcContrib: ModelStateToTempDataAttribute
này cũng đã được nhắc đến cùng với mẹo khác trong bài viết một 'thực hành tốt nhất' trên weblogs.asp.net (dường như tác giả đã chuyển blog, nhưng tôi không thể tìm thấy bài viết này trên blog mới). Từ bài viết:
Một trong những vấn đề với mẫu này là khi xác thực không thành công hoặc bất kỳ ngoại lệ nào xảy ra, bạn phải sao chép ModelState vào TempData. Nếu bạn đang làm nó bằng tay, hãy dừng lại nó, bạn có thể làm điều này tự động với lọc hành động, như sau:
khiển
[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard"), StoryListFilter, ImportModelStateFromTempData]
public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page)
{
//Other Codes
return View();
}
[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData]
public ActionResult Submit(string userName, string url)
{
if (ValidateSubmit(url))
{
try
{
_storyService.Submit(userName, url);
}
catch (Exception e)
{
ModelState.AddModelError(ModelStateException, e);
}
}
return Redirect(Url.Dashboard());
}
lọc hành động
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute
{
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}
public class ExportModelStateToTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//Only export when ModelState is not valid
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
//Export if we are redirecting
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}
base.OnActionExecuted(filterContext);
}
}
public class ImportModelStateFromTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
if (modelState != null)
{
//Only Import if we are viewing
if (filterContext.Result is ViewResult)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
else
{
//Otherwise remove it.
filterContext.Controller.TempData.Remove(Key);
}
}
base.OnActionExecuted(filterContext);
}
}
Điều đó không đúng. Có nhiều tác hại ... tất cả POST phải được theo sau bởi chuyển hướng. (1) Đây là cách duy nhất để xóa yêu cầu POST khỏi lịch sử trình duyệt (2) Nếu không, người dùng nhấn BACK hoặc REFRESH sẽ nhận được xác nhận "gửi lại" gây nhầm lẫn và khó chịu (3) Người dùng chọn "gửi lại" sẽ không biết cách kết quả cuối cùng của hành động có thể là! Đây là một dấu hiệu của các ứng dụng web chất lượng chuyên nghiệp trong hơn 15 năm. (Không phổ biến trong ASP hoặc ASP.NET ứng dụng web mặc dù) Hơn nữa ngay cả một GET * cố gắng * một thay đổi trạng thái không lặp lại nên được chuyển hướng. – Jack
Quan điểm của tôi đơn giản là nếu Xác thực mẫu không thành công, trạng thái máy chủ không được thay đổi và do đó ngay cả khi yêu cầu POST giống nhau được gửi lại, trạng thái máy chủ vẫn không thay đổi.Nhưng nếu bạn cảm thấy mạnh mẽ về việc ngăn chặn xác nhận gửi lại phiền toái cho trường hợp cụ thể này (POST không thành công mà không có thay đổi trạng thái máy chủ), tại sao bạn không chuyển hướng đơn giản? Có thể bạn sẽ cần một phiên làm việc (ví dụ: TempData) để thực hiện ít nhất thông báo lỗi xác thực cho yêu cầu được chuyển hướng và thông báo cho người dùng tại sao POST không thành công. Nhưng sau đó một lần nữa, hiển thị trạng thái phiên trong một yêu cầu GET không phải là rất RESTful ... – marapet
"trạng thái máy chủ không thay đổi" // yêu cầu này không phải là, nhưng bạn giả định rằng thời gian tới nó cũng sẽ không bị thay đổi// bạn không thể đưa ra giả thiết // đó cũng chỉ là một phần của vấn đề // và việc đánh dấu trùng lặp phải được thực hiện phía máy chủ để mạnh mẽ // "đơn giản là chuyển hướng" làm cách nào để truy cập vào ModelState theo yêu cầu tiếp theo? – Jack