顯示具有 Web API 2 標籤的文章。 顯示所有文章
顯示具有 Web API 2 標籤的文章。 顯示所有文章

答客問:多層JSON結構如何轉換為C#的Model物件

答客問:多層JSON結構如何轉換為C#的Model物件

教學上,我一直認為沒有爛問題。只有懂與不懂。

平常我們在課程上設計的範例為求簡單好懂,通常都會盡量簡化。但回去之後的實務問題,在我眼裡都非常有價值。API 的開發可以很簡單,也可以很複雜,例如,只是單純從後端資料庫取資料,資料表與Model的對應關係通常都是一對一(1:1)的,輸出入也很單純只會有一層,除非你導入了如 Entity Framework 之類 ORM,產生了一對多(1:n)或多對多(n:n)的情境。

{
    "filter":{
        "name":"bruce",
        "currentPage":1,
        "pageSize":5
    }
}

以同學提問的情況,感覺比較像 Front-End First(或稱 JSON First),也就是 JSON 規格是由前端定義。我們一步一步來解決。

如何依.NET應用程式建置組態產生對應的Prefix前綴路由

如何依.NET應用程式建置組態產生對應的Prefix前綴路由

在將一個 ASP.NET Web API 應用程式進行容器化(Containerization)發現一個問題,原先的 Web API 部署至 IIS 應用程式之下,我們會區分開發區(Develop)、測試區(Staging)、正式區(Production),而原始的請求因為 IIS 應用程式的關係,路由都會被加上應用程式的前綴(Route Prefix),例如:

  • Org:/api/value
  • Dev:/develop/api/value
  • Stg:/staging/api/value
  • Prd:/production/api/value

ASP.NET Web API GZip/Deflat 資料遺失迷航記

ASP.NET Web API GZip/Deflat 資料遺失迷航記

前情提要:參考(1)(2),之前測試發現 ASP.NET Web API 有個查詢資料量不小(1.92 MB),並且會有同等級的上傳行為,在 ASP.NET Web API 加入 GZIP/Deflate (解)壓縮來改善效能,資料由 1.92 MB → 50 KB 壓縮率約 40 倍,這是用一點 CPU 來改善效能的好範例。

同事回報,在測試區當資料量提升至 3.3 MB(3338506 bytes) 後,程式有機會(隨機)出錯(Exception)。

先來看 HTTP POST 流程:

RestSharp (RawData: Over 3.3 MB) → GZIP → GZIP ByteArray (79515 bytes) → HTTP POST → ASP.NET Web API

這是個 VSTO 的 Excel 應用程式,在讀取 Web API 資料之後,原封不同進行上傳(HTTP POST)動作,由側錄取得離線 RawData 約 3.3 MB,經過 GZIP 壓縮後得到約 78 KB 的 Byte Array 資料,最後使用參考(2)程式碼送出:

request.AddParameter("application/json", content.ToArray(), ParameterType.RequestBody);
檔案大小

接收流程:

ASP.NET Web API → DecompressionHandler → RawData → Web API life cycle

Web API 收到請求後安排一個 Message Handler 進行解壓縮後取得 RawData 之後,按 Web API 生命流程往下進行。

程式穩定運作,經過許多分析與測試後,在終於在 Web API 側錄到錯誤發生時的資訊:

lose data

在 DecompressionHandler 取得的 GZIP ByteArray 大小為 77889,很明顯小於原始的 79515,把解壓縮的 RawData 資料 Dump 出來後確實資料短少被截斷了,造成後續 Web API 在進行 ModelBinding 時的不正常 Exception。

青菜SOAP與蘿蔔REST,請選擇?

青菜SOAP與蘿蔔REST,請選擇?

在 dzone.com 看到一篇比較 SOAP 與 REST 的文章整理的覺得不錯,簡單翻譯做個筆記。

SOAP 和 REST 都是 Web Service 通訊協定,在 REST 未風行之前,SOAP 長期以來都是 Web Service 服務介面的標準方法。不過,根據 Stormpath 的統計,目前已有超過 70% 的公開 API。

SOAP 與 REST 主要差異

當你在 Internet 上公開一個 API,REST 通過獨立且一致的介面進行操作,用以訪問命名資源。而 SOAP 將應用程式邏輯的元件公開為服務,而不是資料,並且它通過不同的介面來操作。簡而言之,REST 訪問資料,SOAP 透過更標準化的訊息模式集來操作。在大多數情況下,可以使用 SOAP 與 REST 來實現相同結果。

