RestClient ライブラリは、REST サービスを利用するためのシンプルなコネクタを提供します。
プロジェクトで使用するには、Mafe.RestClient NuGet パッケージをプロジェクトに追加します。
RestClient の目標は、開発者が非常に簡単な方法で任意のサーバーに簡単に接続できるようにすることです。データ転送オブジェクト (Dto) を定義するだけで、クライアントでの操作を開始できます。
Build() メソッドを使用して、Rest から RestBuilder を作成します。
var rest = Rest . Build ( ) ;
単純な get 呼び出しを作成するには、次のように実行します。
var rest = Rest . Build ( ) ;
var result = rest . Url ( "[URL]" ) . Get ( ) ;
または、GetAsync() メソッドを使用することもできます。
var rest = Rest . Build ( ) ;
var result = await rest . Url ( "[URL]" ) . GetAsync ( ) ;
このドキュメント内で「[URL]」という単語を見つけると、それは WebAPI のベース URL 定義を指します。
Root() エンドポイントを定義し、それを使用してリクエストを構築できます。
public RestBuilder Root ( ) => rest . Url ( "https://mywebapi.mydomain.com" ) ;
そして、次のように使用できます。
public RestBuilder Root ( ) => Rest . Build ( ) . Url ( "https://mywebapi.mydomain.com" ) ;
var result = Root ( )
. Command ( "/my-action" )
. Payload ( "mystring" )
. Post ( ) ;
RestProperties を使用して、yuorrest ルート ポイントを構成します。単純な構成を作成するには、次のようにします。
RestProperties properties = new RestProperties
{
EndPoint = new Uri ( "[URL]" ) , //if you use .Url("[URL]") you override it
BufferSize = 4096 ,
CertificateOption = ClientCertificateOption . Manual ,
Timeout = TimeSpan . FromMinutes ( 2 )
} ;
Build() メソッドをプロパティとともに使用して、Rest から RestBuilder を作成します。
var rest = Rest . Build ( properties ) ;
X.509 証明書の検証は、中間者攻撃に対して脆弱でない安全な SSL/TLS セッションを作成するために不可欠です。
証明書チェーンの検証には次の手順が含まれます。
カスタム証明書チェーン検証を実装して車輪を再発明することはお勧めしません。
TLS ライブラリは、使用する必要がある組み込みの証明書検証機能を提供します。
List < string > validCerts = new List < string > ( ) {
"CERT STRING"
} ;
var result = Rest . Build ( )
. CertificateValidation ( ( sender , certificate , chain , errors ) =>
{
// for development, trust all certificates
if ( development ) return true ;
// Compliant: trust only some certificates
return errors == SslPolicyErrors . None
&& validCerts . Contains ( certificate . GetCertHashString ( ) ) ;
} )
. Url ( "[URL]" )
. Get ( ) ;
HTTP/1.1 [RFC2617] で定義されているように、アプリケーションは認可リクエスト ヘッダーで access_token を直接送信する必要があります。これを行うには、ベアラー トークンの access_token 値を HTTP リクエスト本文に「Authorization: Bearer {access_token_value}」として含めます。
認証されたユーザーが期限切れのベアラー トークンの access_token またはfresh_token を持っている場合、「401 - Unauthorized (無効または期限切れのリフレッシュ トークン)」エラーが返されます。
var result = Rest . Build ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. Url ( "[URL]" )
. Get ( ) ;
有効なベアラー トークン (アクティブな access_token または fresh_token プロパティを持つ) は、ユーザーが資格情報を頻繁に再入力することなく、ユーザーの認証を維持します。 access_token は、アクティブである限り、ログインまたは更新後最大 1 時間使用できます。 fresh_token は 336 時間 (14 日間) 有効です。 access_token の有効期限が切れると、次の例に示すように、アクティブなfresh_token を使用して新しい access_token /fresh_token ペアを取得できます。このサイクルは最大 90 日間継続することができ、その後、ユーザーは再度ログインする必要があります。 Refresh_token の有効期限が切れると、トークンを更新できないため、ユーザーは再度ログインする必要があります。
トークンを更新するには、「RefreshTokenInvoke」を自動的に使用します。
var url = "[URL]" ;
var result = Rest . Build ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. RefreshToken ( true )
. RefreshTokenInvoke ( async ( ) =>
{
var result = await rest
. Url ( url )
. Command ( "/refresh" )
. GetAsync < TokenObjectResponse > ( ) ;
doSomethings ( ) ; //store the token inside your env.
return result ;
} )
. Command ( "/detail" )
. Url ( url )
. Get ( ) ;
Refresh_token を取り消す必要があります。
NetworkCredential クラスは、基本、ダイジェスト、NTLM、Kerberos などのパスワード ベースの認証スキームで資格情報を提供する基本クラスです。 CredentialCache クラスなど、ICredentials インターフェイスを実装するクラスは、NetworkCredential オブジェクトを返します。このクラスは、Secure Sockets Layer (SSL) クライアント認証などの公開キーベースの認証方法をサポートしません。
var result = Rest . Build ( )
. NetworkCredential ( "myUsername" , "myPassword" )
. Url ( "[URL]" )
. Get ( ) ;
var result = rest
. NetworkCredential ( ( ) => new System . Net . NetworkCredential ( "myUsername" , "myPassword" ) )
. Url ( "[URL]" )
. Get ( ) ;
Headers コレクションには、要求に関連付けられたプロトコル ヘッダーが含まれています。 Header((h)=>{}) メソッドを使用すると、キーのリストを追加できます。
var result = Rest . Build ( )
. Header ( ( h ) => {
if ( ! h . Contains ( "auth-custom" ) )
h . Add ( "auth-custom" , "value" ) ;
} )
. Url ( "[URL]" )
. Get ( ) ;
RestClient では、Xml と Json という 2 種類のシリアル化がサポートされていますが、ISerializerContent を実装してシリアル化をカスタマイズすることが可能です。 RestClient は .Json() を使用してオブジェクトを json にシリアル化します。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( )
. Get < ResponseObject > ( ) ;
次のように、json シリアライザー オプションを .Json() メソッドに渡すことができます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( new JsonSerializerOptions {
WriteIndented = true
} )
. Get < ResponseObject > ( ) ;
上記のスニペット コードでは、System.Text.Json ライブラリの使用を考慮しています。 Netwnsoft を次のように使用すると:
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( new JsonSerializerSettings {
Formatting = Formatting . Indented
} )
. Get < ResponseObject > ( ) ;
RestClient は .Xml() を使用してオブジェクトを XML にシリアル化します。
var result = rest
. Url ( "[URL]" )
. Xml ( )
. Get < ResponseObject > ( ) ;
次のように、設定を .Xml() メソッドに渡すことができます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Xml ( new XmlReaderSettings { Indent = true } , new XmlWriterSettings { IgnoreWhitespace = true } )
. Get < ResponseObject > ( ) ;
以下は、ISerializerContent インターフェイスを実装してカスタム シリアル化を行う方法の例です。
public class MyCustomSerializer : ISerializerContent
{
public string MediaTypeAsString => throw new NotImplementedException ( ) ;
public object DeserializeObject ( string value , Type typeOf , object options = null )
{
throw new NotImplementedException ( ) ;
}
public string SerializeObject ( object value , Type typeOf , object options = null )
{
throw new NotImplementedException ( ) ;
}
}
これで、次のように MyCustomSerializer を使用できます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. CustomSerializer ( new MyCustomSerializer { } )
. Get < ResponseObject > ( ) ;
BufferSize を使用して、ストリームのアップロードおよびダウンロード中にバッファ サイズを設定できます。デフォルト値は80Kbです
var result = Rest . Build ( )
. Url ( "[URL]" )
. BufferSize ( 4096 * 5 * 5 ) //100Kb
. Get ( ) ;
指定したリソースとの通信中に gzip 圧縮を有効にします。
var result = Rest . Build ( )
. Url ( "[URL]" )
. EnableGZipCompression ( )
. Get ( ) ;
ライブラリは応答を自動的に解凍します。
GET は最も一般的な HTTP メソッドの 1 つであり、指定されたリソースからデータをリクエストするために使用されます。
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Get ( ) ;
var result = await rest
. Url ( "[URL]" )
. GetAsync ( ) ;
GET リクエストに関するその他の注意事項:
クエリ文字列 (名前と値のペア) は GET リクエストの URL で送信されることに注意してください。
場合によっては、引数をクエリ文字列として使用する必要があります。メソッド Parameter(key, value) を使用して、次のように解決できます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/path" )
. Parameter ( "id" , "10" )
. Parameter ( "type" , "myType" )
. Get ( ) ;
生成される URL は次のとおりです: [URL]/path?id=10&type=myType
POST は、リソースを作成/更新するためにサーバーにデータを送信するために使用されます。 POST でサーバーに送信されたデータは、HTTP リクエストのリクエスト ペイロードに保存されます。
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. Post < ResponseObject > ( ) ;
var result = await rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. PostAsync < ResponseObject > ( ) ;
Post はもう 1 つの一般的な http メソッドであり、次の目的で使用されます。
PUT は、リソースを作成/更新するためにサーバーにデータを送信するために使用されます。
POST と PUT の違いは、PUT リクエストが冪等であることです。つまり、同じ PUT リクエストを複数回呼び出すと、常に同じ結果が生成されます。対照的に、POST リクエストを繰り返し呼び出すと、同じリソースが複数回作成されるという副作用があります。
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. Put < ResponseObject > ( ) ;
var result = await rest
. Url ( "[URL]" )
. Payload ( new Object { } )
. PutAsync < ResponseObject > ( ) ;
DELETE メソッドは、指定されたリソースを削除します。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. Delete < ResponseObject > ( ) ;
var result = await Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. DeleteAsync < ResponseObject > ( ) ;
DOWNLOAD メソッドは、指定されたリソースをダウンロードします。
var result = Rest . Build ( )
. Download ( "[URL]" ) ;
var result = await rest
. DownloadAsync ( "[URL]" ) ;
OnDownloadProgressでダウンロード状況を表示することが可能です。
var rest = Rest . Build ( ) ;
var result = await rest
. OnDownloadProgress ( ( d ) => Console . WriteLine ( $ " { d . CurrentBytes } / { d . TotalBytes } " ) )
. DownloadAsync ( "[URL]" ) ;
操作をキャンセルする必要があるという通知を伝達します。
CancelToken を使用すると、スレッド、スレッド プールの作業項目、または Task オブジェクト間の協調的なキャンセルが可能になります。キャンセル トークンを作成するには、CancelTokenSource オブジェクトをインスタンス化して、CancelTokenSource から取得したキャンセル トークンを管理します。
次の例では、キャンセル トークンを使用して実行を停止します。
// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource ( ) ;
CancellationToken token = source . Token ;
// Schedules a cancel operation on this System.Threading.CancellationTokenSource
// after the specified number of milliseconds
token . CancelAfter ( 3000 ) ;
var file1 = Rest . Build ( ) . DownloadAsync ( "[URL FILE1]" , token . Token ) ;
var file2 = Rest . Build ( ) . DownloadAsync ( "[URL FILE2]" , token . Token ) ;
var get1 = Rest . Build ( ) . Url ( "[URL GET1]" ) . GetAsync < MyObject > ( token . Token ) ;
Task . WaitAll ( file1 , file2 , get1 ) ;
キャンセルが要求されると、TaskCancelratedException がスローされます。例外は RestResult オブジェクトにカプセル化されます。
指定されたリソースをカスタマイズする CUSTOM メソッド。
HttpMethod PATCH = new HttpMethod ( "PATCH" ) ;
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. CustomCall < ResponseObject > ( PATCH ) ;
var result = await rest
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new Object { } )
. CustomCallAsync < ResponseObject > ( PATCH ) ;
RestClient は Playload(obj) メソッドを使用して、リクエストに応じてオブジェクトを設定します。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new RequestObject { } )
. Post < ResponseObject > ( ) ;
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. Payload ( new RequestObject { } )
. Put < ResponseObject > ( ) ;
必要に応じて、リクエストをフォーム URL エンコードとして使用できます。これを使用するには、次のように有効にする必要があります。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. EnableFormUrlEncoded ( true )
そしてパラメータを辞書として渡すことができます。
var params = new Dictionary < string , string > ( ) ;
params . Add ( "key1" , "value1" ) ;
params . Add ( "key2" , "value2" ) ;
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. EnableFormUrlEncoded ( true )
. FormUrlEncoded ( params )
. Post ( ) ;
ハンドラー内でパラメーターを渡し、フォーム URL エンコードを有効にすることができます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. FormUrlEncoded ( true , ( p ) =>
{
p . Add ( "key1" , "value1" ) ;
p . Add ( "key2" , "value2" ) ;
} )
. Post ( ) ;
OnUploadProgress は、リクエストが実行され、データが送信されるときに発生します。次のようにして、アップロードされているデータの割合を取得できます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnUploadProgress ( p =>
{
DoSomethings ( p . ProgressPercentage ) ;
} ) //occurs during request
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnDownloadProgress は、応答が実行され、データが受信されるときに発生します。次のように、ダウンロードされているデータの割合を取得できます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnDownloadProgress ( p =>
{
DoSomethings ( p . ProgressPercentage ) ;
} ) //occurs during response
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
デフォルト値は 100,000 ミリ秒 (100 秒) です。無限のタイムアウトを設定するには、プロパティ値を InfiniteTimeSpan に設定します。ドメイン ネーム システム (DNS) クエリが返されるか、タイムアウトになるまでに最大 15 秒かかる場合があります。リクエストに解決が必要なホスト名が含まれており、タイムアウトを 15 秒未満の値に設定した場合、リクエストのタイムアウトを示す例外がスローされるまでに 15 秒以上かかることがあります。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Timeout ( 3200 ) //milliseconds
. Get < ResponseObject > ( ) ;
var result = Rest . Build ( )
. Url ( "[URL]" )
. Timeout ( TimeSpan . FromMinutes ( 10 ) )
. Get < ResponseObject > ( ) ;
OnStart は、リクエストの開始時にトリガーされるイベントです。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnStart ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnPreviewContentRequestAsString は、リクエストの準備ができてまだ送信されていないときにトリガーされるイベントです。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreviewContentRequestAsString ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnPreviewContentResponseAsString は、応答が受信され、まだ逆シリアル化されていないときにトリガーされるイベントです。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreviewContentResponseAsString ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnPreResult は、リクエストが完了しつつあるものの、まだ完了していないときに発生します。 OnPreResult が発生すると、リクエストの結果を取得して使用するなど、何かを行うことができます。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnPreCompleted ( ( r ) => {
DoSomethings ( r . Result ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnException は、リクエストで例外が発生した場合に発生します。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnException ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
OnCompleted はリクエストが完了したときに発生します。
var result = Rest . Build ( )
. Url ( "[URL]" )
. Command ( "/action" )
. OnCompleted ( ( e ) => {
DoSomethings ( e ) ;
} )
. Payload ( new BigObject { } )
. Post < ResponseObject > ( ) ;
RestClient を使用すると、柔軟で堅牢なネットワーク層を作成でき、非常に使いやすいです。以下に完全なコードのデモと完全なコード例を示します。
public class NetworkService {
//building context
public RestBuilder Root ( )
=> Rest . Build ( )
. CertificateValidation ( ( sender , certificate , chain , errors ) =>
{
if ( development ) return true ;
return errors == SslPolicyErrors . None
&& validCerts . Contains ( certificate . GetCertHashString ( ) ) ;
} )
. Url ( "[URL]" ) ;
public RestBuilder RootAuthentication ( )
=> Root ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. RefreshToken ( )
. RefreshTokenInvoke ( async ( ) => await PostRefreshAsync ( new RefreshRequest { } ) ) ;
public RestBuilder UsersRoot ( )
=> Root ( ) . Command ( "/Users" ) ;
public RestBuilder DimensionsRoot ( )
=> Root ( ) . Command ( "/Dimensions" ) ;
public RestBuilder EventsRoot ( )
=> RootAuthentication ( ) . Command ( "/Events" ) ;
//requests
public async Task < RestResult < LoginResponse > > PostLoginAsync ( LoginRequest request )
=> await UsersRoot ( )
. Command ( "/Login" ) //[URL]/Users/Login
. Payload ( request )
. PostAsync < LoginResponse > ( ) ;
public async Task < RestResult < RuleResponse > > GetRulesAsync ( )
=> await UsersRoot ( )
. Command ( "/Rules" )
. GetAsync < RuleResponse > ( ) ;
public async Task < RestResult < RefreshResponse > > PostRefreshAsync ( RefreshRequest request )
=> await UsersRoot ( )
. Command ( "/Refresh" )
. Payload ( request )
. PostAsync < RefreshResponse > ( ) ;
public async Task < RestResult < CountryResponse > > PostCountriesAsync ( CountryRequest request )
=> await DimensionsRoot ( )
. Command ( "/Countries" )
. Payload ( request )
. PostAsync < CountryResponse > ( ) ;
public async Task < RestResult < EventDetailResponse > > PostEventDetailAsync ( EventDetailRequest request )
=> await EventsRoot ( )
. Command ( "/EventDetail" )
. Payload ( request )
. PostAsync < EventDetailResponse > ( ) ;
}