欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET MVC Model验证(三)

程序员文章站 2022-06-21 19:41:22
前言 上篇中说到在mvc框架中默认的model验证是在哪里验证的,还讲到defaultmodelbinder类型的内部执行的示意图,让大家可以看到默认的model验证是在哪个具体...
前言

上篇中说到在mvc框架中默认的model验证是在哪里验证的,还讲到defaultmodelbinder类型的内部执行的示意图,让大家可以看到默认的model验证是在哪个具体的方法中来执行的,本篇的主题就是模拟一下默认的实现,自定义个model绑定器继承自defaultmodelbinder类型,并且重写某些个重要的方法。

 

 

 

model验证

model验证简单运用示例

modelvalidator使用生成过程

自定义实现defaultmodelbinder进行验证

自定义modelvalidatorprovider 和modelvalidator 

validationattribute特性类使用

自定义validationattribute特性类的示例实现

 

 

自定义实现defaultmodelbinder进行验证

以下用到的示例正是修改自asp.net mvc model验证(一)篇幅中的示例,这里就不多说什么了,开始直接贴代码。

 

首先是viewmodel的定义,代码1-1。

 

代码1-1

 

复制代码

namespace mapplication.models

 

{

 

    public class registrationinformation

 

    {

 

        public string id { get; set; }

 

        public string userid { get; set; }

 

        public string password1 { get; set; }

 

        public string password2 { get; set; }

 

        public string name { get; set; }

 

    }

 

}

复制代码

 

 

控制器的定义,代码1-2:

 

代码1-2

 

 

 

复制代码

   public class modelvalidatorcontroller : controller

 

    {

 

        public actionresult index()

 

        {

 

            return view(new models.registrationinformation());

 

        }

 

        public actionresult modelvalidator(registrationinformation reginfo)

 

        {

 

            return view(reginfo);

 

        }

 

    }

复制代码

 

 

控制器方法对应视图定义,代码1-3:

 

代码1-3-1

 

index视图

 

复制代码

@model mvcapplication.models.registrationinformation

 

@{

 

    viewbag.title = "index";

 

}

 

<h2>index</h2>

 

@using (html.beginform("modelvalidator","modelvalidator"))

 

{

 

    <p>用户注册id:@html.editorfor(m=>m.id)</p>

 

    <p>用户名:@html.editorfor(m=>m.userid)</p>

 

    <p>登录密码:@html.editorfor(m=>m.password1)</p>

 

    <p>再次输入域密码:@html.editorfor(m=>m.password2)</p>

 

    <p>姓名:@html.editorfor(m=>m.name)</p>

 

    <input type="submit" value="提交" />

 

}

复制代码

代码1-3-2

 

modelvalidator视图

 

复制代码

@model mvcapplication.models.registrationinformation

 

@{

 

    viewbag.title = "modelvalidator";

 

}

 

<h2>modelvalidator</h2>

 

@html.validationsummary(true)

 

<p>用户注册id:@html.editorfor(m => m.id)

 

@html.validationmessagefor(m=>m.id)

 

</p>

 

<p>用户名:@html.editorfor(m => m.userid)

 

@html.validationmessagefor(m=>m.userid)</p>

 

<p>登录密码:@html.editorfor(m => m.password1)

 

@html.validationmessagefor(m=>m.password1)

 

</p>

 

<p>再次输入域密码:@html.editorfor(m => m.password2)

 

@html.validationmessagefor(m=>m.password2)

 

</p>

 

<p>姓名:@html.editorfor(m=>m.name)</p>

复制代码

前面所示的就是把示例演示所需的定义好,这个时候运行会发现,只不过是一个页面传值而已,什么都没有发生。现在我们来定义一下自定义的model绑定器继承自defaultmodelbinder类型。

 

代码1-4

 

复制代码

public class mycustomdefaultmodelbinder : defaultmodelbinder

    {

        protected override void setproperty(controllercontext controllercontext, modelbindingcontext bindingcontext, propertydescriptor propertydescriptor, object value)

        {

            base.setproperty(controllercontext, bindingcontext, propertydescriptor, value);

 

            switch (propertydescriptor.name)

            {

                case "id":

                    if (string.isnullorempty((string)value) || (string)value == "")

                    {

                        bindingcontext.modelstate.addmodelerror("id", "请输入id,id不能为空!");

                    }

                    break;

                case "userid":

                    if (string.isnullorempty((string)value) || (string)value == "")

                    {

                        bindingcontext.modelstate.addmodelerror("userid", "请输入用户账户,用户账户不能为空!");

                    }

                    break;

                case "password1":

                    if (string.isnullorempty((string)value) || (string)value == "")

                    {

                        bindingcontext.modelstate.addmodelerror("password1", "请输入登录密码,登录密码不能为空!");

                    }

                    break;

                case "password2":

                    if (string.isnullorempty((string)value) || (string)value == "")

                    {

                        bindingcontext.modelstate.addmodelerror("pssword2", "请再次输入密码,密码不能为空!");

                    }

                    break;

                case "name":

                    break;

            }

        }

 

        protected override void onmodelupdated(controllercontext controllercontext, modelbindingcontext bindingcontext)

        {

            base.onmodelupdated(controllercontext, bindingcontext);

            models.registrationinformation reginfo = bindingcontext.model as models.registrationinformation;

            if (bindingcontext.modelstate["password1"].errors.count == 0 && bindingcontext.modelstate["password2"].errors.count == 0)

            {

                if (reginfo.password1 != reginfo.password2)

                {

                    bindingcontext.modelstate.addmodelerror("password2", "请重新输入密码,与上次输入密码不同");

                }

            }

            if (string.compare(reginfo.name, "jinyuan", true)==0)

            {

                bindingcontext.modelstate.addmodelerror("", "您输入的名称违法了,立即更改不然查水表");

            }

        }

    }

复制代码

代码1-4中,我们重写了setproperty()方法,从上篇的知识中得知,这个方法是在propertydescriptor类型的集合中遍历执行的,所以每次进入方法内部的只是个model属性,而在setproperty()方法内部的model验证判断逻辑和asp.net mvc model验证(一)篇幅的一样。

 

而在onmodelupdated()方法中,我们首先获取了示例代码1-1中定义的viewmodel类型实例,这里有的朋友可能会问为什么不在setproperty()方法中也这样使用,而是使用propertydescriptor类型的参数来进行验证操作,因为在setproperty()方法执行的期间并没有对viewmodel完全的赋值,所以不能那样直接获取实例来使用。接着上面的说,在此之后从当前的绑定上下文的modelstate属性中获取判断密码1和密码2是否存在属性验证级的错误信息,没有的话将会对它们进行等值验证,正如上面代码所示的那样,随之验证name的时候我将错误信息添加的键值为””,这表示默认为model级验证错误信息。