• mvc中使用一个action对多个不同名字段做remote验证


    MVC中可以在model的属性上使用Remote这个attribute来生成客户端的远程验证

    [Remote("ForbiddenWord", "RemoteValidation")]
    public string Title { get; set; }
    

    比如这样,当客户端触发验证事件时,会访问Remotevalidation/ForbiddenWord这个controller/action,他传递参数(文本框中填写的值)使用的参数名就是这个文本框的name属性,如果是通过Html.EditorFor生成的,自然就是这个model中的属性名。

    默认的参数名是由jquery.validate生成的。

    假设我们现在的action是这样的形式

    public ActionResult ForbiddenWord(string title)
    这样没问题,通过title参数,就可以获取到传来值,然后在action中对此值做具体验证
    在model中还有另外一个属性,也需要做同样的验证,如
    [Remote("ForbiddenWord", "RemoteValidation")]
    public string Body { get; set; }
    

    他生成的验证地址是RemoteValidation/ForbiddenWord?Body=???这样的url形式,action中title参数是获取不到值的。

    我不知道有没有什么办法用routes来解决这种问题,我是通过filter来解决的。

    如果说AdditionalFields能解决同一个model的问题,那对不同model,model中属性不同名的情况AdditionalFields就不行了

    既然url的参数与action的参数名对应不上,我们写action的时候就不管他了,随便起个名就OK,如

    public ActionResult ForbiddenWord(string word)
    

    同样,model中若干字段都需要做同样的验证,如

    [Remote("ForbiddenWord", "RemoteValidation")]
    public string Title { get; set; }
    [Remote("ForbiddenWord", "RemoteValidation")]
    public string Body { get; set; }
    [Remote("ForbiddenWord", "RemoteValidation")]
    public string Intro { get; set; }
    

    我们需要把url实际的参数,如title,body,intro的值,赋给action的参数word

    在action上加一个filter,OnActionExecuting中做这部分工作

    [RemoteValidationActionParamFix("word", "body", "title", "intro")]
    public ActionResult ForbiddenWord(string word)
    

    filter的参数:第一个为action要fix的参数名,后面为连接可能使用的具体名称

    以下是filter的全部代码

      1: public class RemoteValidationActionParamFixAttribute : ActionFilterAttribute
    
      2: {
    
      3:     string paramName;
    
      4:     string[] toFix;
    
      5:     
    
      6:     public RemoteValidationActionParamFixAttribute(string paramname, params string[] tofix)
    
      7:     {
    
      8:         paramName = paramname;
    
      9:         toFix = tofix;
    
     10:     }
    
     11: 
    
     12:     public override void OnActionExecuting(ActionExecutingContext filterContext)
    
     13:     {
    
     14:         if (toFix == null || toFix.Length < 1)
    
     15:         {
    
     16:             return;
    
     17:         }
    
     18:         foreach (string str in toFix)
    
     19:         {
    
     20:             try
    
     21:             {
    
     22:                 filterContext.ActionParameters[paramName] = filterContext.Controller.ValueProvider.GetValue(str).AttemptedValue;
    
     23:                 break;
    
     24:             }
    
     25:             catch
    
     26:             {
    
     27:                 continue;
    
     28:             }
    
     29:         }
    
     30:     }
    
     31: }

    image

    image

    虽然url传递使用了不同的参数名,但都验证成功了。

    在若干model中对不同名的属性做同样的验证,也可行。

    更进一步,对可能使用到的参数名,不写在attribute构造里,而通过一个配置文件设置,这样可以避免修改代码。

    如果不使用filter,使用modelbinder也可以实现同样的效果

    使用modelbinder还可以在提交时对整个表单做统一验证,而不是ajax对每个字段验证。这样可以减少客户端与服务器端之间的数据传输。不过就是要post之后错误才能显示出来,具体使用什么看情况而定。

  • 相关阅读:
    Docker的load,save和import,export的区别
    LeetCode 146. LRU 缓存机制
    mongoTemplate怎么获取MongoDB自动生成的主键_id
    $ajax()或$.get()中的请求成功时运行的函数success无法执行的解决办法
    使用$.get()请求controller出现 http://localhost:8080/../[object%20Object] 错误的问题解决
    Java利用Runtime调用Python脚本
    SpringMVC返回对象类型报错HttpMessageNotWritableException: No converter found for return value of type
    「题解」洛谷 P1801 黑匣子
    「题解」洛谷 P1717 钓鱼
    「题解」洛谷 P2571 [SCOI2010]传送带
  • 原文地址:https://www.cnblogs.com/czcz1024/p/2244741.html
Copyright © 2020-2023  润新知