当前位置导航:炫浪网>>网络学院>>网页制作>>ASP.NET教程

详解ASP.NET MVC PRG数据验证

  我们这里将要谈到的是ASP.NET MVC PRG数据验证,主要是参考一些国外关于PRG数据验证的文章,希望对大家有所帮助。

  我的理念:

  既然是ASP.NET MVC,那就肯定要用PRG。但是简单的PRG不能在输入页面显示Html.ValidationMessage,另一个就是之前的数据会被全部清空或者初始化了。

  想想要我是打了半天的字一下全没了那多惨啊。你的访客不气傻了才怪。

  OK,Google一下,找到了http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx

  阿,他叫什么名字我不认识,我也看不懂英文的版权声明,所以这只有个链接没署名了。谁认识他叫他写个C#版或者VB.NET版的版权声明吧,谢谢。

  英文不好不要紧,直接看第13点:Use PRG Pattern for Data Modification

  Controller  [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());

  }

  自定义了两个ActionFilter,阿,作者好像打错别字了。您别在意。

  ModelStateTempDataTransfer  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);

  }

  }

  因为我用的是VB.NET,直接拿工具转了放自己项目里,英文不懂照他的源代码套上去一试。

  哈,成功了,可爱的Html.ValidationMessage来了。

  但是还是没有解决数据被清空或初始化的问题。

  这下惨了,Google也好,百度也好,还是在博客园里找这找那都没找着。我估计可能我找的方法不对吧,不然这么多人都碰到的问题怎么没人发出来呢。

  最后在园子的小组里找到http://space.cnblogs.com/group/topic/7919/ 第三个回复有说ModelState.SetModelValue方法,拿过来一试,真不错。

  所以修改了一下刚才所说的两个ActionFilter中的ExportModelStateToTempData;代码如下:

  Code      Public Overrides Sub OnActionExecuted(ByVal pFilterContext As ActionExecutedContext)

  If Not pFilterContext.Controller.ViewData.ModelState.IsValid Then

  If TypeOf (pFilterContext.Result) Is RedirectResult OrElse TypeOf (pFilterContext.Result) Is RedirectToRouteResult Then                  If pFilterContext.HttpContext.Request.Form.Count > 0 Then

  Dim tFormCollection As New FormCollection(pFilterContext.HttpContext.Request.Form)

  For Each fKey As String In tFormCollection

  pFilterContext.Controller.ViewData.ModelState.SetModelValue(fKey, tFormCollection.ToValueProvider(fKey))

  Next

  pFilterContext.Controller.TempData(mKey) = pFilterContext.Controller.ViewData.ModelState

  End If

  End If

  End If

  MyBase.OnActionExecuted(pFilterContext)

  End Sub 最后说下,因为我用的VB.Net是不区分大小写的,所以我的每个参数都用p开头,临时变量用t开头,内部循环用f开头,客官将就着看吧。

相关内容
赞助商链接