超狂.超提升ASP.NET Web API效能的8種方法(有沒有100倍呀?)

超狂.超提升ASP.NET Web API效能的8種方法(有沒有100倍呀?)

看到一篇 8 ways to improve ASP.NET Web API performance 覺得整理的不錯,順手簡單整理與寫點心得。

  1. 使用最快的 JSON 序列化套件

ASP.NET Web API 預設採用 JSON.NET。JSON.NET 求穩不求快,如果要求快,透過 ASP.NET Web API 優秀擴充點機制,可隨時更換序列化套件。

之前在 Blog 介紹過 Jil:

8 Ways作者則是採用 ServiceStack.Text 套件。

JSON Serialization 速度

圖片來源:theburningmonk.com

POST GZIP/Deflate Data to ASP.NET Web API

POST GZIP/Deflate Data to ASP.NET Web API

前一篇使用GZIP或DEFLATE壓縮,提升資料傳遞效能40倍,我們處理了查詢資料量大時,Web API 在傳遞未經壓縮的資料產生許多不必要的網路流量的問題。現在我們轉換方向,如果是用戶端要傳遞大量資料至 Web API 時,那麼我們要怎麼處理?這比較麻煩,有二個方向要討論,一是 Client 端進行發送請求時,必須先做 GZIP/Deflate 的壓縮,而 Web API 接收到 GZIP/Deflate 壓縮資料後需要解壓縮還原資料內容。

從這個方向來思考,你應該能發現另一件事,就是前一篇我們只專注在 GZIP/Deflate 的壓縮上,並無做任何解壓縮的工作,那是因為瀏覽器本身在協商過程與接收到的 Header 可以判定接收到的是 GZIP/Deflate 的內容,瀏覽器會直接幫我們進行 GZIP/Deflate 的解壓縮工作。

ASP.NET Web API:使用GZIP或Deflate壓縮,提升資料傳遞效能40倍

ASP.NET Web API使用GZIP或Deflate壓縮,提升資料傳遞效能40倍

未壓縮資料量

專案有個查詢資料量不小,基本測試資料每次約1.92 MB,透過 ASP.NET Web API 傳遞至 Client 端每次就是 1.92 MB 的網路傳遞量,而且未來上線後,資料量只會越來越大,直覺感到不對勁(壞味道)。

IIS的動態壓縮與靜態壓縮對 ASP.NET Web API 是無效的。而且,平常 ASP.NET Web API 的請求,資料負載量也不是很大,那種 KB 級的資料壓縮率不高,平常也就沒特別注意。不過在 MB 級的資料,有無啟用 GZIP 或 Deflate 壓縮的資料量差異,直接說結果,以我實測得到的數據差了40倍。

以 requestb.in 解開 HTTP Request 之密

以 requestb.in 解開 HTTP Request 之密

公司有個特別的 D 系統,我們需要透過 ASP.NET Web API 去存取它的 XML Web Service 來提供資源。這個 D 系統本身有個特別的限制,就是存取之前使用者需要先進行頁面 Login,然後才能存取 XML Web Service。Login 頁面很單純,就是一個帳號與密碼的組合,沒有其他特別驗證碼等保護。也就是使用者使用者輸入帳號密碼,而 ASP.NET Web API 透過使用者提供的帳號密碼透過程式方式進行登入,我們開發的 ASP.NET Web API 服務從一開始的 Beta 至 RC,這部分的程式碼都沒什麼問題,直到那令人鬼打牆的關鍵人物(暫稱他苦命的呆伯特好了)出現。

呆伯特一直說無法Login

簡單說明一下,此 ASP.NET Web API 服務主要使用者在美國,美國下班台灣上班的黃金交接點,我們私下請呆伯特(美國)幫忙測試此 ASP.NET Web API 服務的同事,但幾星期以來僅呆伯特都一直反應無法 Login 服務,由日誌看出來,他確實是登入失敗。但所有幫忙測試的人員只有呆伯特會出現此狀況。D 系統我們無任何權限,我們能做的也只是不斷調整 ASP.NET Web API 程式並不斷請呆伯特幫忙 Login 與測試。但每每得到"不行"時,心情都低落到不行(測到呆伯特都生氣了),不過最後得到一條重要資訊,呆伯特的密碼含有數個的特殊符號。

