MVC专题研究(三)——数据绑定和传送

 一、HTML页面数据传输机制:

                如果你之前学习过ASP或者PHP,建议你完全可以跳开这一章节,因为您应该对纯HTML页面的数据传输规律了如指掌;但是如果你是一个纯ASP.NET程序员,建议你应该先从这里起步——因为ASP.NET过于优秀的设计会使你“一叶障目,不见泰山”——在完全不了解HTML页面数据传输的情况下,学习MVC设计模式显然是不可能的。

                一个普通的HTML页面(假如你曾经尝试右键鼠标,然后“查看源代码”查看你的运行的aspx页面),你将会发现这样一些东西(以下是截取和本章节有关的片段):

<form method="post" action="WebForm1.aspx" id="form1">

<input type=”hidden” id=”…”…../>

<input type=”text” id=”…” …./>

<input type=”submit” value=”submit”…./>

</form>

                ASP.NET中那些所谓的服务器控件的本质还是HTML控件,只不过在编译和运行的过程中被解析成了标准的HTML代码返回请求的客户端了。你拖拽的一个按钮(Button)被解析成了一个submit按钮,该按钮是一个提交按钮。必须放置在form中,否则就会发生错误——为什么呢?因为你运行你的ASPX页面的时候点击这个按钮,观察IE偏右的状态栏中发现进度条会突然“一闪而过”,伴随着您的当前页面刷新了一次。这个功劳应该归功于Form,注意看action这里一块——WebForm1.aspx,这个不正式你现在运行的页面名称?是的,也就是说,当你点击了这个本质是submit的按钮的同时,由于它在Form中,浏览器自动读取action中的路径,像服务器发出一个WebForm1.aspx页面的请求而已。当发出请求时,你在文本框(被解析成了“<input type=”text”……>”)输入的东西就会自动跟随当前那个请求被发送到action所指定的页面。

                Action的路径可以是“相对路径”和“绝对路径”:

所谓相对路径就是从根目录开始加上自己当前页面的所在的路径(比如你的这个HTML页面在根路径的“files”文件夹下,那么此时路径是:http://localhost:[端口号]/,加上action中的页面所在的路径和action那个请求的文件名,变成:http://localhost:[端口号]/files/WebForm1.aspx。此时它就会到你根目录的files文件夹下找WebForm1.apsx页面,找不到就返回一个出错的信息了。

绝对路径就是不取决于当前文件的路径,用人为的方式直接从根目录开始指定,以“/”开头。如果你是action=”/WebForm1.aspx”,那么如果这个页面在files文件夹下,就会抛出一个找不到的异常,因为你指定从根目录下搜寻该页面的。

                Method是指定发送的方式。如果你想验证我的这句话,那么不妨你就创建两个HTML文档,其中page1<body>标签下应该存在这样一些内容:

                <form action=”page2” method=”get”>

                                <input type=”text” value=”Hello” name=”txt”…/>

                                <input type=”submit” value=”submit”/>

                </form>

                当您点击submit按钮,你将会发现地址栏上是http://.../page1.html?txt=Hello这样的类似内容,可见当前页面包含在Form里的东西的的确确可以传输到另外一个页面。如果改成post,包含问号的这一部分就会完全消失,但是这不代表没有将值传过去。因为接受页面也是HTML类型,所以“暂时”无法接受并且显示数据得以验证。如果是服务器页面(*.aspx),直接可以使用Response.Write(Request[“txt”])的方式输出得以验证了。

 

二、MVC中数据传输形式:

                仔细查看我的MVC组织架构,MvcDemo是一个根目录(相当于http://localhost:[端口号]的部分),因为我的URL定义是{controller}/{action}形式,所以直接以绝对路径的形式出现“action=/Controller名”。这就是MVCaction路径的写法。

                然后我们再来看看当一个action接受了从远处客户端请求的参数,如何获取呢?学习过ASP.NET的人理所当然Request[id]方法。当然这是一个。实际上,在接受Form表单的参数还有两种方法:

              1)使用FormCollection类。你只要把函数写成XXX (FormCollection params)的形式,直接从params[string key]的方式也可以获得。这个在获取表单数据的时候几乎和直接Request[id]一样,没有多大意思。不过后续的数据绑定就有好戏看了。

                2)使用函数(方法)参数,就像我一样——使用和表单中一些input等控件中name同名的参数而已,因为MVC会自动绑定。不过再次提醒您——有些参数不一定存在(比如刚开始的当前页数是没有的,为null的,此时如果让系统自动转化成int肯定会发生错误),那么我的建议就是对于某些基本类型最好使用int?的形式,或者是采用DefaultSettingsValue(默认值)来表示(如果没有值,自动采用默认值)。

 

三、MVC中数据自动绑定:

                AddItemEdit中不知道你注意到一个问题没有——我没有使用以上两种方式进行获取参数,然后实例化一个类,分别给其属性赋值,最后在执行Linq的保存……我就是把SaveTypeSaveItem的参数直接使用了一个类,形式如下:

                Public  ActionResult SaveType (HomeFinanceType type)

或许你会提出“我怎么在传输的过程中去传递一个类以便实例化?”的问题,实际上,你观察我的AddItem中每一个页面的”TextBox”或者是”TextArea”的名称都是映射HomeFinanceType的属性名称,这样就会自动进行绑定了。当然,可以缺省一些参数,那么type中那个缺省的是null

前面说过FormCollections 也可以绑定,不过似乎必直接类绑定要“麻烦”点,你要额外待用内部函数UpdateModel<T>的形式进行绑定,以便使得提交的数值会自动变更到你设定的那个类中,它有两种形式,假设我存在这样的代码:

HomeFinanceType type = new HomeFinanceType();

1Update<HomeFinanceType>(type);

2Update<HomeFinanceType>(type, new {“typeName”});

                第一个是缺省的,表示将key逐一映射成该实例type的属性,然后分别取对应的value给赋值,如遇不存在的自动设置null;第二个是表示将指定的某个key映射成属性,然后取数值进行赋值。

你可能感兴趣的:(数据绑定)