如果您不喜欢将用户重定向到其他页面,那么通过使用我的方式,您不需要Post/Redirect/Get (PRG) Pattern并且用户保留在当前页面上而不用担心重新提交的负面影响表格!
我使用一个TempData
项目和一个Hidden field
(表单中的一个属性)在两边( )ViewModel
保持相同,并且我的标志是检测表单是否通过刷新重新提交。Guid
Server/Client
代码的最终面看起来非常简短:
行动:
[HttpPost]
public virtual ActionResult Order(OrderViewModel vModel)
{
if (this.IsResubmit(vModel)) // << Check Resubmit
{
ViewBag.ErrorMsg = "Form is Resubmitting";
}
else
{
// .... Post codes here without any changes...
}
this.PreventResubmit(vModel);// << Fill TempData & ViewModel PreventResubmit Property
return View(vModel)
}
在视图中:
@if (!string.IsNullOrEmpty(ViewBag.ErrorMsg))
{
<div>ViewBag.ErrorMsg</div>
}
@using (Html.BeginForm(...)){
@Html.HiddenFor(x=>x.PreventResubmit) // << Put this Hidden Field in the form
// Others codes of the form without any changes
}
在视图模型中:
public class OrderViewModel: NoResubmitAbstract // << Inherit from NoResubmitAbstract
{
// Without any changes!
}
你怎么看?
我通过编写 2 类使其变得简单:
NoResubmitAbstract
抽象类
ControllerExtentions
静态类(一个扩展类System.Web.Mvc.ControllerBase
)
控制器扩展:
public static class ControllerExtentions
{
[NonAction]
public static bool IsResubmit (this System.Web.Mvc.ControllerBase controller, NoResubmitAbstract vModel)
{
return (Guid)controller.TempData["PreventResubmit"]!= vModel.PreventResubmit;
}
[NonAction]
public static void PreventResubmit(this System.Web.Mvc.ControllerBase controller, params NoResubmitAbstract[] vModels)
{
var preventResubmitGuid = Guid.NewGuid();
controller.TempData["PreventResubmit"] = preventResubmitGuid ;
foreach (var vm in vModels)
{
vm.SetPreventResubmit(preventResubmitGuid);
}
}
}
不重新提交摘要:
public abstract class NoResubmitAbstract
{
public Guid PreventResubmit { get; set; }
public void SetPreventResubmit(Guid prs)
{
PreventResubmit = prs;
}
}
只需将它们放在您的 MVC 项目中并运行它... ;)