ไลบรารี RestClient มอบตัวเชื่อมต่อที่ใช้งานง่ายเพื่อใช้บริการ REST
หากต้องการใช้ในโครงการของคุณ ให้เพิ่มแพ็คเกจ Mafe.RestClient NuGet ไปยังโครงการของคุณ
เป้าหมายของ RestClient คือการทำให้นักพัฒนาสามารถเชื่อมต่อกับเซิร์ฟเวอร์ใด ๆ ได้อย่างง่ายดายด้วยวิธีที่ง่ายมาก เพียงกำหนด Data Transfer Object (Dto) ของคุณแล้วเริ่มเล่นกับไคลเอนต์!
ใช้เมธอด Build() เพื่อสร้าง RestBuilder จาก Rest:
var rest = Rest . Build ( ) ;
หากต้องการสร้างการรับสายแบบง่ายๆ เพียงทำดังนี้:
var rest = Rest . Build ( ) ;
var result = rest . Url ( "[URL]" ) . Get ( ) ;
หรือเราสามารถใช้เมธอด GetAsync() ได้:
var rest = Rest . Build ( ) ;
var result = await rest . Url ( "[URL]" ) . GetAsync ( ) ;
เมื่อใดก็ตามที่คุณพบคำว่า "[URL]" ในเอกสารนี้จะหมายถึงคำจำกัดความ URL พื้นฐานของ webAPI
เราสามารถกำหนดจุดสิ้นสุด 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 เพื่อกำหนดค่าจุดรูทส่วนที่เหลือ หากต้องการสร้างการกำหนดค่าอย่างง่าย ให้ทำดังนี้:
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() พร้อมคุณสมบัติเพื่อสร้าง RestBuilder จาก Rest:
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 เป็น 'การอนุญาต: ผู้ถือ {access_token_value}'
หากผู้ใช้ที่ได้รับการตรวจสอบความถูกต้องมี access_token หรือ Refresh_token ของผู้ถือโทเค็นที่หมดอายุแล้ว ข้อผิดพลาด '401 - ไม่ได้รับอนุญาต (โทเค็นการรีเฟรชไม่ถูกต้องหรือหมดอายุ)' จะถูกส่งกลับ
var result = Rest . Build ( )
. Authentication ( ( ) => new AuthenticationHeaderValue ( "Bearer" , "[Token]" ) )
. Url ( "[URL]" )
. Get ( ) ;
โทเค็นผู้ถือที่ถูกต้อง (พร้อมคุณสมบัติ access_token หรือ Refresh_token ที่ใช้งานอยู่) ช่วยให้การรับรองความถูกต้องของผู้ใช้ยังคงอยู่โดยไม่ต้องให้ผู้ใช้ป้อนข้อมูลประจำตัวซ้ำบ่อยๆ access_token สามารถใช้งานได้ตราบเท่าที่มีการใช้งานอยู่ ซึ่งสูงสุดหนึ่งชั่วโมงหลังจากการเข้าสู่ระบบหรือต่ออายุ Refresh_token ใช้งานได้ 336 ชั่วโมง (14 วัน) หลังจากที่ access_token หมดอายุ สามารถใช้ Refresh_token ที่ใช้งานอยู่เพื่อรับคู่ access_token / Refresh_token ใหม่ดังที่แสดงในตัวอย่างต่อไปนี้ รอบนี้สามารถดำเนินต่อไปได้นานถึง 90 วัน หลังจากนั้นผู้ใช้จะต้องเข้าสู่ระบบอีกครั้ง หาก Refresh_token หมดอายุ โทเค็นจะไม่สามารถต่ออายุได้ และผู้ใช้จะต้องเข้าสู่ระบบอีกครั้ง
หากต้องการรีเฟรชโทเค็น ให้ใช้ "RefreshTokenInrigg" โดยอัตโนมัติ
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 คลาสที่ใช้อินเทอร์เฟซ ICredentials เช่นคลาส CredentialCache จะส่งกลับอ็อบเจ็กต์ 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 ( ) ;
คอลเลกชันส่วนหัวประกอบด้วยส่วนหัวของโปรโตคอลที่เกี่ยวข้องกับคำขอ เมธอด Header((h)=>{}) ช่วยให้คุณสามารถเพิ่มรายการคีย์ได้
var result = Rest . Build ( )
. Header ( ( h ) => {
if ( ! h . Contains ( "auth-custom" ) )
h . Add ( "auth-custom" , "value" ) ;
} )
. Url ( "[URL]" )
. Get ( ) ;
RestClient รองรับการทำให้ซีเรียลไลซ์สองประเภท: Xml และ Json แต่เป็นไปได้ที่จะใช้งาน ISerializerContent เพื่อปรับแต่งการทำให้ซีเรียลไลซ์ RestClient ใช้ .Json() เพื่อทำให้วัตถุเป็นอนุกรมเป็น json
var result = Rest . Build ( )
. Url ( "[URL]" )
. Json ( )
. Get < ResponseObject > ( ) ;
เป็นไปได้ที่จะส่งตัวเลือก json serializer ไปยังเมธอด .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 ที่ใช้บ่อยที่สุด และ GET ใช้เพื่อขอข้อมูลจากทรัพยากรที่ระบุ
var rest = Rest . Build ( ) ;
var result = rest
. Url ( "[URL]" )
. Get ( ) ;
var result = await rest
. Url ( "[URL]" )
. GetAsync ( ) ;
หมายเหตุอื่นๆ เกี่ยวกับคำขอ GET:
โปรดทราบว่าสตริงการสืบค้น (คู่ชื่อ/ค่า) จะถูกส่งไปใน URL ของคำขอ GET
ในบางกรณีเราจำเป็นต้องใช้อาร์กิวเมนต์เป็นสตริงการสืบค้น เราสามารถใช้เมธอดพารามิเตอร์ (คีย์, ค่า) เพื่อแก้ไขได้ดังนี้:
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 เป็นอีกหนึ่งวิธี http ทั่วไปที่ใช้เพื่อ:
PUT ใช้เพื่อส่งข้อมูลไปยังเซิร์ฟเวอร์เพื่อสร้าง/อัปเดตทรัพยากร
ความแตกต่างระหว่าง POST และ PUT ก็คือคำขอ PUT นั้นเป็น idempotent นั่นคือการเรียกคำขอ 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 > ( ) ;
วิธีการดาวน์โหลดจะดาวน์โหลดทรัพยากรที่ระบุ
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]" ) ;
เผยแพร่การแจ้งเตือนว่าควรยกเลิกการดำเนินการ
CancellationToken ช่วยให้สามารถยกเลิกการทำงานร่วมกันระหว่างเธรด รายการงานพูลเธรด หรือวัตถุงาน คุณสร้างโทเค็นการยกเลิกโดยการสร้างอินสแตนซ์อ็อบเจ็กต์ CancellationTokenSource ซึ่งจัดการโทเค็นการยกเลิกที่ดึงมาจาก CancellationTokenSource
ตัวอย่างต่อไปนี้ใช้โทเค็นการยกเลิกเพื่อหยุดการดำเนินการ:
// 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 ) ;
หลังจากการร้องขอการยกเลิก มันจะส่ง TaskCancellatedException ข้อยกเว้นจะถูกห่อหุ้มไว้ในวัตถุ 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 > ( ) ;
}