Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use REST.NET Standard Library refit

2025-02-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the relevant knowledge of "how to use the REST.NET standard library refit". The editor shows you the operation process through the actual case. The operation method is simple, fast and practical. I hope this article "how to use the REST.NET standard library refit" can help you solve the problem.

1. Brief introduction

Refit is an automatic type-safe REST library inspired by Square's Retrofit library (Java). Through HttpClient network request (POST,GET,PUT,DELETE, etc.), the data returned by REST API is transformed into POCO (Plain Ordinary C # Object, simple C # object) to JSON. Our application requests the network through Refit, in fact, it uses Refit interface layer to encapsulate request parameters, Header, Url and other information, and then HttpClient completes the subsequent request operations. After the server returns data, HttpClient gives the original results to Refit, which parses the results according to the needs of users. Install the component command line:

Install-Package refit

Code example:

[Headers ("User-Agent: Refit Integration Tests")] / / since the target source is GitHubApi, be sure to add this static request header information to make it a test request, otherwise a data exception will be returned. Public interface IGitHubApi {[Get ("/ users/ {user}")] Task GetUser (string user);} public class GitHubApi {public async Task GetUser () {var gitHubApi = RestService.For ("https://api.github.com"); var octocat = await gitHubApi.GetUser (" octocat "); return octocat;}} public class User {public string login {get; set;} public int? Id {get; set;} public string url {get; set;}} [HttpGet] public async Task Get () {var result = await new GitHubApi () .GetUser (); return new string [] {result.id.Value.ToString (), result.login};}

Note: the attributes Headers and Get in the interface are called Refit features.

Define a REST API interface for IGitHubApi above, which defines a function GetUser that encapsulates the returned result as a User POCO object and returns it through the HTTP GET request to access the server's / users/ {user} path. Where the value of {user} in the URL path is the value of the parameter user in the GetUser function, where the value is assigned to octocat. Then an implementation of the IGitHubApi interface is generated through the RestService class and called by HttpClient.

2.API attribute

Each method must have the provide request URL and HTTP attributes. The HTTP property has six built-in comments: Get, Post, Put, Delete, Patch and Head, for example:

[Get ("/ users/list")]

You can also specify query parameters in the request URL:

[Get ("/ users/list?sort=desc")]

You can also use replacement blocks and parameters on the relative URL to request resources dynamically. The replacement block is an alphanumeric string surrounded by {and, or &}. If the parameter name does not match the name in the URL path, use the AliasAs attribute, for example:

[Get ("/ group/ {id} / users")] Task GroupList ([AliasAs ("id")] int groupId)

Request URL can also bind replacement blocks to custom objects, for example:

[Get ("/ group/ {request.groupId} / users/ {request.userId}")] Task GroupList (UserGroupRequest request); class UserGroupRequest {int groupId {get;set;} int userId {get;set;}}

Parameters that are not specified to be replaced by URL are automatically used as query parameters. This is different from Retrofit, where all parameters must be specified explicitly in Retrofit, for example:

[Get ("/ group/ {id} / users")] Task GroupList ([AliasAs ("id")] int groupId, [AliasAs ("sort")] string sortOrder); GroupList (4, "desc")

Output: "/ group/4/users?sort=desc"

3. Dynamic query string parameter (Dynamic Querystring Parameters)

Method can also pass a custom object, appending object properties to the query string parameters, such as:

