初試ASP.NET Web API/MVC API(附Demo)

来源:http://www.cnblogs.com/liubibi23/archive/2017/01/23/6344152.html
-Advertisement-
Play Games

參考頁面: http://www.yuanjiaocheng.net/webapi/media-formatter.html http://www.yuanjiaocheng.net/webapi/webapi-filters.html http://www.yuanjiaocheng.net/we ...


參考頁面:

http://www.yuanjiaocheng.net/webapi/media-formatter.html

http://www.yuanjiaocheng.net/webapi/webapi-filters.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1-get.html

http://www.yuanjiaocheng.net/webapi/create-crud-api-1-post.html

寫在前面

  ASP.NET Web API是​​一個框架,可以很容易構建達成了廣泛的HTTP服務客戶端,包括瀏覽器和移動設備。是構建RESTful應用程式的理想平臺的.NET框架。

  上面是微軟對Web API給出的定義,其中包含兩個關鍵字:HTTP和RESTful,其實從這一方面,大家就可以看出Web API和它的同胞兄弟:WebService和WCF有些不同了。

HTTP

  對於HTTP大家都不是很陌生,因為我們每天瀏覽網頁填寫的URL就是HTTP開頭,但只是知道有這個東西,確沒有想過它是什麼,就好像我們對世間萬物有著模糊的認識,但認識東西的確很少。

  也可以從另一方面去理解,曾經看一個電視節目,有個嘉賓在錄製的過程中,突然抬起頭對著天花板仰望,然後主持人很驚訝問他在幹嗎?他說:我在思考宇宙有沒有盡頭?主持人接著問:那宇宙有沒有盡頭?他淡然的回答道:有就有,沒有就沒有。當然觀眾和主持人都笑作一團,你會笑嗎?透過現象看本質,其實這個思想和老莊的思想很合拍,扯遠了。

HTTP即超文本傳送協議。

超文本傳輸協議 (HTTP-Hypertext transfer protocol) 是一種詳細規定了瀏覽器和萬維網伺服器之間互相通信的規則,通過網際網路傳送萬維網文檔的數據傳送協議。

  從定義中看出HTTP是一種協議,超文本傳輸協議,那什麼是超文本?和我們所說的富文本有些區別,超文本也是一種文本格式,那可以把它看成是文本與文本之間關聯而組成的網狀文本,有點類似於面向對象中對象的集合,雖然是對象的集合,但本身也是一個對象。

  HTTP協議有下麵三個基本特點:

  • 簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯繫的類型不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通信速度很快。
  • 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  • 無狀態:無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。

  相對於Web API來說,HTTP不只是為了生成Web頁面,它也是一個強大的平臺建設公開服務和數據的API。HTTP是簡單、 靈活和無處不在,因此幾乎任何平臺都可以有一個HTTP庫,因此,HTTP服務可以到達範圍廣泛的客戶端,包括瀏覽器、移動設備和傳統的桌面應用程式。

RESTful

  RESTful架構概念是Fielding提出的,Fielding這號人物就是上面HTTP協議的主要設計者之一。我們先看下RESTful這個詞,ful是跟在名詞之後,表示程度,什麼什麼的,例如helpful樂於助人的,因此我們可以看出符合REST的架構就可以稱為RESTful,接著我們看下REST,全稱為“Representational State Transfer”,意為“表現層狀態轉化”