我們為加解密演算法補上特殊符號的測試程式碼,先確保特殊符號在加密與解密過程正常。其中小心\與"這兩個符號,在C#的字串中,需要使用\\與\"進行轉義。

以這條線索測試到最後終於有了曙光。

讓ASP.NET網站在開發除錯時期擁有Web.config文件轉換功能

讓ASP.NET網站在開發除錯時期擁有Web.config文件轉換功能

網站開發到一定規模,你一定有經驗,開始在 Web.config 裡去註解A執行B設定,或註解C執行D設定,最常碰到的需求有:測試區與正式區的 appSettings 設定,測試區與正式區的 connectionStrings 設定等。當專案離開本機開始發行至測試區或正式區時,千萬不要還在用切換註解的方式,應該參考 Kevin:「發佈網站時依據組態設定的不同而轉換 Web.Config」的模式去進行發行時 *.config 的切換。這種動作的名稱「XML-Document-Transform」(XML文件轉換),簡單說,就是利用 Locator 找出要修改位置,再利用 Transform 屬性指定進行的動作。

發行能,那本機除錯呢?

發行可以利用「XML-Document-Transform」來解決不同區域不同配置的問題。但開發人員最常碰到卻是開發當下!開發除錯當下,你無法去只是簡單切換 Debug | Release 來達到或啟用XML文件轉換的功能,假設,你想將原本 SqlLocalDb 的連線字串切換至 SQL Server Express 連線字串進行測試時,好像只有註解、移除註解這條路。 :-(

這樣的路,其實走了好久好久,我累了,我想,是應該跟它分手了。(超假文青 XD)

啟用本機除錯XML文件轉換

這裡會利用如何:擴充 Visual Studio 建置處理序裡的技巧。以下技巧通用於 ASP.NET WebForms 與 ASP.NET MVC 與 ASP.NET Web API 專案。(照理說是只要是 XML 的 .config 都通用,但我沒一一嘗試就是了)

[額滿]2016年9月-ASP.NET Web API 2實戰訓練營

如果,你正要開發一個 Web API 來自用?

如果,你需要提供 Web API 讓第三方(例如,手機App)呼叫?

如果,你需要串接其他第三方 Web API 來使用?

隨著 client 越來越多樣化,Web API 的重要性不言而喻,還沒趕上或是充滿迷惘?

2016年重磅規劃的課程,業界實戰的內容,走過路過,真的不要錯過!

報名:ASP.NET Web API 2實戰訓練營

ASP.NET Web API-取代JsonFormatter新選擇-招喚JilFormatter

ASP.NET Web API-取代JsonFormatter新選擇-招喚JilFormatter

ASP.NET Web API一開始就以JSON.NET來取代JavaScriptSerializer以完成世代交替,JSON.NET的表現一直是中規中矩,以我的認知他是求穩。ASP.NET Web API採用Formatter的設計方式,預設有JsonFormatter與XmlFormatter,在求快的過程,如同頭文字D的86,換上一顆新F1引擎是最快的方式,我們來替ASP.NET Web API安裝一顆JilFormatter的高速引擎。

揭開HttpClient APIs在UWP的神秘面紗

揭開HttpClient APIs在UWP的神秘面紗

日前很高興有機會去參加SkillTree的UWP 與 Microsoft Azure 實戰課程(臺北場)課程,其中一個段落正是在介紹HttpClient APIs,我才知道目前的HttpClient在UWP有兩個實作:System.Net.Http.HttpClient 類別與Windows.Web.Http.HttpClient 類別。它們兩個都應優先於WebClient和HttpWebRequest來使用。

這引起了我的好奇。看了一些文章與討論區,都沒有感到滿意的回答。最近剛好看到一篇官方 Blog 的文章,正是討論兩者的差異,覺得交代的很清楚,以下是我不負責簡單翻譯加筆記。

使用Hangfire處理ASP.NET MVC/Web API長時間與排程工作

使用Hangfire處理ASP.NET MVC/Web API長時間與排程工作

工作管理

網頁通常是做為一個即時資訊交換工具,也就是一個請求-回應模式,不過在現實世界(或討論區)中經常會聽到希望可以進行長時間作業與排程作業的需求,網頁長時間作業通常是使用非同步技術來處理,但排程作業呢?這在單純的網頁作業流程中比較難處理,通常會勸說交給後端SQL Server排程處理或使用Windows工作排程器或寫成Windows Service來解決。

廢話那麼多,反正就是傳統網頁要處理長時間工作與排程工作都要額外花費不少心思,最近剛好有這方面的需求,試玩國外火紅Hangfire,不試還好,試了…

Hangfire - 射後不理、延遲、定時

Hangfire重點功能

從Hangfire官網可以看到最明顯的三個功能:Fire-and-forget tasks、Delayed tasks、Recurring tasks。

破解System.Web.Helpers 2.0.0.0與3.0.0.0之謎

破解System.Web.Helpers 2.0.0.0與3.0.0.0之謎

Error 2

System.Web.Helpers命名空間是.NET Framework裡一個神秘的組織,它和ASP.NET MVC 3一起推出,知道和用它的人並不多,它暗地裡提供許多便利型的功能(可以參考之前寫的系列文(1、2、3、4、5、6、7、8)。但如上圖所見,它在我VS2015裡的新專案裡就這樣赤裸裸的爆開,開啟著另一個VS2013的專案,怎麼一切安然無事。當下會很直覺的想罵聲-暗,是不是命中帶ㄕㄞˋ,老是碰到這種鬼錯誤。但有幾次VS2015的經驗,我改變心態,耐著性子一路追下去,意外發現System.Web.Helper一件不為人知的故事。

如何使用路由傳遞含"+"符號到Web API 2

Web API 2如何使用路由傳遞"+"符號

我們需要傳遞一個加密過的參數,此加密方法產生有一定機會產出含"+"符號的亂數。"+"符號在網路傳遞過程中會有一些問題,常見的解決辦法是傳遞前後使用Encode與Decode方法來針對特殊符號進行加解密。但在Web API 2比較難處理。

Web API 2與"+"號的邂逅

在預設的Web API 2範本及預設的路由"api/{controller}/{id}"設置下,簡單進行兩個測試:

測試一

以QueryString方式"/api/values?id=1%2b1"進行請求。這裡的%2b是"+"符號Encode的代表號。這個測試可以順利到達Get(string id)方法之內。

ASP.NET Web API 文件產生器(2) - Swagger

ASP.NET Web API 文件產生器(2) - Swagger

前一篇,我們使用ASP.NET Web API範本內建的Help Page快速產出即時的Web API文件,不過在APP Service - API App我們可以發現,微軟在未來的API App範本使用另一個Swagger,接下來我們來看看如何在現有的ASP.NET Web API專案中導入使用Swagger。

在ASP.NET Web API整合Swagger

Swagger是100% Open Source的軟體,它不只能快速產生Web API文件(有好看的UI),而且能直接透過JSON或YAML進行Web API的匯入與匯出,並且可以快速的對你的Web API進行測試,不論此Web API是在本機或是遠端。

  • Swagger UI 你可以試著操作Swagger的界面。
  • Swagger Editor 可以使用JSON或YAML進行Web API的定義描敘,你可以隨意修改看看即時效果。

ASP.NET Web API 文件產生器(1) - Help Page

ASP.NET Web API 文件產生器(1) - Help Page

開發ASP.NET Web API有個很重要的問題,就是文件的撰寫,但開發者都知道,我們希望把心力放在ASP.NET Web API應用程式上面而非文件,原因很簡單:改變是容易的。但如何即時反應程式上的修改,這就不是一件容易工作。

Help Page

在Visual Studio 2013,如果一開始就選擇Web API專案,那麼從專案一開始你就會擁有一個強大的Web API文件產生器,Web API文件產生器由Yao - MSFT針對ASP.NET Web API所設計。

Help Page - Areas目錄

啟動Web API範本會發現比MVC範本一個【API】的連結。

API連結

進入後可以看到Yao設計的ApiExplorer會動態解析目前專案下繼承ApiController的Controller的API方法。

API清單

點擊任一API方法,可以看到更進一步的訊息。

API詳細資訊

如果讀者有跟著做或玩過Help Page會覺得這也太陽春了吧!對,這是因為我們還沒有提供足夠的資訊給ApiExplorer。

OOP繼承技巧:BaseController與BaseApiController

繼承技巧:BaseController與BaseApiController

BaseController與BaseApiController類別技巧不算是ASP.NET MVC或ASP.NET Web API的技術,它是一個OOP(Object-oriented programming,物件導向程式設計)繼承的應用,這在早期Web Forms就已經被大量使用,因為它只是單純的OOP繼承應用,並不會被語言或框架所限制。

ASP.NET MVC - Controller類別

我們先來看看我們在進行開發的Controller類別繼承關係:

IController繼承關係

ControllerBase類別繼承自IController介面,Controller類別繼承自ControllerBase類別,而ControllerBase與Controller都是抽象類別:

 public abstract class ControllerBase : IController {}
 public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IAsyncManagerContainer {}  
 

而我們開發者所在的ASP.NET MVC的Controller都是繼承自Controller抽象類別,Controller抽象類別提供開發者所需的大部分功能:

 public class HomeController : Controller {}  
 

從程式設計的角度來看,ASP.NET MVC的Controller也只是一個類別。如果你發現自己在其他Controller寫了完全相同邏輯的程式碼(相同的成員、屬性或方法等),那麼我們有非常合理的理由來建立一個共用的基礎類別,之後將Controller裡相同的成員、屬性或方法往上層的基礎類別移動,Controller只需重新繼承此基礎類別,就能發揮物件導向的繼承的優勢。

ASP.NET Web API 2:安全的PATCH方法的三種實作

ASP.NET Web API 2:安全的PATCH方法的三種實作

之前「ASP.NET WEB API的HTTP PATCH動詞與PATCH方法實作」被網友反應有問題,經驗證後證實,ASP.NET MVC的Bind屬性對於ASP.NET Web API無效。真的是犯了程式碼會動的大錯,非常抱歉,以下重新整理三種Patch方法的實作方向。

Model - TodoItem

以下是範例用的Model:

 public class TodoItem
 {
     public int Id { get; set; }
     public string Name { get; set; }
     public bool IsDone { get; set; }
 }  
 

請先利用基架(Web API 2 - Entity Framework)產生TodoItemsConteoller。建置之後,先利用POSTMAN / Fiddler等工具新增幾筆資料。

Patch方法的安全性問題

PATCH動詞在HTTP規範中代表著「部分更新」,而Patch方法即是要拿來實作對應PATCH動詞的方法。但預設的Model Binding機制是將所有傳入的資料盡量(盡其所能)進行Binding動作。

  public IHttpActionResult Patch(int id, TodoItem todoItem) {}
 

這在我們進行部分更新的可能會有一些安全性問題,例如,可疑用戶端傳入{"Id":1,"Name":"Is Patch?","IsDone":false},Name與IsDone都會被修改。所以我們要保護好資料,不應該被更新的部分就要剔除。

Patch方法 - 指定更新屬性

第一種方法就是之前那一篇的方法,透過指定更新屬性名稱來進行部分更新的動作:

  TodoItem item = db.TodoItems.Find(id);
  // 一一指定
  item.IsDone = todoItem.IsDone;
  db.Entry(item).State = EntityState.Modified;
  
  try
  {
      db.SaveChanges();
  }
  // 省略
 

我們的範例比較簡單,工作項目只許修改是否完成(IsDone)的狀態。此種方式在有大量屬性(欄位)時比較麻煩。記得,如果你不是一一指定的方式,那麼此PATCH方法等於是PUT方法。

在ASP.NET Web API 2進行動態的ApiController層級組態

前一篇「在ASP.NET WEB AP 2進行APICONTROLLER層級的組態」是透過屬性(Attribute)設置方式來為ApiControler加入靜態設置。它無法在執行期間改變。

實作IControllerConfiguration介面

方法前一篇已經介紹過了:

 public class JsonOnlyAttribute : Attribute, IControllerConfiguration
 {
     public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
     {
         controllerSettings.Formatters.Clear();
         controllerSettings.Formatters.Add(new JsonMediaTypeFormatter());
     }
 }  
 

以上是僅提供JSON Formatter的範例,這樣的好處是不用整個ASP.NET Web API 2專案都完全關閉XML Formatter,需要關閉時才關閉。

如果你是希望動態進行Controller層級組態的話,其實前一篇的參考文件有留下一篇MVP Filip的參考文章,以下簡述Filip文章以瞭解如何進行動態Controller組態。