1. 程式人生 > 其它 >[譯]Asp.net MVC 之 Contorllers(一)

[譯]Asp.net MVC 之 Contorllers(一)

Asp.net MVC contorllers

    在Ajax全面開花的時代,ASP.NET Web Forms 開始慢慢變得落後。有人說,Ajax已經給了Asp.net致命一擊。Ajax使越來越多的控制在Html和客戶端程式碼完成。隨著時間的推移,導致了架構的變化,也使ASP.NET Web Forms有點不能適應當今潮流。

    基於當前的ASP.NET執行時環境和MVC模式,誕生了一個新的架構——ASP.NET MVC,這種組合的Web開發模式順應了當今的開發的趨勢。

    在ASP.NET MVC中,每一個請求最終就是執行一個特殊類中的Action方法。Action的執行結果被傳遞給帶有檢視模版的檢視子系統中。瀏覽器最終的響應結果就是由Action的執行結果和這個模版建立的。

    與Web Forms不同,ASP.NET MVC是由各個層的程式碼連線在一起的,這些層次之間既不是相互交叉,也不是單一一坨的模組。正因如此,根據自定義元件能很輕鬆的替換其中任何一層,這樣就提高了解決方案的可維護性和穩定性。使用ASP.NET MVC,不僅有標籤的完全控制權,還可以使用樣式和喜歡的js框架。

    儘管你想堅持使用Web Froms,但是對於當今的Web開發來說,ASP.NET MVC 確實是一個更好的選擇。我們不需要花費太多的時間去學習,但是我們必須知道怎麼運用以及MVC工作原理。如果這樣做了,那麼我們投入將會快速的帶給我們應有的回報。

  注:本系列是基於ASP.NET MVC 5。該版本是向前相容的,也就是說,一臺電腦中可以同時安裝新老版本,新版本執行不會影響現存MVC版本程式碼。

路由請求

    最初,ASP.NET平臺的開發主要是圍繞著伺服器端物理頁面請求的思想。在ASP.NET應用程式中使用的大多數的URL是由兩部分組成:包含邏輯的物理網頁的路徑,和一些填充在查詢字串中的作為引數的資料。這種方式已經使用了有些年了,現在仍在被使用。ASP.NET執行時環境沒有限制我們只能呼叫特定位置或者檔案的資源。通過寫一個專門的HTTP處理程式,並繫結到URL,我們就可以使用ASP.NET響應一個非依賴於物理檔案的請求執行程式碼。這只是ASP.NET MVC不同於ASP.NET Web Forms眾多不同中的一個方面。接下來我們看看如何通過使用一個HTTP處理程式來模擬ASP.NET MVC行為。

注:在軟體中,專業術語URI(Uniform Resource Identifier)是用於通過位置或名稱來引用的資源。當URI通過位置來標識資源時,就是URL(Uniform Resource Locator)。當URI通過名稱標識資源時,就變成了URN(Uniform Resource Name)。在這方面,ASP.NET MVC是設計來處理更通用的URI,而ASP.NET Web Forms被設計來處理位置識別物理資源

模擬ASP.NET執行時

    我們構建一個簡單的ASP.NET Web Forms應用程式,使用HTTP處理程式搞清楚ASP.NET MVC應用程式的內部機制。我們從最基本的ASP.NET Web Forms應用程式開始。

定義辨認URLs的語法

    請求的URLs不需要匹配伺服器端的物理檔案。第一步列出應用程式有意義的URLs。為了避免太特殊,我們假設支援幾個固定的URLs,把他們對映到一個HTTP處理程式模組。下面的程式碼片段顯示了請求中預設Web.config的變化

  <system.web>
    <httpHandlers>
      <add verb="*" path="home/test/*" type="MvcEmule.Components.MvcEmuleHandler"/>
    </httpHandlers>
  </system.web>

    只要應用程式收到一個與配置中匹配的URL請求,就會轉到相應的處理程式。

定義HTTP處理程式行為

    在ASP.NET中,HTTP處理程式是一個實現了IHttpHandler介面的元件。非常簡單,只有兩個成員,程式碼如下:

    public class MvcEmuleHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            // 業務邏輯
        }

        public Boolean IsReusable
        {
            get { return false; }
        }
    }

    大多數時候,HTTP處理程式是根據輸入資料的查詢字串傳遞(query string)相關的硬編碼行為。然而,他不能阻止我們使用請求處理程式最為抽象工廠,增加一個或多個簡介層。事實上,我們可以使用請求處理程式中的請求資訊,來確定外部的實際服務請求。按照這種方式,一個簡單的HTTP請求程式可以服務於大量的請求,只要呼叫一些更加專門的元件。

HTTP 處理程式可以解析出 URL中的標記(Controller、action、param),並使用該資訊來標識類和呼叫的方法。下面是它如何工作的示例:

public void ProcessRequest(HttpContext context)
        {
            // 轉化 URL 並獲取 controller, action, 和引數
            var segments = context.Request.Url.Segments;
            var controller = segments[1].TrimEnd('/');
            var action = segments[2].TrimEnd('/');
            var param1 = segments[3].TrimEnd('/');

            // 使用字首和名稱空間組裝Controller類名
            var fullName = String.Format("{0}.{1}Controller",
            this.GetType().Namespace, controller);
            var controllerType = Type.GetType(fullName, true, true);

            // 例項化controller
            var instance = Activator.CreateInstance(controllerType);

            // 呼叫 controller 例項的 action 方法 
            var methodInfo = controllerType.GetMethod(action,
            BindingFlags.Instance |
            BindingFlags.IgnoreCase |
            BindingFlags.Public);
            var result = String.Empty;
            if (methodInfo.GetParameters().Length == 0)
            {
                result = methodInfo.Invoke(instance, null) as String;
            }
            else
            {
                result = methodInfo.Invoke(instance, new Object[] { param1 }) as String;
            }

            // 返回結果
            context.Response.Write(result);
        }

    我們假設上面的程式碼中,伺服器名稱後面的第一個標記,唯一標識了服務請求的元件(類)。第二個標記涉及這個元件(類)中需要呼叫的方法名最後,第三個標記標識傳遞的引數

請求HTTP處理程式

    在瀏覽器中輸入一個URL http://localhost:9086/home/test/*,他的結果就是,“home”標識了類名,“test”標識方法名,無論結尾是什麼,都作為引數。型別進一步制定,擴充套件為包含名稱空間和字尾。根據例項,,最終類名是MvcEmule.Components.HomeController。預計這個類對於應用程式是可用的,也暴露一個名為Test的方法。看下結果:

    public class HomeController
    {
        public String Test(Object param1)
        {
            var message = "<html><h1>Got it! You passed ‘{0}’</h1></html>";
            return String.Format(message, param1);
        }
    }

    這個簡單的例項說明了如何使用ASP.NET MVC最基本的機制。控制器(Controller)是一個為請求提供服務的專門的元件。控制器(Controller)是一個只有方法沒有狀態的類。一個獨特的系統級HTTP處理程式負責將發來的請求匹配到一個特定的控制器類,這樣一個類的例項將執行一個給定的操作方法,併產生一個響應。

    那麼Url 的方案是怎樣呢?在此示例中,我們只是使用硬編碼的 URL。在 ASP.NET MVC 中,有一種非常靈活的語法,可以使用表示應用程式能夠識別的這些 Url。此外,一個新的系統元件在執行時管道中擷取的請求、 處理 URL,並觸發的 ASP.NET MVC HTTP 處理程式。此元件是 URL 路由的 HTTP 模組。關於URL路由模組,下次再譯。