在符合架構原理的前提下,理解和評估以網路為基礎的應用軟體的架構設計,得到一個功能強、性能好、適宜通信的架構。  -Fielding

  這是Fielding在論文中所提到的,對於REST雖說是架構,但如果深入一點,就像是HTTP協議一樣,可以看成一種規則或是協議。我們從一個地點到另一個地點,可以坐汽車、高鐵、飛機等,對於REST就像是其中的一種交通方式,但REST的根本是HTTP協議,也就是說REST是基於HTTP協議的,這點就像坐汽車必須要有公路,坐高鐵必須要有鐵路是一樣的道理,有時候為什麼選用REST,就像我們從南京到徐州,選擇坐高鐵而不選擇坐飛機一樣。

  上面這個比喻可能不太恰當,但是思想都是相同的,如果有可能的話可以看下一些哲學方面的書,像莊子的道德經,畢竟編程是哲學或是藝術的另一類體現,又扯遠了。

  “Representational State Transfer”我們分解下:

  • Representational 表現層:表現層表現什麼,應該呈現資源(Resources),一個圖片、一段文字、一個文件都成為資源,每個資源都用一個URI(統一資源定位符)指向它,表現層就是調用URI把資源呈現出來,而且只是呈現,不做其他操作。舉個例子:有些網址最後的".html"尾碼名是不必要的,因為這個尾碼名錶示格式,屬於"表現層"範疇,而URI應該只代表"資源"的位置。它的具體表現形式,應該在HTTP請求的頭信息中用Accept和Content-Type欄位指定,這兩個欄位才是對"表現層"的描述。
  • State Transfer 狀態轉化:訪問一個網站,就表示客戶端和伺服器發生一次交互行為,在這個過程中,就不發生數據和狀態的轉化,上面說到HTTP協議具有無狀態性,如果客戶端操作伺服器,必須要狀態轉化,這個體現在表現層上,所以叫“表現層狀態轉化”

  通過上面的理解,可以總結下什麼是RESTful架構:

  1. 每一個URI代表一種資源。
  2. 客戶端和伺服器之間,傳遞這種資源的某種表現層。
  3. 客戶端通過四個HTTP動詞(PUT、GET、POST和DELETE),對伺服器端資源進行操作,實現"表現層狀態轉化"。

創建Web API

  關於Web API的實現方式,.net提供了一套機制就是ASP.NET MVC API,類似MVC的方式,實現起來很簡單,也不需要你去關註HTTP和RESTful的一些東西,當你去新建項目的時候,一切東西.net都幫你搞定了,是好還是不好?只能呵呵笑過。

  下麵我們就一步一步的創建一個ASP.NET MVC API

  1,新建ASP.NET MVC WebMvcApiDemo程式,選擇Web API模板類型。

  2,創建News模型,雖然創建的是MVC項目,但是我們一般只用到控制器和模型。

 1     public class News
 2     {
 3         /// <summary>
 4         /// 新聞ID
 5         /// </summary>
 6         public int Id { get; set; }
 7         /// <summary>
 8         /// 新聞標題
 9         /// </summary>
10         public string Title { get; set; }
11         /// <summary>
12         /// 新聞內容
13         /// </summary>
14         public string Content { get; set; }
15         /// <summary>
16         /// 新聞作者
17         /// </summary>
18         public string Author { get; set; }
19         /// <summary>
20         /// 發佈新聞時間
21         /// </summary>
22         public DateTime CreateTime { get; set; }
23     }

  3,創建數據模擬類NewsRepository,用於查詢數據。

 1     public class NewsRepository
 2     {
 3         public IEnumerable<News> GetAllNews()
 4         {
 5             News[] news = new News[] 
 6             { 
 7                 new News { Id = 1, Title="新聞標題1", Content="新聞內容1", Author="xishuai", CreateTime=DateTime.Now }, 
 8                 new News { Id = 2, Title="新聞標題2", Content="新聞內容2", Author="xishuai", CreateTime=DateTime.Now }, 
 9                 new News { Id = 3, Title="新聞標題2", Content="新聞內容3", Author="xishuai", CreateTime=DateTime.Now }
10             };
11             return news;
12         }
13     }

  4,創建NewsController控制器,註意的是:新建控制器的時候,模板選擇“空 API 控制器”,與MVC控制器不同的是,API控制器繼承ApiController基類。在我們新建ApiDemo的MVC項目的時候,自動生成了一個ValuesController API控制器,打開後我們發現,有很多自動生成的方法,請求方式就是我們上面說GET、POST、PUT和DELETE的四種HTTP請求方式,我們這邊做一個Get的,獲取全部新聞或是指定新聞ID獲取,返回結果格式為XML。

 1     public class NewsController : ApiController
 2     {
 3         /// <summary>
 4         /// GET獲取全部新聞
 5         /// </summary>
 6         /// <returns></returns>
 7         [HttpGet]
 8         public HttpResponseMessage GetAllNews()
 9         {
10             var news = new NewsRepository().GetAllNews();
11             return new HttpResponseMessage()
12             {
13                 RequestMessage = Request,
14                 Content = new XmlContent(SimpleXmlConverter.ToXmlDocument<News>(news, "NewsRoot"))
15             };
16         }
17 
18         /// <summary>
19         /// GET獲取指定ID新聞
20         /// </summary>
21         /// <param name="ID"></param>
22         /// <returns></returns>
23         [HttpGet]
24         public HttpResponseMessage GetNewsByID(int ID)
25         {
26             var news = new NewsRepository().GetAllNews().Where((p) => p.Id == ID);
27             return new HttpResponseMessage()
28             {
29                 RequestMessage = Request,
30                 Content = new XmlContent(SimpleXmlConverter.ToXmlDocument<News>(news, "NewsRoot"))
31             };
32         }
33     }

  這裡面主要用到兩個轉化類:XmlContent和SimpleXmlConverter,有關這兩個類的詳細代碼可以下載Demo看下。

  5,路由配置Web API和MVC的路由配置很相似,主要區別是Web API使用HTTP方法而不是URI路徑來選擇動作,路由文件WebApiConfig,如下:

