不用asp.net MVC,用WebForm照样能够实现MVC
? 在《避開(kāi)WebForm天坑,擁抱ASP.Net?MVC吧》這篇博客中我講到了ASP.net?WebForm由于一些先天的“誘導(dǎo)犯罪”的缺陷,如今用ASP.net?MVC的公司越來(lái)越多。可是依據(jù)那篇文章末尾的"ASP.net?MVC的免費(fèi)網(wǎng)絡(luò)公開(kāi)課"調(diào)查表的統(tǒng)計(jì),我們發(fā)現(xiàn)有一大半的人還沒(méi)有使用過(guò)ASP.Net?MVC。而沒(méi)用過(guò)ASP.net?MVC的人中居然有非常多人人是由于感覺(jué)ASP.Net?難、沒(méi)時(shí)間學(xué)。調(diào)查表分析數(shù)據(jù)例如以下:
?
?
? ? 初看ASP.net確實(shí)難:復(fù)雜的路由機(jī)制、?ViewData/ViewBag/TempData、過(guò)濾器、Razor、Layout、XXXHelper、驗(yàn)證、WebAPI、依賴注入、單元測(cè)試……光看這一堆概念頭就暈了。“還是拖控件簡(jiǎn)單”。
? ? 事實(shí)上學(xué)習(xí)一個(gè)新的框架,僅僅要搞清他的原理就會(huì)“豁然開(kāi)朗”,再看其它的東西就不會(huì)感覺(jué)恐懼了。
? ? 這篇文章我將會(huì)帶著大家搞明確什么叫MVC模式。而且?guī)е蠹矣么蠹沂煜さ腁sp.Net?WebForm實(shí)現(xiàn)MVC。
? ? 對(duì)!
你沒(méi)聽(tīng)錯(cuò)!
? ? 用Asp.Net?WebForm實(shí)現(xiàn)MVC!
?
? ? 再次感受一下ASP.net WebForm吧。
? ?如果有一個(gè)Person對(duì)象的集合,我們要在網(wǎng)頁(yè)中以html渲染。那么要例如以下編寫
| 1 2 3 4 5 | <table> ????????<asp:Repeater?ID="Repeater1" runat="server"> ????????????<ItemTemplate><tr><td><%#Eval("Name") %></td><td><%#Eval("Age") %></td></tr></ItemTemplate> ????????</asp:Repeater> </table> |
C#代碼:
if(!IsPostBack) { List<Person> list = new List<Person>(); list.Add(new Person { Name = "rupeng", Age = 8 }); list.Add(new Person { Name = "qq", Age = 18 }); Repeater1.DataSource = list; Repeater1.DataBind(); }?
這樣做的缺點(diǎn)是C#代碼中訪問(wèn)了apsx中的控件Repeater1。也就是在aspx中必需要有一個(gè)Repeater類型、Id為Repeater1的控件,這樣aspx就和C#代碼耦合在了一起。麻煩在哪兒呢?
1)假設(shè)aspx有兩個(gè)地方都要用list了,那么就要寫兩組DataSource=list;DataBind()。
2)假設(shè)aspx中突然不想要Repeater了,把Repeater1刪掉C#代碼就會(huì)報(bào)錯(cuò)
3)Aspx中忽然不想用Repeater進(jìn)行數(shù)據(jù)的顯示了,想換別的控件,那么C#代碼也要改
?
再比方。在ASP.Net?WebForm中,實(shí)現(xiàn)加法計(jì)算器會(huì)例如以下實(shí)現(xiàn):
| 1 2 3 4 | <asp:TextBox?ID="TextBox1" runat="server"></asp:TextBox> +<asp:TextBox?ID="TextBox2" runat="server"></asp:TextBox> <asp:Button?ID="Button1" runat="server" OnClick="Button1_Click" Text="=" /> <asp:TextBox?ID="TextBox3" runat="server"></asp:TextBox> |
?
protected void Button1_Click(object sender, EventArgs e) {int i1 = Convert.ToInt32(TextBox1.Text);int i2 = Convert.ToInt32(TextBox2.Text);int i3 = i1 + i2;TextBox3.Text = i3.ToString(); }?
? ? 后臺(tái)的C#代碼和aspx的耦合要求aspx視圖中必須有三個(gè)名字各為TextBox1、TextBox2、TextBox3的TextBox類型的server控件。
假設(shè)我想把計(jì)算的結(jié)果從TextBox改成span就不行。
前端設(shè)計(jì)人員看到TextBox絕對(duì)沒(méi)有input親切。前端人員對(duì)input?的把控能力會(huì)被TextBox更好。另外不必再說(shuō)WebForm引入的ViewState、頁(yè)面生命周期、ClientID等令人作嘔的問(wèn)題。?
? ? 有同學(xué)會(huì)說(shuō)了:你有病嗎,開(kāi)發(fā)時(shí)候aspx怎么可能總是變來(lái)變?nèi)?#xff0c;即使aspx變了,你C#代碼也就變唄。有什么大不了的?
? ? 假設(shè)說(shuō)系統(tǒng)小的話可能無(wú)所謂,對(duì)于比較復(fù)雜的系統(tǒng),假設(shè)aspx和C#這樣緊密的耦合。維護(hù)還會(huì)特別麻煩。并且假設(shè)實(shí)現(xiàn)像一些CMS系統(tǒng)那樣能夠動(dòng)態(tài)改動(dòng)模板文件的話就是存在著“C#無(wú)法預(yù)測(cè)、無(wú)法強(qiáng)制要求aspx究竟怎么寫”的問(wèn)題。
?
? ? 這還不過(guò)展示一個(gè)集合的問(wèn)題。假設(shè)要展示復(fù)雜的扁平化數(shù)據(jù)或者須要從用戶輸入中獲取數(shù)據(jù),用這樣的方式更災(zāi)難。
? ? 那么MVC思想怎么解決呢?邏輯代碼(Controller)不直接和頁(yè)面視圖(View)進(jìn)行交互,他們之間用Model(數(shù)據(jù)模型)作為溝通的通道。當(dāng)須要展示數(shù)據(jù)的時(shí)候由Controller收集到數(shù)據(jù)(Model)。然后把數(shù)據(jù)交給View去展示;當(dāng)Controller須要讀取View中用戶輸入內(nèi)容的時(shí)候,框架會(huì)把View中的數(shù)據(jù)映射到Model中,然后Controller讀取Model中的數(shù)據(jù)進(jìn)行興許的邏輯處理。這樣就把邏輯代碼(俗稱C#代碼)和視圖(俗稱頁(yè)面)進(jìn)行解耦了。
? ? 光說(shuō)概念沒(méi)用。還是先看代碼把。以下使用MVC模式改造的“顯示Person集合”:
?
View視圖PersonsView.aspx
<%@ Page Language="C#"%> <%@ Import Namespace="System.Collections.Generic" %> <%@ Import Namespace="WebApplication1" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <body><table><%var persons = (List<Person>)Context.Items["persons"];foreach(var person in persons){%><tr><td><%=person.Name %></td><td><%=person.Age %></td></tr><%} %></table> </body> </html>?
注意,我把a(bǔ)spx相關(guān)的兩個(gè)自己主動(dòng)生成的.cs文件刪掉了,而且把<%@Page%>標(biāo)簽的AutoEventWireup、CodeBehind、Inherits等幾個(gè)屬性也都干掉了,這樣aspx就變成了一個(gè)純粹的“模板引擎”
?
作為Controller的Index.ashx的代碼例如以下:
public void ProcessRequest(HttpContext context) {List<Person> list = new List<Person>();list.Add(new Person { Name="rupeng",Age=8});list.Add(new Person { Name = "qq", Age = 18 });context.Items["persons"] = list;context.Server.Transfer("PersonsView.aspx"); }?
? ? ?這里借鑒了JSP中“request.getRequestDispatcher("index.jsp").forward(request,response)”一樣的思路。
? ? ?context.Server.Transfer是在server內(nèi)部把請(qǐng)求處理權(quán)轉(zhuǎn)交給"PersonsView.aspx"處理。HttpContext中的Items的生命周期是整個(gè)請(qǐng)求響應(yīng),這樣我們?cè)谝话闾幚沓绦蛑邪褦?shù)據(jù)放到context.Items中。然后在"PersonsView.aspx"中就能夠能夠通過(guò)Context.Items["persons"]拿到這個(gè)數(shù)據(jù)從而進(jìn)行數(shù)據(jù)的展示。
? ? ?為什么把數(shù)據(jù)放到HttpContext.Items中呢。因?yàn)門ransfer不過(guò)server內(nèi)部處理權(quán)的轉(zhuǎn)接。可是仍然是在一個(gè)請(qǐng)求中的,所以放到Context.items是最好的。
假設(shè)放到Session、Application等中會(huì)有并發(fā)的問(wèn)題。
?
? ? 這樣Controller(一般處理程序)和View(aspx)之間僅僅要維持一個(gè)“要傳遞一個(gè)名字為persons類型的List<Person>”這樣一個(gè)弱耦合關(guān)系就可以,至于aspx用不用這個(gè)persons、用幾次persons、怎么用persons。你Controller都不用管。?
依照相同方法改造加法計(jì)算器
?
以下是視圖AddView.aspx的代碼
<%@ Page Language="C#"%> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><%dynamic viewBag = Context.Items["ViewBag"]; %> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>加法計(jì)算器</title> </head> <body><form id="form1"><input type="hidden" name="action" value="addSubmit" /><input type="text" name="i1" value="<%=viewBag.i1 %>" />+<input type="text" name="i2" value="<%=viewBag.i2%>" /><input type="submit" value="=" /><input type="text" value="<%=viewBag.i3 %>" /></form> </body> </html>而AddHandler.ashx的主體代碼例如以下:
public void ProcessRequest(HttpContext context) {string action = context.Request["action"];dynamic viewBag = new System.Dynamic.ExpandoObject();if(string.IsNullOrEmpty(action)){ viewBag.i1 = ""; viewBag.i2 = ""; viewBag.i3 = ""; }else if(action=="addSubmit"){ int i1 = Convert.ToInt32(context.Request["i1"]); int i2 = Convert.ToInt32(context.Request["i2"]); int i3 = i1 + i2; viewBag.i1 = i1; viewBag.i2 = i2; viewBag.i3 = i3;}context.Items["ViewBag"] = viewBag;context.Server.Transfer("AddView.aspx"); }?
? ? 因?yàn)閂iew和Controller之間傳遞的數(shù)據(jù)比較復(fù)雜、比較多。為了簡(jiǎn)化開(kāi)發(fā),這樣用了dynamic?動(dòng)態(tài)類型。熟悉ASP.Net?MVC的同學(xué)是不是感覺(jué)這個(gè)和ASP.net?MVC中的ViewBag異曲同工呢。
? ? 在這個(gè)加法計(jì)算器中假設(shè)我想把結(jié)算結(jié)果用span顯示。那么僅僅要把<input?type="text"?name="i2"?value="<%=viewBag.i2%>"?/>改成<span><%=viewBag.i2%></span>就能夠了。美工也easy介入頁(yè)面美化。
? ??假設(shè)我想把頁(yè)面的Title從“加法計(jì)算器”改成“3和5相加的結(jié)果”,那么僅僅要這樣改就能夠:<title><%=viewBag.i1?%>和<%=viewBag.i2?%>相加的結(jié)果</title>????這樣model里的數(shù)據(jù)我aspx想用幾次用幾次,想怎么用就怎么用。
有沒(méi)有感覺(jué)到和WebForm不一樣的地方呢?
?
? ?所以僅僅要思想想通了,事實(shí)上實(shí)現(xiàn)MVC模式不一定要用ASP.net?MVC。我見(jiàn)過(guò)非常多項(xiàng)目都是自己搞的MVC機(jī)制。
? ? 當(dāng)然既然ASP.net?MVC已經(jīng)這么優(yōu)秀了,普通情況不是必需像我這樣又一次自己發(fā)明一個(gè)輪子用。這里給大家講ASPX實(shí)現(xiàn)MVC僅僅是用大家熟悉的東西讓大家明確原理,project項(xiàng)目應(yīng)用還是用ASP.Net?MVC吧。
如鵬網(wǎng).Net培訓(xùn)班正在報(bào)名,有網(wǎng)絡(luò)的地方就能夠參加如鵬網(wǎng)的學(xué)習(xí),學(xué)完就能高薪就業(yè),點(diǎn)擊此處了解
?
三年前僅僅要懂“三層架構(gòu)”就能夠說(shuō)“精通分層架構(gòu)”。如今則須要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值錢;
三年前僅僅要會(huì)SQLServer就能夠說(shuō)自己“精通數(shù)據(jù)庫(kù)開(kāi)發(fā)”;如今則需還須要掌握MySQL等開(kāi)源數(shù)據(jù)庫(kù)才干說(shuō)是“.Net開(kāi)源”時(shí)代的程序猿;
三年前僅僅要會(huì)進(jìn)行用戶上傳內(nèi)容的安全性處理就可以;如今則須要熟悉云存儲(chǔ)、CDN等才干在云計(jì)算時(shí)代游刃有余。
三年前僅僅要掌握Lucene.Net就會(huì)說(shuō)自己“熟悉站內(nèi)搜索引擎開(kāi)發(fā)”;如今大家都用ElasticSearch了,你還用Lucene.Net就太老土了。
三年前發(fā)郵件還是用SmtpClient;如今做大型站點(diǎn)發(fā)郵件必須用云郵件引擎;
三年前緩存就是Context.Cache。如今則是Redis、Memcached的天下;
如鵬網(wǎng)再次引領(lǐng).Net社區(qū)技術(shù)潮流!點(diǎn)擊此處了解如鵬網(wǎng).Net最新課程
轉(zhuǎn)載于:https://www.cnblogs.com/zsychanpin/p/7029322.html
總結(jié)
以上是生活随笔為你收集整理的不用asp.net MVC,用WebForm照样能够实现MVC的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android报“android.con
- 下一篇: 【ADO.NET基础知识】SqlConn