矛魚盾

使用XmlSerializer,序列化與反序列化

使用XmlSerializer,XML序列化(建立)與反序列化(讀取) 雖然現在大多數是使用JSON作為資料傳輸格式,但偶爾還是會遇到操作XML狀況,特別是遇到使用SOAP情形下,不得不說,XML與JSON在轉換物件的便利性還是有些許差距,久不用實在容易忘記,最近剛好又碰到,就順勢整理一下筆記吧 環境 XmlSerializer LinqPad 5 Note XmlSerializer 在LinqPad 6 .NET Core 3.1,可能會出現 NotSupportedException: A non-collectible assembly may not reference a collectible assembly. 錯誤,或許是下列問題 請參考 https://github.com/dotnet/runtime/issues/1388 XML常使用Stream作為輸出入格式,這邊為了方便,直接使用LinqPad中的Console.Out功能呈現結果 各種屬性設置後XML檔案呈現結果 這是下列實作產生出來的結果,也是大致的對照表,我通常會先草擬一份XML檔,然後再使用Visual Studio 的「貼上XML做為類別」功能,對照下表,整理一份比較常見的類別檔 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class XMLObject { // <Element1>Element1</Element1> public string Element1 { get; set; } // <Element2>Element2</Element2> [XmlElement] public string Element2 { get; set; } // <NewElement>Element3</NewElement> [XmlElement("NewElement")] public string Element3 { get; set; } // 節點上的Attribute // <XMLObject Attribute1="Attribute1"></XMLObject> [XmlAttribute] public string Attribute1 { get; set; } //<SubItem1> // <ItemName>Name1</ItemName> //</SubItem1> public SubItem SubItem1 { get; set; } // <SubItems2> // <SubItem> // <ItemName>Name2</ItemName> // </SubItem> // </SubItems2> public List<SubItem> SubItems2 { get; set; } // <Items> // <SubItem> // <ItemName>Name3</ItemName> // </SubItem> // </Items> [XmlArray("Items")] public List<SubItem> SubItems3 { get; set; } // <SubItems4> // <ItemName>Name4</ItemName> // </SubItems4> [XmlElement] public List<SubItem> SubItems4 { get; set; } } public class SubItem { public string ItemName { get;set; } } 實作 序列化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 XMLObject xml = new XMLObject() { Element1 = "Element1", Element2 = "Element2", Element3 = "Element3", Attribute1 = "Attribute1", SubItem1 = new SubItem() { ItemName = "Name1" }, SubItems2 = new List<SubItem>() { new SubItem { ItemName = "Name2" } }, SubItems3 = new List<SubItem>() { new SubItem { ItemName = "Name3" } }, SubItems4 = new List<SubItem>() { new SubItem { ItemName = "Name4" } }, }; // using System.

LINE登入-使用.NET Core OAuth