1             config.Routes.MapHttpRoute(
2                 name: "DefaultApi",
3                 routeTemplate: "api/{controller}/{action}/{id}",
4                 defaults: new { id = RouteParameter.Optional }
5             );

  其實寫到這裡創建Web API的代碼就差不多了,當然複雜的操作可以擴充,用.net開發就是這麼簡單,只要完成業務邏輯就行了,呵呵。

調用Web API

  調用Web API有很多種方式,js可以調用,就像我們寫MVC請求數據一樣,這種是同一域下調用,Web API也是這種方式就沒什麼意思了,如果使用js調用就必須跨域操作,這邊我們使用HttpClient的方式。

  1,新建控制台應用程式-ClientDemo。

  2,安裝Web API 客戶端庫,工具-程式包管理器-程式包管理控制平臺,輸入命令:Install-Package Microsoft.AspNet.WebApi.Client

  上面新建的ClientDemo項目.net framework版本是4.0,安裝HttpClient的時候報下麵錯誤:

  .net framework版本改為4.5就安裝成功了,難道HttpClient只支持4.5以上?查了下MSDN,HttpClient確實只支持.net framework4.5,難道以前程式如果使用HttpClient要把.net framework改成4.5?有點鬱悶。

  4,創建HttpClient,先貼下代碼:

 1         static void Main(string[] args)
 2         {
 3             RunAsync().Wait();
 4         }
 5 
 6         static async Task RunAsync()
 7         {
 8             using (var client = new HttpClient())
 9             {
10                 client.BaseAddress = new Uri("http://localhost:8077/");
11                 client.DefaultRequestHeaders.Accept.Clear();
12                 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
13 
14                 string xmlString = await client.GetStringAsync("api/News/GetAllNews");
15                 XmlDocument xmlDoc = new XmlDocument();
16                 xmlDoc.LoadXml(xmlString);
17                 XmlNodeList nodeList = xmlDoc.GetElementsByTagName("News");
18                 foreach (XmlNode node in nodeList)
19                 {
20                     Console.WriteLine("新聞ID:" + node.SelectSingleNode("Id").InnerText);
21                     Console.WriteLine("新聞標題:" + node.SelectSingleNode("Title").InnerText);
22                     Console.WriteLine("新聞內容:" + node.SelectSingleNode("Content").InnerText);
23                     Console.WriteLine("作者:" + node.SelectSingleNode("Author").InnerText);
24                     Console.WriteLine("新聞發佈時間:" + node.SelectSingleNode("CreateTime").InnerText);
25                     Console.WriteLine("======================");
26                 }
27                 Console.ReadKey();
28             }
29         }

  Main 函數調用一個名為RunAsync的非同步方法,然後會阻止,直到RunAsync完成。許多的HttpClient方法是非同步,因為他們執行網路 i/o 操作。MediaTypeWithQualityHeaderValue是定義傳輸格式,如果使用json則為“application/json”,這邊要與Web API格式一致,XML獲取使用的是GetStringAsync方法,然後轉換為XmlDocument,網上找了一種GetStreamAsync方法獲取,通過Stream轉化為字元串,但是轉化後的字元串為空。

  上面調用Web API的是獲取全部新聞,如果調用通過新聞ID獲取新聞,GetStringAsync的方法參數只需要改為“api/News/GetNewsByID/新聞ID”就可以了。

  5,關於Web API的發佈問題,這個問題花了不少時間,一個一個問題出現及解決,首先我們先不急著調用,先發佈瀏覽,如果瀏覽器瀏覽沒問題的話再調用。Web API的發佈和MVC差不多,需要註意下麵幾點:

  • 文件許可權別忘了配置,要配置every one。
  • 應用程式池選擇“ASP.NET v4.0 DefaultAppPool”。
  • 選擇應用程式池之後要配置“ISAPI 和 CGI 限制”的4.0版本設置為允許,要不然出現“由於 Web 伺服器上的“ISAPI 和 CGI 限制”列表設置,無法提供您請求的頁面。”的錯誤。
  • “Newtonsoft.Json”文件引用。
  • “An error has occurred.Multiple actions were found that match the request”,這個錯誤信息是Web API的路由沒有配置好,要檢查下。
  • “Response status code does not indicate success: 404 (Not Found)”,這個錯誤信息也是路由問題。
  • “Response status code does not indicate success: 500 (Internal Server Error).”,這個是伺服器問題,也就是Web API的代碼問題。

