1. 程式人生 > >初試ASP.NET Web API/MVC API(附Demo)

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

寫在前面

  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釋出執行截圖:

  客戶端呼叫執行截圖:

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

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

相關推薦

ASP.NET WEB網站簡單入門簡單Demo ->釋出

簡單分幾個階段 一、簡單程式碼實現 1.新建工程 2.開啟設計器(檢視設計器),托出一個label ,寫上Hello 3.點選除錯,即可看到網頁效果 4.重新生成後,釋出到指定

初試ASP.NET Web API/MVC APIDemo

寫在前面   ASP.NET Web API是​​一個框架,可以很容易構建達成了廣泛的HTTP服務客戶端,包括瀏覽器和移動裝置。是構建RESTful應用程式的理想平臺的.NET框架。   上面是微軟對Web API給出的定義,其中包含兩個關鍵字:HTTP和RESTful,其實從這一方面,大家就可以看出

ASP.NET Core 2 學習筆記十二REST-Like API

light namespace strong postman space 新增 html move engine Restful幾乎已算是API設計的標準,通過HTTP Method區分新增(Create)、查詢(Read)、修改(Update)和刪除(Delete),簡稱

ASP.NET Core快速入門】十四MVC開發:UI、 EF + Identity實現

dfa models cti ted lec inpu word pri numeric 前言 之前我們進行了MVC的web頁面的Cookie-based認證實現,接下來的開發我們要基於之前的MvcCookieAuthSample項目做修改。 MvcCookieAuth

ASP.NET WEB 專案雲端部署Visual Studio+SQL server +阿里雲+IIS 多圖

一.前期準備 Windows 系統電腦(筆者用win10) Visual Studio 軟體(筆者用 2017) SQL server 軟體 (筆者2017和2005) 雲端伺服器一臺(阿里雲Window server 2012 R2) 網站程式碼 二.伺服

ASP.NET Core】處理異常上篇

關心 指向 然而 sub 相關 pri roo epon netcore 依照老周的良好作風,開始之前先說點題外話。 前面的博文中,老周介紹過自定義 MVC 視圖的搜索路徑,即向 ViewLocationFormats 列表添加相應的內容,其實,對 Razor Page

ASP.NET Core 2 學習筆記十四Filters

span ans 黃色 返回 lec red addm spn using 原文:ASP.NET Core 2 學習筆記(十四)FiltersFilter是延續ASP.NET MVC的產物,同樣保留了五種的Filter,分別是Authorization Filter、Res

ASP.NET Core 2 學習筆記十一Cookies & Session

自動 asp Go 內存 rtu serialize .html call names 原文:ASP.NET Core 2 學習筆記(十一)Cookies & Session基本上HTTP是沒有記錄狀態的協定,但可以通過Cookies將Request來源區分出來,並

Core中使用Hangfire 在Asp.Net Core中使用DI的方式使用Hangfire構建後臺執行指令碼 解決 ASP.NET Core Hangfire 未授權401 Unauthorized

    之前使用Quartz.Net,後來發現hangfire對Core的繼承更加的好,而且自帶管理後臺,這就比前者好用太多了。 安裝註冊 安裝 PM> Install-Package Hangfire Startup.cs,在ConfigureServices方法中添加註冊:

NodeJS中的事件EventEmitter API詳解原始碼

EventEmitter 簡介 EventEmitter 是 NodeJS 的核心模組 events 中的類,用於對 NodeJS 中的事件進行統一管理,用 events 特定的 API 對事件進行新增、觸發和移除等等,核心方法的模式類似於釋出訂閱。 實現 EventEm

Asp.Net Core 釋出和部署Linux + Jexus

前言 在上篇文章中,主要介紹了 Dotnet Core Run 命令,這篇文章主要是講解如何在 asp.net core 中對我們的已經完成的程式進行釋出和部署。 目錄 安裝 Liunx DotNet 環境 新建一個 Web 專案,併發布 使用 Jexus 進行反向代理 安裝 Linux DotNet

winserver的consul部署實踐與.net core客戶端使用demo源碼

指令 his on() client模式 mvc lan -s enc .com 前言 隨著微服務興起,服務的管理顯得極其重要。都知道微服務就是”拆“,把臃腫的單塊應用,拆分成多個輕量級的服務,每個服務可以在短周期內重構、叠代、交付。隨著微服務的數

winserver的consul部署實踐與.net core客戶端使用demo原始碼

前言隨著微服務興起,服務的管理顯得極其重要。都知道微服務就是”拆“,把臃腫的單塊應用,拆分成多個

Vue.js 實戰教程demo

href 還需要 webapp bsp XA 生命周期 系統 初學 基礎 在實戰之前,你需要對vuejs的基礎語法有一定的了解,可以通過以下幾個途徑進行學習: vue.js官方文檔:https://cn.vuejs.org/v2/guide/index.html vue

Aspnetcore2.0中Entityframeworkcore及Autofac的使用Demo

desc *** 結果 get rtu configure ogg netcore rri 一,通過Entityframeworkcore中DbFirst模式創建模型 這裏只說一下Entityframeworkcore中DbFirst模式創建模型,想了解CodeFirst的

Aspnetcore2.0中Entityframeworkcore及Autofac的使用Demo

-a new 自己 col 用途 spl isp aspnet ide 一,新建Aspnetcore項目 Aspnetcore是微軟家族中年紀較輕的新成員,但他的功能用途是其他前輩們望塵莫及的。想要知道他的功能特性大家可以問度娘也可以去官網查找一些資料。這裏主要給大家說一下

Aspnetcore2.0中Entityframeworkcore及Autofac的使用Demo2018-12-04 10:08

三,使用Autofac替換原有Ioc 首先安裝Autofac兩個外掛類庫: Autofac Autofac.Extensions.DependencyInjection 修改Startup.cs替換框架自帶IOC: // This method gets called by the runti

SpringBoot整合Shiro登入認證和授權demo

SpringBoot整合Shiro登入認證和授權 廢話不多說,直接上程式碼: 程式碼有點多,想直接拿demo的直接拉到底 ps:demo忘了在哪拿的了,在他的基礎上改了一些 步驟一:pom.xml匯入依賴jar包 <dependencies

Android Wear 控制元件——WearableListViewDemo

WearableListView是適用於android小型裝置如智慧手錶顯示列表的元件,可以村子滾動,非常方便的在只能手錶上顯示列表控制元件,每次顯示三個列表在螢幕中間位置。 它繼承RecyclerView,實現了OnScrollListener介面。 public cla

Android MediaPlayer+SurfaceView播放視訊Demo

MediaPlayer,顧名思義是用於媒體檔案播放的元件。Android中MediaPlayer通常與SurfaceView一起使用,當然也可以和其他控制元件諸如TextureView、SurfaceTexture等可以取得holder,用於MediaPlaye