[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"content-asp-mvc":3,"$f12hcgyv9fk6v4":20},{"id":4,"type":5,"slug":6,"title":7,"date":8,"category":9,"tags":10,"body_markdown":13,"permalink":14,"excerpt_src":14,"media_type":14,"media_title":14,"media_author":14,"media_url":14,"rating":14,"layout":14,"pv":15,"admin_only":15,"created_at":16,"updated_at":16,"deleted_at":14,"status":17,"html":18,"cover":19},150,"article","asp-mvc","mvc三层构架在asp中的应用","2010-02-13 14:44:28","web",[11,12],"asp","mvc","\n前段时间读了不少关于MVC的文章，试着在ASP中应用了一下，发现对于小程序，代码量会大幅度增加，但是逻辑清晰，数据封装很合理，以前需要仔细规划的代码复用竟然成了理所当然的事情。\n\n所谓MVC，即Model（模型），View（视图），Control（控制）三层架构。各部分各司其职，Model即底层构架，包含与数据库连接的部分，View即UI展示部分，与用户直接打交道，Control即控制层，负责接收View的请求并做适当预处理后交由Model处理，然后接收Model返回值并做格式化处理返回View层。简单地说，Model直接与系统底层如数据库等打交道，而不管数据出去后如何用，View只负责请求和展示数据，而不管详细流程，Control分别与View和Model打交道，并负责数据的验证、格式化等工作。\n\n写了一个获取用户资料的ASP中应用：\n\n先写Model层，定义数据库地址，打开连接数据库，获取记录。\n\n在写Model层之前定义了两个类：Cls_Config整站设置，包括数据库地址；Cls_DatabaseModel，负责打开关闭数据库连接。\n\nCls_ConfigModel.asp代码如下：\n\n```asp\n\u003C%\nClass Cls_ConfigModel\n\tPrivate i_datapath,i_sitename,i_sitedomain,i_mastermail\n\tPrivate Sub Class_Initialize()\n\t\ti_datapath=\"data\\testtdata.mdb\"\n\t\ti_sitename=\"testsite\"\n\t\ti_sitedomain=\"www.test.cn\"\n\t\ti_mastermail=\"master@test.cn\"\n\tEnd Sub\n\tPublic property get DataPath\n\t\tDataPath=server.MapPath(i_datapath)\n\tEnd property\n\tPublic property get SiteName\n\t\tSiteName=i_sitename\n\tEnd property\n\tPublic property get SiteDomain\n\t\tSiteDomain=i_sitedomain\n\tEnd property\n\tPublic property get MasterMail\n\t\tMasterMail=i_mastermail\n\tEnd property\nEnd Class\n%>\n```\n\nCls_DatabaseModel.asp代码如下：\n\n```asp\n\u003C!--#include file=\"cls_configmodel.asp\" -->\n\u003C!--#include file=\"..\u002Fpublic\u002Fcls_cache.asp\" -->\n\u003C%\nClass Cls_DatabaseModel\n\tPrivate i_config,i_cache,i_datapath\n\tPrivate i_conn\n\tPrivate Sub Class_Initialize()\n\t\tset i_cache = new Cls_Cache\n\t\tif i_cache.GetCache(\"Config\",\"DataPath\") = \"\" then\n\t\t\tset i_config = new Cls_ConfigModel\n\t\t\ti_datapath = i_config.DataPath\n\t\t\tCall i_cache.SetCache(\"Config\",\"DataPath\",i_datapath)\n\t\telse\n\t\t\ti_datapath = i_cache.GetCache(\"Config\",\"DataPath\")\n\t\tend if\n\t\tset i_cache = nothing\n\tEnd Sub\n\tPrivate Sub Class_Terminate()\n\t\tset i_config=nothing\n\tEnd Sub\n\tPublic property get Conn\n\t\tset Conn=i_conn\n\tEnd property\n\tPublic Function OpenConn()\n\t\tset i_conn=server.createobject(\"adodb.connection\")\n\t\ti_conn.open \"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"& i_datapath &\";User ID=admin;Password=;Jet OLEDB:Database Password=\"\n\tEnd Function\n\tPublic Function CloseConn()\n\t\tset i_conn=nothing\n\tEnd Function\nEnd Class\n%>\n```\n\n其中Cls_Cache是一个缓存类，这里缓存了数据库地址。\n\n用户Model层Cls_UserModel.asp代码如下：\n\n```asp\n\u003C!--#include file=\"cls_databasemodel.asp\" -->\n\u003C%\nClass Cls_UserModel\n\tPrivate i_database,i_sql,i_rs\n\tPublic UserInfo()\n\tPrivate Sub Class_Initialize()\n\t\tset i_database=new Cls_DatabaseModel\n\tEnd Sub\n\tPrivate Sub Class_Terminate()\n\t\tset i_database=nothing\n\tEnd Sub\n\tPublic Function GetUserInfo(KeyType,Key)\n\t\tselect case KeyType\n\t\tcase \"uid\"\n\t\t\ti_sql=\"select * from [MYT_User] where UserId=\" & Key\n\t\tcase \"uname\"\n\t\t\ti_sql=\"select * from [MYT_User] where UserName=&#39;\" & Key & \"&#39;\"\n\t\tend select\n\t\ti_database.OpenConn()\n\t\tset i_rs = i_database.Conn.execute(i_sql)\n\t\tif not i_rs.eof then\n\t\t\tReDim UserInfo(i_rs.fields.count)\n\t\t\tfor i=0 to i_rs.fields.count-1\n\t\t\t\tUserInfo(i)=i_rs(i)\n\t\t\tnext\n\t\telse\n\t\t\tReDim UserInfo(2)\n\t\t\tUserInfo(0)=0\n\t\t\tUserInfo(1)=\"guest\"\n\t\tEnd if\n\t\ti_rs.close\n\t\tset i_rs=nothing\n\t\ti_database.CloseConn()\n\tEnd Function\nEnd Class\n%>\n```\n\nModel层构造SQL语句并查询，然后将记录集存入UserInfo数组，供Control层调用。\n\nControl层Cls_User.asp代码如下：\n\n```asp\n\u003C!--#include file=\"..\u002Fmodel\u002Fcls_usermodel.asp\" -->\n\u003C%\nClass Cls_User\n\tPrivate i_uid,i_uname,i_user\n\tPrivate Sub Class_Initialize()\n\t\tset i_user = new Cls_UserModel\n\tEnd Sub\n\tPrivate Sub Class_Terminate()\n\t\tset i_user=nothing\n\tEnd Sub\n\tPublic property get Uid\n\t\tUid=i_uid\n\tEnd property\n\tPublic property get UName\n\t\tUname=i_uname\n\tEnd property\n\tPublic property let Uid(Userid)\n\t\ti_uid=Userid\n\t\tCall i_user.GetUserInfo(\"uid\",Userid)\n\t\tFillInfo()\n\tEnd property\n\tPublic property let UName(UserName)\n\t\ti_uname=UserName\n\t\tCall i_user.GetUserInfo(\"uname\",UserName)\n\t\tFillInfo()\n\tEnd property\n\tPrivate Function FillInfo()\n\t\ti_uid=i_user.UserInfo(0)\n\t\ti_uname=i_user.UserInfo(1)\n\tEnd Function\nEnd Class\n%>\n```\n\nCls_User类中只定义了两个属性：i_uid，i,uname。当View层给i_uid或者i_uname赋值的时候调用Model层查询用户信息，然后用Fillinfo函数填写属性供View层调用。\n\nView层UserInfo.asp代码如下：\n\n```asp\n\u003C!--#include file=\"control\u002Fcls_user.asp\" -->\n\u003C!DOCTYPE html PUBLIC \"-\u002F\u002FW3C\u002F\u002FDTD XHTML 1.0 Transitional\u002F\u002FEN\" \"http:\u002F\u002Fwww.w3.org\u002FTR\u002Fxhtml1\u002FDTD\u002Fxhtml1-transitional.dtd\">\n\u003Chtml xmlns=\"http:\u002F\u002Fwww.w3.org\u002F1999\u002Fxhtml\">\n\u003Chead>\n\u003Cmeta http-equiv=\"Content-Type\" content=\"text\u002Fhtml; charset=gb2312\" \u002F>\n\u003Ctitle>显示用户信息\u003C\u002Ftitle>\n\u003C\u002Fhead>\n\u003Cbody>\n\u003C%\nset User=new Cls_User\nfor iii=1 to 100\n\tUser.Uid=2\n\tresponse.write User.Uid\n\tresponse.write User.UName\nnext\nset User=nothing\n%>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n```\n\n这样调用逻辑就非常清晰了。\n\n试着加了一个循环（注释掉的代码），查询100个用户大约要3秒左右，看来频繁连接数据库开销确实很大。\n\n另外，循环的时候变量不能用i，不然只能显示第一个用户信息，不知何故。\n\n三层构架的大致思想基本算是掌握了，缓存应用还不够自如，模板类的实现还没开始。任重道远。\n\nPS：今天大年三十，祝所有人幸福安康！\n",null,0,"2026-08-28 04:37:17","published","\u003Cp>前段时间读了不少关于MVC的文章，试着在ASP中应用了一下，发现对于小程序，代码量会大幅度增加，但是逻辑清晰，数据封装很合理，以前需要仔细规划的代码复用竟然成了理所当然的事情。\u003C\u002Fp>\n\u003Cp>所谓MVC，即Model（模型），View（视图），Control（控制）三层架构。各部分各司其职，Model即底层构架，包含与数据库连接的部分，View即UI展示部分，与用户直接打交道，Control即控制层，负责接收View的请求并做适当预处理后交由Model处理，然后接收Model返回值并做格式化处理返回View层。简单地说，Model直接与系统底层如数据库等打交道，而不管数据出去后如何用，View只负责请求和展示数据，而不管详细流程，Control分别与View和Model打交道，并负责数据的验证、格式化等工作。\u003C\u002Fp>\n\u003Cp>写了一个获取用户资料的ASP中应用：\u003C\u002Fp>\n\u003Cp>先写Model层，定义数据库地址，打开连接数据库，获取记录。\u003C\u002Fp>\n\u003Cp>在写Model层之前定义了两个类：Cls_Config整站设置，包括数据库地址；Cls_DatabaseModel，负责打开关闭数据库连接。\u003C\u002Fp>\n\u003Cp>Cls_ConfigModel.asp代码如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>&lt;%\nClass Cls_ConfigModel\n\tPrivate i_datapath,i_sitename,i_sitedomain,i_mastermail\n\tPrivate Sub Class_Initialize()\n\t\ti_datapath=&quot;data\\testtdata.mdb&quot;\n\t\ti_sitename=&quot;testsite&quot;\n\t\ti_sitedomain=&quot;www.test.cn&quot;\n\t\ti_mastermail=&quot;master@test.cn&quot;\n\tEnd Sub\n\tPublic property get DataPath\n\t\tDataPath=server.MapPath(i_datapath)\n\tEnd property\n\tPublic property get SiteName\n\t\tSiteName=i_sitename\n\tEnd property\n\tPublic property get SiteDomain\n\t\tSiteDomain=i_sitedomain\n\tEnd property\n\tPublic property get MasterMail\n\t\tMasterMail=i_mastermail\n\tEnd property\nEnd Class\n%&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Cls_DatabaseModel.asp代码如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>&lt;!--#include file=&quot;cls_configmodel.asp&quot; --&gt;\n&lt;!--#include file=&quot;..\u002Fpublic\u002Fcls_cache.asp&quot; --&gt;\n&lt;%\nClass Cls_DatabaseModel\n\tPrivate i_config,i_cache,i_datapath\n\tPrivate i_conn\n\tPrivate Sub Class_Initialize()\n\t\tset i_cache = new Cls_Cache\n\t\tif i_cache.GetCache(&quot;Config&quot;,&quot;DataPath&quot;) = &quot;&quot; then\n\t\t\tset i_config = new Cls_ConfigModel\n\t\t\ti_datapath = i_config.DataPath\n\t\t\tCall i_cache.SetCache(&quot;Config&quot;,&quot;DataPath&quot;,i_datapath)\n\t\telse\n\t\t\ti_datapath = i_cache.GetCache(&quot;Config&quot;,&quot;DataPath&quot;)\n\t\tend if\n\t\tset i_cache = nothing\n\tEnd Sub\n\tPrivate Sub Class_Terminate()\n\t\tset i_config=nothing\n\tEnd Sub\n\tPublic property get Conn\n\t\tset Conn=i_conn\n\tEnd property\n\tPublic Function OpenConn()\n\t\tset i_conn=server.createobject(&quot;adodb.connection&quot;)\n\t\ti_conn.open &quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=&quot;&amp; i_datapath &amp;&quot;;User ID=admin;Password=;Jet OLEDB:Database Password=&quot;\n\tEnd Function\n\tPublic Function CloseConn()\n\t\tset i_conn=nothing\n\tEnd Function\nEnd Class\n%&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>其中Cls_Cache是一个缓存类，这里缓存了数据库地址。\u003C\u002Fp>\n\u003Cp>用户Model层Cls_UserModel.asp代码如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>&lt;!--#include file=&quot;cls_databasemodel.asp&quot; --&gt;\n&lt;%\nClass Cls_UserModel\n\tPrivate i_database,i_sql,i_rs\n\tPublic UserInfo()\n\tPrivate Sub Class_Initialize()\n\t\tset i_database=new Cls_DatabaseModel\n\tEnd Sub\n\tPrivate Sub Class_Terminate()\n\t\tset i_database=nothing\n\tEnd Sub\n\tPublic Function GetUserInfo(KeyType,Key)\n\t\tselect case KeyType\n\t\tcase &quot;uid&quot;\n\t\t\ti_sql=&quot;select * from [MYT_User] where UserId=&quot; &amp; Key\n\t\tcase &quot;uname&quot;\n\t\t\ti_sql=&quot;select * from [MYT_User] where UserName=&amp;#39;&quot; &amp; Key &amp; &quot;&amp;#39;&quot;\n\t\tend select\n\t\ti_database.OpenConn()\n\t\tset i_rs = i_database.Conn.execute(i_sql)\n\t\tif not i_rs.eof then\n\t\t\tReDim UserInfo(i_rs.fields.count)\n\t\t\tfor i=0 to i_rs.fields.count-1\n\t\t\t\tUserInfo(i)=i_rs(i)\n\t\t\tnext\n\t\telse\n\t\t\tReDim UserInfo(2)\n\t\t\tUserInfo(0)=0\n\t\t\tUserInfo(1)=&quot;guest&quot;\n\t\tEnd if\n\t\ti_rs.close\n\t\tset i_rs=nothing\n\t\ti_database.CloseConn()\n\tEnd Function\nEnd Class\n%&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Model层构造SQL语句并查询，然后将记录集存入UserInfo数组，供Control层调用。\u003C\u002Fp>\n\u003Cp>Control层Cls_User.asp代码如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>&lt;!--#include file=&quot;..\u002Fmodel\u002Fcls_usermodel.asp&quot; --&gt;\n&lt;%\nClass Cls_User\n\tPrivate i_uid,i_uname,i_user\n\tPrivate Sub Class_Initialize()\n\t\tset i_user = new Cls_UserModel\n\tEnd Sub\n\tPrivate Sub Class_Terminate()\n\t\tset i_user=nothing\n\tEnd Sub\n\tPublic property get Uid\n\t\tUid=i_uid\n\tEnd property\n\tPublic property get UName\n\t\tUname=i_uname\n\tEnd property\n\tPublic property let Uid(Userid)\n\t\ti_uid=Userid\n\t\tCall i_user.GetUserInfo(&quot;uid&quot;,Userid)\n\t\tFillInfo()\n\tEnd property\n\tPublic property let UName(UserName)\n\t\ti_uname=UserName\n\t\tCall i_user.GetUserInfo(&quot;uname&quot;,UserName)\n\t\tFillInfo()\n\tEnd property\n\tPrivate Function FillInfo()\n\t\ti_uid=i_user.UserInfo(0)\n\t\ti_uname=i_user.UserInfo(1)\n\tEnd Function\nEnd Class\n%&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Cls_User类中只定义了两个属性：i_uid，i,uname。当View层给i_uid或者i_uname赋值的时候调用Model层查询用户信息，然后用Fillinfo函数填写属性供View层调用。\u003C\u002Fp>\n\u003Cp>View层UserInfo.asp代码如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>&lt;!--#include file=&quot;control\u002Fcls_user.asp&quot; --&gt;\n&lt;!DOCTYPE html PUBLIC &quot;-\u002F\u002FW3C\u002F\u002FDTD XHTML 1.0 Transitional\u002F\u002FEN&quot; &quot;http:\u002F\u002Fwww.w3.org\u002FTR\u002Fxhtml1\u002FDTD\u002Fxhtml1-transitional.dtd&quot;&gt;\n&lt;html xmlns=&quot;http:\u002F\u002Fwww.w3.org\u002F1999\u002Fxhtml&quot;&gt;\n&lt;head&gt;\n&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\u002Fhtml; charset=gb2312&quot; \u002F&gt;\n&lt;title&gt;显示用户信息&lt;\u002Ftitle&gt;\n&lt;\u002Fhead&gt;\n&lt;body&gt;\n&lt;%\nset User=new Cls_User\nfor iii=1 to 100\n\tUser.Uid=2\n\tresponse.write User.Uid\n\tresponse.write User.UName\nnext\nset User=nothing\n%&gt;\n&lt;\u002Fbody&gt;\n&lt;\u002Fhtml&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>这样调用逻辑就非常清晰了。\u003C\u002Fp>\n\u003Cp>试着加了一个循环（注释掉的代码），查询100个用户大约要3秒左右，看来频繁连接数据库开销确实很大。\u003C\u002Fp>\n\u003Cp>另外，循环的时候变量不能用i，不然只能显示第一个用户信息，不知何故。\u003C\u002Fp>\n\u003Cp>三层构架的大致思想基本算是掌握了，缓存应用还不够自如，模板类的实现还没开始。任重道远。\u003C\u002Fp>\n\u003Cp>PS：今天大年三十，祝所有人幸福安康！\u003C\u002Fp>\n","",{"total":15,"totalRoots":15,"comments":21,"pv":15},[]]