運行截圖及Demo下載

  Web API瀏覽器請求截圖:

  Web API發佈運行截圖:

  客戶端調用運行截圖:

  Demo下載地址:http://pan.baidu.com/s/1gdopRub

  HTTP請求的四種方法(PUT、GET、POST和DELETE)本篇只是講到GET,HTTP的數據傳輸格式(json、xml等)也只是說了XML,但都是大同小異,舉一反三可得。

  如果你覺得本篇文章對你有所幫助,請點擊右下部“推薦”,^_^


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.匿名類型:匿名類型是C#3.0新增的特性,是強類型(由編譯器後臺在生成為CIL時,自動聲明的代碼定義類型),聲明與初始化屬性後其屬性是盡讀屬性。只有在屬性的名稱、順序、類型一致時,多個聲明匿名變數才會共用同一個匿名類型。其ToString()方法已重寫了返回的是屬性名稱與值的文本。 2.隱式局部 ...
  • 1.多播委托:由與delegate關鍵字聲明的委托,在編譯後預設繼承Delegate與MulticastDelegate類型,所以聲明的委托自然就含有多播委托的特性,即一個委托變數可以調用一個方法鏈(多個相同簽名的方法)。在C#中,多播委托的實現是一個通用的模式,目的是避免大量的手工編碼,這個模式稱 ...
  • Unity下GL沒有畫圓的函數,只能自己來了。 如果能幫到大家,我也很高興。 雖然沒有畫圓的函數,但是能畫直線,利用這一點,配合微積分什麼的,就可以畫出來了。反正就是花很多連在一起的直線,每條直線足夠短的時候,就足夠圓了 參數分別為: x,y,z 中心點三維坐標, r 圓的半徑, accuracy ...
  • 魔方 是一個基於 ASP.NET MVC 的 用戶許可權管理平臺,可作為各種信息管理系統的基礎框架。 演示:http://cube.newlifex.com 源碼 演示賬號:admin/admin 源碼: https://git.newlifex.com/NewLife/X/Tree/master/N ...
  • 先上圖: 操作方法: 1、先設置一下gridview中屬性:IndicatorWidth,一般為:40。如下圖;(一般可以顯示5位數字。如要更長顯示,自己測試一下。) 2、找到gridview中的:CustomDrawRowIndicator事件,輸入如下麵代碼: 1 private void gv ...
  • 參考頁面: http://www.yuanjiaocheng.net/CSharp/csharp-class.html http://www.yuanjiaocheng.net/CSharp/csharp-variable.html http://www.yuanjiaocheng.net/CSha ...
  • 參考頁面: http://www.yuanjiaocheng.net/webapi/test-webapi.html http://www.yuanjiaocheng.net/webapi/web-api-controller.html http://www.yuanjiaocheng.net/we ...
  • 參考頁面: http://www.yuanjiaocheng.net/entity/Persistence-in-EF.html http://www.yuanjiaocheng.net/entity/crud-in-connected.html http://www.yuanjiaocheng.n ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...