LINE登入-使用.NET Core OAuth 這篇算是同場加映,因為LINE Login 微軟官方並沒有提供現成的OAuth.LINE可用,所以我研究了一下替代方案OAuth,這套件似乎不用額外安裝,因為中間也採了很多雷,覺得值得紀錄一下,順便分享出來,看是否有其他人適用,當然也不僅適用於LINE,只要是OAuth流程都可以使用,這方法主要是使用Microsoft.AspNetCore.Authentication.OAuth自己客製化。 LINE 應用程式服務建立請參考 LINE登入-手動建立登入 OAuth 2 OAuth 2.0,其工作方式如下: 應用程式(OAuth套件)將使用者導向第三方驗證連結AuthorizationEndpoint,就是那個登入視窗,使用者輸入帳號和密碼,並授權應用程式可以訪問哪些請求的資源,會不會出現請求資源的視窗,是透過設定Scope而定,並不一定會有。 OAuth會攔截授權結果,若成功會取得code,這相當於使用者同意書的概念 接著應用程式會將授權代碼code,連同ClientId、ClientSecret、CallbackPath,發送到TokenEndpoint,這是一個交換的過程,把授權書(code),還有API服務的帳號給驗證方,交換訪問令牌AccessToken。 驗證方的授權服務器返回AccessToken。 若成功取得AccessToken,應用程式會把AccessToken附在UserInformationEndpoint連結中,告知要取得個人資料。 授權服務器返回所請求的個人資料。 使用Authentication.OAuth客製化LINE登入 要先給OAuth服務一個名稱,因為可能同時存在很多個第三方驗證,這邊的名稱要與authenticationScheme對應 1 AddOAuth("Line"); 設置基本OAuth參數,如果對OAuth已經有初步了解,大概就知道這些參數的意義,多數是不能省略的,要特別留意CallbackPath這項(必填),他回傳是AuthorizationEndpoint驗證的結果code,這路徑不需要實際存在,只要與Line Developer API的回傳路徑對應即可,如果這邊填寫了實際回傳路徑,則會告訴你State驗證值被改變了,反而不能登入,程序中他會將Token轉換為TokenResponse。 另外LINE Profile 並不提供Email,所以options.Scope.Add("email")也可以省略 1 2 3 4 5 6 7 8 9 10 11 12 options.ClientId = "{應用程式編號}"; options.ClientSecret = "{應用程式密鑰}"; options.AuthorizationEndpoint = "https://access.line.me/oauth2/v2.1/authorize"; options.TokenEndpoint = "https://api.line.me/oauth2/v2.1/token"; options.UserInformationEndpoint = "https://api.line.me/v2/profile"; options.CallbackPath = new PathString("/signin-line"); options.Scope.Add("profile"); options.Scope.Add("openid"); // 這邊即使設定了Email,https://api.line.me/v2/profile 也沒有提供Email欄位 // options.Scope.Add("email"); 對應使用者資料,這邊要看API Response什麼資料 1 2 options.

LINE登入-手動建立登入 OAuth 2

LINE登入-手動建立登入 OAuth 2 Line 手動建立OAuth 和 Facebook及Google並沒有不同,都是標準的OAuth流程,有差異的地方在於Line Profile 並沒有提供Email,相反的在取出AccessToken時,也會同時取得IdToken,就看Email是否是必要項目。這邊分兩部分,上半部是申請應用程式服務,下半部是手動建立OAuth程式碼,如果建立應用程式服務的畫面與你現在的不同,不要太意外,可能改版了。 Note 要特別留意的是,若決定使用第三方驗證的Id作為會員Primary key,則服務不可隨意中止,因為不同的Provider取得的UserId是不一樣的。 例如:同時申請兩種不同的服務,LINE Login、Line Bot,兩者皆可取得UserId,但同一使用者在這兩者服務中是不同UserId的。 建立應用程式服務 到 Line Developer API 登入建立應用程式 選擇Create a LINE Login channel 填入Channel name和Channel Description,有提醒你哪些欄位不能為空 完成後你應該就可以看到Channel ID 和 Channel secret,這兩欄我們在交換權杖的時候會用到 下面有一個Email address permission,這個是選填,勾選後,使用者在第一次登入時,會出現是否同意讓應用程式讀取Email,如果你的應用程式不需要Email就不用管他 接下來在LINE Login的地方,要填寫回傳網址,填寫完畢後,整個建立過程就結束了 實作 取得叫用「登入」對話方塊與設定重新導向網址 這邊參數請參考https://developers.line.biz/zh-hant/docs/line-login/integrate-line-login/#making-an-authorization-request 1 2 3 4 5 6 7 8 9 10 11 public IActionResult Index() { State = Guid.NewGuid(); ViewData["LineAuth"] = $"https://access.line.me/oauth2/v2.1/authorize?" + $"client_id={_appId}" + $"&response_type=code" + $"&redirect_uri={RedirectUrl}" + $"&scope={HttpUtility.

Google登入-手動建立登入 OAuth 2

