不用asp.net MVC,用WebForm照樣能夠實現MVC(請看最後一句話)

    在《避開WebForm天坑,擁抱ASP.Net MVC吧》這篇博客中我講到了ASP.net WebForm因爲一些先天的「誘導犯罪」的缺陷,如今用ASP.net MVC的公司愈來愈多。可是根據那篇文章末尾的"ASP.net MVC的免費網絡公開課"調查表的統計,咱們發現有一大半的人尚未使用過ASP.Net MVC,而沒用過ASP.net MVC的人中居然有不少人人是由於感受ASP.Net 難、沒時間學。調查表分析數據以下:html

 

 

    初看ASP.net確實難:複雜的路由機制、 ViewData/ViewBag/TempData、過濾器、Razor、Layout、XXXHelper、驗證、WebAPI、依賴注入、單元測試……光看這一堆概念頭就暈了,「仍是拖控件簡單」。前端

    其實學習一個新的框架,只要搞清他的原理就會「豁然開朗」,再看其餘的東西就不會感受恐懼了。程序員

    這篇文章我將會帶着你們搞明白什麼叫MVC模式,而且帶着你們用你們熟悉的Asp.Net WebForm實現MVC!數據庫

    對!你沒聽錯!緩存

    用Asp.Net WebForm實現MVC!安全

 

    再次感覺一下ASP.net WebForm吧。服務器

   假設有一個Person對象的集合,咱們要在網頁中以html渲染,那麼要以下編寫網絡

<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();
}

 

這樣作的缺點是C#代碼中訪問了apsx中的控件Repeater1,也就是在aspx中必需要有一個Repeater類型、Id爲Repeater1的控件,這樣aspx就和C#代碼耦合在了一塊兒。麻煩在哪兒呢?併發

1)若是aspx有兩個地方都要用list了,那麼就要寫兩組DataSource=list;DataBind();

2)若是aspx中忽然不想要Repeater了,把Repeater1刪掉C#代碼就會報錯

3)Aspx中突然不想用Repeater進行數據的顯示了,想換別的控件,那麼C#代碼也要改

 

再好比,在ASP.Net WebForm中,實現加法計算器會以下實現:

<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();
}

 

    後臺的C#代碼和aspx的耦合要求aspx視圖中必須有三個名字各爲TextBox一、TextBox二、TextBox3的TextBox類型的服務器控件。若是我想把計算的結果從TextBox改爲span就不行。前端設計人員看到TextBox絕對沒有input親切,前端人員對input 的把控能力會被TextBox更好。另外沒必要再說WebForm引入的ViewState、頁面生命週期、ClientID等使人做嘔的問題。 

    有同窗會說了:你有病嗎,開發時候aspx怎麼可能老是變來變去,即便aspx變了,你C#代碼也就變唄,有什麼大不了的?

    若是說系統小的話可能無所謂,對於比較複雜的系統,若是aspx和C#這樣緊密的耦合,維護還會特別麻煩。並且若是實現像一些CMS系統那樣能夠動態修改模板文件的話就是存在着「C#沒法預測、沒法強制要求aspx到底怎麼寫」的問題。

 

    這還僅僅是展現一個集合的問題,若是要展現複雜的扁平化數據或者須要從用戶輸入中獲取數據,用這種方式更災難。

    那麼MVC思想怎麼解決呢?邏輯代碼(Controller)不直接和頁面視圖(View)進行交互,他們之間用Model(數據模型)做爲溝通的通道。當須要展現數據的時候由Controller收集到數據(Model),而後把數據交給View去展現;當Controller須要讀取View中用戶輸入內容的時候,框架會把View中的數據映射到Model中,而後Controller讀取Model中的數據進行後續的邏輯處理。這樣就把邏輯代碼(俗稱C#代碼)和視圖(俗稱頁面)進行解耦了。

    光說概念沒用,仍是先看代碼把。下面使用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>

 

注意,我把aspx相關的兩個自動生成的.cs文件刪掉了,而且把<%@Page%>標籤的AutoEventWireup、CodeBehind、Inherits等幾個屬性也都幹掉了,這樣aspx就變成了一個純粹的「模板引擎」

 

做爲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是在服務器內部把請求處理權轉交給"PersonsView.aspx"處理。HttpContext中的Items的生命週期是整個請求響應,這樣咱們在通常處理程序中把數據放到context.Items中,而後在"PersonsView.aspx"中就能夠能夠經過Context.Items["persons"]拿到這個數據從而進行數據的展現。

     爲何把數據放到HttpContext.Items中呢。因爲Transfer僅僅是服務器內部處理權的轉接,可是仍然是在一個請求中的,因此放到Context.items是最好的。若是放到Session、Application等中會有併發的問題。 

    這樣Controller(通常處理程序)和View(aspx)之間只要維持一個「要傳遞一個名字爲persons類型的List<Person>」這樣一個弱耦合關係便可,至於aspx用不用這個persons、用幾回persons、怎麼用persons,你Controller都不用管。 

按照一樣方法改造加法計算器

 

下面是視圖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>加法計算器</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");
}

 

    因爲View和Controller之間傳遞的數據比較複雜、比較多,爲了簡化開發,這樣用了dynamic 動態類型。熟悉ASP.Net MVC的同窗是否是感受這個和ASP.net MVC中的ViewBag殊途同歸呢。

    在這個加法計算器中若是我想把結算結果用span顯示,那麼只要把<input type="text" name="i3" value="<%=viewBag.i3%>" />改爲<span><%=viewBag.i3%></span>就能夠了。美工也容易介入頁面美化。

    若是我想把頁面的Title從「加法計算器」改爲「3和5相加的結果」,那麼只要這樣改就能夠:<title><%=viewBag.i1 %>和<%=viewBag.i2 %>相加的結果</title>    這樣model裏的數據我aspx想用幾回用幾回,想怎麼用就怎麼用。有沒有感受到和WebForm不同的地方呢?

 

   因此只要思想一想通了,其實實現MVC模式不必定要用ASP.net MVC,我見過不少項目都是本身搞的MVC機制。

    固然既然ASP.net MVC已經這麼優秀了,通常狀況不必像我這樣從新本身發明一個輪子用。 

    這裏給你們講ASPX實現MVC只是用你們熟悉的東西讓你們明白原理,工程項目應用仍是直接用ASP.Net MVC吧。

 

如鵬網.Net培訓班正在報名,有網絡的地方就能夠參加如鵬網的學習,學完就能高薪就業,點擊此處瞭解

 

    三年前只要懂「三層架構」就能夠說「精通分層架構」;如今則須要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值錢;

    三年前只要會SQLServer就能夠說本身「精通數據庫開發」;如今則需還須要掌握MySQL等開源數據庫才能說是「.Net開源」時代的程序員;

    三年前只要會進行用戶上傳內容的安全性處理便可;如今則須要熟悉雲存儲、CDN等才能在雲計算時代遊刃有餘;

    三年前只要掌握Lucene.Net就會說本身「熟悉站內搜索引擎開發」;如今你們都用ElasticSearch了,你還用Lucene.Net就太老土了;

    三年前發郵件仍是用SmtpClient;如今作大型網站發郵件必須用雲郵件引擎;

    三年前緩存就是Context.Cache;如今則是Redis、Memcached的天下;

    如鵬網再次引領.Net社區技術潮流!點擊此處瞭解如鵬網.Net最新課程

相關文章
相關標籤/搜索