Public class MyQueryParams {[AliasAs ("order")] public string SortOrder {get; set;} public int Limit {get; set;}} [Get ("/ group/ {id} / users")] Task GroupList ([AliasAs ("id")] int groupId, MyQueryParams params); [Get ("/ group/ {id} / users")] Task GroupListWithAttribute ([AliasAs ("id")] int groupId, [Query ("" search ")] MyQueryParams params); params.SortOrder =" desc "; params.Limit = 10 GroupList (4, params)

Output: "/ group/4/users?order=desc&Limit=10"

GroupListWithAttribute (4, params)

Output: "/ group/4/users?search.order=desc&search.Limit=10"

You can also use [Query] to specify the querystring parameter and flatten it in a non-GET request, similar to:

[Post ("/ statuses/update.json")] Task PostTweet ([Query] TweetParams params) 4. Collection as a query string parameter (Collections as Querystring Parameters)

Method not only supports passing custom object queries, but also supports collection queries, for example:

[Get ("/ users/list")] Task Search ([Query (CollectionFormat.Multi)] int [] ages); Search (new [] {10,20,30})

Output: "/ users/list?ages=10&ages=20&ages=30"

[Get ("/ users/list")] Task Search ([Query (CollectionFormat.Csv)] int [] ages); Search (new [] {10,20,30})

Output: "/ users/list?ages=10%2C20%2C30"

5. Escape character query string parameter (Unescape Querystring Parameters)

Use the QueryUriFormat attribute to specify whether the query parameter should escape the URL, for example:

[Get ("/ query")] [QueryUriFormat (UriFormat.Unescaped)] Task Query (string Q); Query ("Select+Id,Name+From+Account")

Output: "/ query?q=Select+Id,Name+From+Account"

6.Body content

By using the Body attribute, you can append custom object parameters to the HTTP request Body.

[Post ("/ users/new")] Task CreateUser ([Body] User user)

Depending on the type of parameter, there are four possibilities for providing Body data:

If the type is Stream, the content is transmitted as an StreamContent stream.

If the type is string, the string is used directly as the content, and unless [Body (BodySerializationMethod.Json)] sets the string, it is used as a StringContent.

If the parameter has the attribute [Body (BodySerializationMethod.UrlEncoded)], the content will be encoded by URL.

For all other types, the object is serialized using the content serializer specified in RefitSettings (default is JSON).

Buffer and Content-Length header

By default, Refit re-adjusts the streaming body content without buffering it. For example, this means that you can stream files from disk without the overhead of loading the entire file into memory. The disadvantage of this is that the content length header (Content-Length) is not set on the request. If your API requires you to send a content length header with the request, you can disable this popularity by setting the buffer parameter of the [Body] property to true:

Task CreateUser ([Body (buffered: true)] User user); 6.1.JSON content

Serialize / deserialize JSON requests and responses using Json.NET. By default, Refit uses serializer settings that can be configured by setting Newtonsoft.Json.JsonConvert.DefaultSettings:

JsonConvert.DefaultSettings = () = > new JsonSerializerSettings () {ContractResolver = new CamelCasePropertyNamesContractResolver (), Converters = {new StringEnumConverter ()}}; / / Serialized as: {"day": "Saturday"} await PostSomeStuff (new {Day = DayOfWeek.Saturday})

Because the default static configurations are global settings, they affect your entire application. Sometimes we only want to set certain API, and you can choose to use the RefitSettings property to allow you to specify the desired serializer settings, which allows you to set different serializer settings for individual API:

Var gitHubApi = RestService.For ("https://api.github.com", new RefitSettings {ContentSerializer = new JsonContentSerializer (new JsonSerializerSettings {ContractResolver = new SnakeCasePropertyNamesContractResolver ()})}) Var otherApi = RestService.For ("https://api.example.com", new RefitSettings {ContentSerializer = new JsonContentSerializer (new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver ()})})

You can also use the JsonProperty property of Json.NET to customize property serialization / deserialization:

Public class Foo {/ / like [AliasAs ("b")] posts [JsonProperty (PropertyName= "b")] public string Bar {get; set;}} 6.2XML content in the form

XML requests and responses are serialized / deserialized using System.XML.Serialization.XmlSerializer. By default, Refit only serializes content using JSON. To use XML content, configure ContentSerializer to use XmlContentSerializer:

Var gitHubApi = RestService.For ("https://www.w3.org/XML", new RefitSettings {ContentSerializer = new XmlContentSerializer ()})

Attribute serialization / deserialization can be customized using attributes in the System.Xml.serialization namespace:

Public class Foo {[XmlElement (Namespace = "https://www.w3.org/XML")] public string Bar {get; set;}})

System.Xml.Serialization.XmlSerializer provides a number of serialization options that can be set by providing XmlContentSerializer settings to the XmlContentSerializer constructor:

Var gitHubApi = RestService.For ("https://www.w3.org/XML", New RefitSettings {ContentSerializer = new XmlContentSerializer (new XmlContentSerializerSettings {XmlReaderWriterSettings = new XmlReaderWriterSettings () {ReaderSettings = new XmlReaderSettings {IgnoreWhitespace = true})}) 6.3. Form publishing (Form posts)

For API published as a form (that is, serialized to application/x-www-form-urlencoded), use the initialization Body attribute BodySerializationMethod.UrlEncoded property, which can be an IDictionary dictionary, for example:

Public interface IMeasurementProtocolApi {[Post ("/ collect")] Task Collect ([Body (BodySerializationMethod.UrlEncoded)] Dictionary data);} var data = new Dictionary {{"v", 1}, {"tid", "UA-1234-5"}, {"cid", new Guid ("d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c")}, {"t", "event"},} / Serialized as: v=1&tid=UA-1234-5&cid=d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c&t=eventawait api.Collect (data)

If the passed object is inconsistent with the field name in the request form, you can add a [AliasAs ("you define the field name")] attribute to the object property name, and the object fields added will be serialized into the form fields in the request:

Public interface IMeasurementProtocolApi {[Post ("/ collect")] Task Collect ([Body (BodySerializationMethod.UrlEncoded)] Measurement measurement);} public class Measurement {/ / Properties can be read-only and [AliasAs] isn't required public int v {get {return 1;}} [AliasAs ("tid")] public string WebPropertyId {get; set;} [AliasAs ("cid")] public Guid ClientId {get; set;} [AliasAs ("t")] public string Type {get Set;} public object IgnoreMe {private get; set;}} var measurement = new Measurement {WebPropertyId = "UA-1234-5", ClientId = new Guid ("d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c"), Type = "event"}; / / Serialized as: v=1&tid=UA-1234-5&cid=d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c&t=eventawait api.Collect (measurement); 7. Set request header 7.1 static header (Static headers)

You can set one or more static request headers for requests that apply the headers attribute to a method:

[Headers ("User-Agent: Awesome Octocat App")] [Get ("/ users/ {user}")] Task GetUser (string user)

By applying the headers attribute to the interface, you can also add static headers to each request in the API:

[Headers ("User-Agent: Awesome Octocat App")] public interface IGitHubApi {[Get ("/ users/ {user}")] Task GetUser (string user); [Post ("/ users/new")] Task CreateUser ([Body] User user);} 7.2 dynamic header (Dynamic headers)

If you need to set the contents of the header at run time, you can add a header with a dynamic value to the request by applying the header attribute to the parameter:

[Get ("/ users/ {user}")] Task GetUser (string user, [Header ("Authorization")] string authorization); / / Will add the header "Authorization: token OAUTH-TOKEN" to the requestvar user = await GetUser ("octocat", "token OAUTH-TOKEN"); 7.3Authorization (dynamic header redux)

The most common reason for using headers is for authorization. Most API now use oAuth-style access tokens that expire and refresh longer-lived tokens. One way to encapsulate these types of tokens is to insert a custom HttpClientHandler. There are two classes to do this: one is AuthenticatedHttpClientHandler, which accepts a Func parameter in which you can generate a signature without knowing the request. The other is authenticatedparameteredhttpclienthandler, which accepts a Func parameter, where the signature requires information about the request (see the previous note on Twitter's API)

For example:

Class AuthenticatedHttpClientHandler: HttpClientHandler {private readonly Func getToken; public AuthenticatedHttpClientHandler (Func getToken) {if (getToken = = null) throw new ArgumentNullException (nameof (getToken)); this.getToken = getToken;} protected override async Task SendAsync (HttpRequestMessage request, CancellationToken cancellationToken) {/ / See if the request has an authorize header var auth = request.Headers.Authorization If (auth! = null) {var token = await getToken () .ConfigureAwait (false); request.Headers.Authorization = new AuthenticationHeaderValue (auth.Scheme, token);} return await base.SendAsync (request, cancellationToken) .ConfigureAwait (false);}}

Or:

Class AuthenticatedParameterizedHttpClientHandler: DelegatingHandler {readonly Func getToken; public AuthenticatedParameterizedHttpClientHandler (Func getToken, HttpMessageHandler innerHandler = null): base (innerHandler?? New HttpClientHandler () {this.getToken = getToken? Throw new ArgumentNullException (nameof (getToken));} protected override async Task SendAsync (HttpRequestMessage request, CancellationToken cancellationToken) {/ / See if the request has an authorize header var auth = request.Headers.Authorization; if (auth! = null) {var token = await getToken (request) .ConfigureAwait (false); request.Headers.Authorization = new AuthenticationHeaderValue (auth.Scheme, token) } return await base.SendAsync (request, cancellationToken) .ConfigureAwait (false);}}

Although HttpClient contains almost the same method signature, it is used differently. Reinstall did not call HttpClient.SendAsync. The HttpClientHandler must be modified instead. The use of this class is similar (the example uses the ADAL library to manage automatic token refresh, but the principal is used for Xamarin.Auth or any other library:

Class LoginViewModel {AuthenticationContext context = new AuthenticationContext (...); private async Task GetToken () {/ / The AcquireTokenAsync call will prompt with a UI if necessary / / Or otherwise silently use a refresh token to return / / a valid access token var token = await context.AcquireTokenAsync ("http://my.service.uri/app"," clientId ", new Uri (" callback://complete ")); return token } public async Task LoginAndCallApi () {var api = RestService.For (new HttpClient (new AuthenticatedHttpClientHandler (GetToken)) {BaseAddress = new Uri ("https://the.end.point/")}); var location = await api.GetLocationOfRebelBase ();}} interface IMyRestService {[Get (" / getPublicInfo ")] Task SomePublicMethod (); [Get (" / secretStuff ")] [Headers (" Authorization: Bearer ")] Task GetLocationOfRebelBase ();}

In the above example, whenever a method that requires authentication is called, AuthenticatedHttpClientHandler attempts to obtain a new access token. Provided by the application, check the expiration time of existing access tokens and obtain new access tokens as needed.

This is the end of the introduction on "how to use the REST.NET standard library refit". Thank you for reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report