Google登入-手動建立登入 OAuth 2 Google 文件我實在不太習慣,所以這邊算是有點東拼西湊的,照自己的理解實作,我會把找到的文件參考連結,放在步驟裡面 Google 官方也有一份.NET OAuth,似乎是獨立文件,只是裡面有很多使用Google 自行開發的Library,我沒有採用,一樣放在參考部分 實作 先找到OAuth 驗證連結,參考要傳送的選項,組合驗證連結,這邊要留意文件中Score說明 1 2 3 4 5 6 7 8 9 10 11 12 13 public IActionResult Index() { State = Guid.NewGuid(); // scope 來自於要啟用的Google API,因為我們只是要取得最基本的資料,所以這邊直接設定 profile // 如果是使用不同的Google API服務,這邊的Scope值也會不同 ViewData["GoogleAuth"] = $"https://accounts.google.com/o/oauth2/auth?" + $"scope={HttpUtility.UrlEncode("profile email")}" + $"&response_type=code" + $"&state={State}" + $"&redirect_uri={RedirectUrl}" + $"&client_id={_appId}"; return View(); } 參考OAuth Response結果,這邊大致上都是code、state、error,依照這結果設置使用者同意或不同意的導回結果 1 2 3 4 5 6 public async Task<IActionResult> SignInGoogle(string code, Guid state, string error, string error_description) { // 有錯誤訊息(未授權等)、State遺失、State不相同、沒有code if (!

Google登入-.NET Core Identity簡化版

Google登入-.NET Core Identity簡化版 就在我以為抽離Identity只使用第三方驗證的部分很簡單的時候,瞬間被打臉…一開始不管怎麼做都不會過,但過幾天後,回來截圖,重新改回正常流程,又能過…我個人猜測是憑證問題或是google回傳路徑設定,這也是我在Google SDK API那篇中,強烈建議使用預設的回傳路徑/signin-google的原因。 環境 .NET Core 3.1 Nuget > Microsoft.AspNetCore.Authentication.Google Note 先到Google Cloud Platform 建立應用程式服務,步驟請參考 實作 先安裝Microsoft.AspNetCore.Authentication.Google 在Startup.cs 中設置服務 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddGoogle(options => { options.ClientId = "{應用程式編號}"; options.ClientSecret = "{應用程式密鑰}"; }).AddCookie(options => { options.

Google登入-Google SDK API

Google登入-Google SDK API 這篇主要是Google SDK API的登入驗證,和Facebook提供的SDK差不多,都是複製貼上就可以動的優良程式!,唯一比較大的缺點是,改版速度太快,文件又多又雜,且幾乎是英文文件,散落於各處,很容易困惑到底該使用哪個API服務…,友善提醒,Google官網改版很快,申請畫面不同很正常。 建立應用程式服務 到 Google Cloud Platform 申請建立應用程式 選擇網頁應用程式,使用Javascript SDK,填入已授權的 JavaScript 來源及已授權的重新導向 URI,使用Javascript SDK重新導向網址在可以不填,不過我在另一篇中有用到這項,所以圖示上還是填寫了,這邊會特別講是因為,那個回傳網址,強烈建議不要更動,也就是使用/signin-google,這組,可以省掉很多很多的問題… 建立完成後,就可以看到用戶端ID和用戶端密碼,這兩項等等要輸入到SDK中,畫面關掉也沒關係,外面也可以找到 如果只是要登入的部分,這邊就結束了,如果要取得使用者資料,則需要再申請API服務,可以取得使用者資料的API很多 微軟使用的是 https://www.googleapis.com/oauth2/v2/userinfo 而Google Javascript SDK範例是使用 Google People API,不清楚差異,但我們只要ID、Name、Email,擇一即可 點資料庫,選擇 Google People API 並啟用 Google People API啟用後,我們就要申請一組API Key,有這組Key,API才可以正常使用,Google API 服務與Key是分開的,一組Key可以多組服務,也可以一組Key對應一組服務,另外Google會提醒你配額問題,可能有部分的API服務會計費,詳細請自行查看Google配額說明,這邊不詳細介紹。 應用程式建立到這邊基本流程就結束了,Google API服務、憑證、Key三者都是分開申請的,所以申請順序沒有太大差異,如果參照其他Blog發現順序好像不一樣,是很正常的,簡而言之,只要你有申請這三項應該都可以正常執行。 實作 Google SDK API,有提供GitHub連結,範例程式碼照貼即可運作,記得填寫自己的API KEY及申請的用戶端ID,我直接將幾個重點標註在程式碼中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 <p>Say hello using the People API.