当前位置: 首页 > news >正文

西安市做网站cms网站建站流程

西安市做网站,cms网站建站流程,wordpress 十大插件,建设网站项目总结本文大部分内容是针对Refit官网的翻译。官网地址#xff1a; https://github.com/reactiveui/refitRefit是一个类似于Retrofit的Restful Api库#xff0c;使用它#xff0c;你可以将你的Restful Api定义在接口中。例如#xff1a;public interface IGitHubApi { [Get( https://github.com/reactiveui/refitRefit是一个类似于Retrofit的Restful Api库使用它你可以将你的Restful Api定义在接口中。例如public interface IGitHubApi { [Get(/users/{user})] TaskUser GetUser(string user); }这里RestService类生成了一个IGitHubApi接口的实现它使用HttpClient来进行api调用。var gitHubApi RestService.ForIGitHubApi(https://api.github.com); var octocat await gitHubApi.GetUser(octocat);Refit可以在哪些地方使用当前Refit支持一下平台。•UWP•Xamarin.Android•Xamarin.Mac•Xamarin.iOS•Desktop .NET 4.6.1•.NET Core.NET Core的注意事项对于.NET Core的构建时支持(Build-Time support), 你必须使用.NET Core 2.x SDK。你可以针对所有的支持平台构建你的库只要构建时使用2.x SDK即可。API属性基本用法针对每个方法都必须提供一个HTTP属性这个属性指定了请求的方式和相关的URL。这里有6种内置的批注Get, Post, Put, Delete, Patch和Head。在批注中需要指定资源对应的URL。[Get(/users/list)]你同样可以指定URL中的查询字符串。[Get(/users/list?sortdesc)]动态URL你还可以使用可替换块replacement block和方法参数创建动态URL。这里可替换块是一个被大括号包裹的字符串变量。[Get(/group/{id}/users)] TaskListUser GroupList([AliasAs(id)] int groupId);URL中没有指定的参数就会自动作为URL的查询字符串。这与Retrofit不同在Retrofit中所有参数都必须显示指定。[Get(/group/{id}/users)] TaskListUser GroupList([AliasAs(id)] int groupId, [AliasAs(sort)] string sortOrder);这里当调用GroupList(4, desc);方法时调用API会是/group/4/users?sortdesc。回转路由语法回转路由参数语法使用双星号的捕获所有参数(catch-all parameter)且不会对/进行编码在生成链接的过程, 路由系统将编码双星号捕获的全部参数(catch-all parameter)而不会编码/。[Get(/search/{**page})] TaskListPage Search(string page);回转路由参数必须是字符串这里当调用Search(admin/products);时生成的连接是/search/admin/products动态查询字符串参数当你指定一个对象作为查询参数的时候所有非空的public属性将被用作查询参数。使用Query特性将改变默认的行为它会扁平化你的查询字符串对象。如果使用Query特性你还可以针对扁平化查询字符串对象添加指定的分隔符和前缀。例public class MyQueryParams { [AliasAs(order)] public string SortOrder { get; set; } public int Limit { get; set; } }普通的扁平化查询字符串对象[Get(/group/{id}/users)] TaskListUser GroupList([AliasAs(id)] int groupId, MyQueryParams params);扁平化查询字符串对象并附加分隔符和前缀[Get(/group/{id}/users)] TaskListUser GroupListWithAttribute([AliasAs(id)] int groupId, [Query(.,search)] MyQueryParams params);代码调用及结果。params.SortOrder desc; params.Limit 10; GroupList(4, params) //结果 /group/4/users?orderdescLimit10 GroupListWithAttribute(4, params) //结果 /group/4/users?search.orderdescsearch.Limit10集合作为查询字符串参数Query特性同样可以指定查询字符串中应该如何格式化集合对象。例[Get(/users/list)] Task Search([Query(CollectionFormat.Multi)]int[] ages); Search(new [] {10, 20, 30}) //结果 /users/list?ages10ages20ages30 [Get(/users/list)] Task Search([Query(CollectionFormat.Csv)]int[] ages); Search(new [] {10, 20, 30}) //结果 /users/list?ages10%2C20%2C30正文内容在你的方法签名中你还可以将使用Body特性将参数中的一个标记为正文内容。[Post(/users/new)] Task CreateUser([Body] User user);这里Refit支持4种请求体数据•如果正文内容类型是Stream, 其内容会包裹在一个StreamContent对象中。•如果正文内容类型是string, 其内容会直接用作正文内容。当指定当前参数拥有特性[Body(BodySerializationMethod.Json)]时它会被包裹在一个StringContent对象中。•如果当前参数拥有特性[Body(BodySerializationMethod.UrlEncoded)], 其内容会被URL编码。•针对其他类型当前指定的参数会被默认序列化成JSON。缓冲及Content-Header头部设置默认情况下Refit会流式传输正文内容而不会缓冲它。这意味着你可以从磁盘流式传输文件而不产生将整个文件加载到内存中的开销。这样做的缺点是请求头部没有设置Content-Length。如果你的API需要发送一个请求并指定Content-Length请求头则需要将Body特性的buffered参数设置为true。Task CreateUser([Body(buffered: true)] User user);Json内容JSON请求和响应可以使用Json.NET来序列化和反序列化默认情况下Refit会使用Newtonsoft.Json.JsonConvert.DefaultSettings的默认序列化配置。JsonConvert.DefaultSettings () new JsonSerializerSettings() { ContractResolver new CamelCasePropertyNamesContractResolver(), Converters {new StringEnumConverter()} }; // Serialized as: {day:Saturday} await PostSomeStuff(new { Day DayOfWeek.Saturday });因为默认设置是全局设置它会影响你的整个应用。所以这里我们最好使用针对特定API使用独立的配置。当使用Refit生成一个接口对象的时候你可以传入一个RefitSettings参数这个参数可以指定你使用的JSON序列化配置。var gitHubApi RestService.ForIGitHubApi(https://api.github.com, new RefitSettings { ContentSerializer new JsonContentSerializer( new JsonSerializerSettings { ContractResolver new SnakeCasePropertyNamesContractResolver() } )}); var otherApi RestService.ForIOtherApi(https://api.example.com, new RefitSettings { ContentSerializer new JsonContentSerializer( new JsonSerializerSettings { ContractResolver new CamelCasePropertyNamesContractResolver() } )});针对自定义属性的序列化和反序列化我们同样可以使用Json.NET的JsonProperty属性。public class Foo { // Works like [AliasAs(b)] would in form posts (see below) [JsonProperty(PropertyNameb)] public string Bar { get; set; } } Xml内容针对XML请求和响应的序列化和反序列化Refit使用了System.Xml.Serialization.XmlSerializer。默认情况下 Refit会使用JSON内容序列化器如果想要使用XML内容序列化器你需要将RefitSetting的ContentSerializer属性指定为XmlContentSerializer。var gitHubApi RestService.ForIXmlApi(https://www.w3.org/XML, new RefitSettings { ContentSerializer new XmlContentSerializer() });我们同样可以使用System.Xml.Serialization命名空间下的特性自定义属性的序列化和反序列化。public class Foo { [XmlElement(Namespace https://www.w3.org/XML)] public string Bar { get; set; } }System.Xml.Serialization.XmlSerializer提供了多种序列化方式你可以通过在XmlContentSerialier对象的构造函数中指定一个XmlContentSerializerSettings 对象类进行配置。var gitHubApi RestService.ForIXmlApi(https://www.w3.org/XML, new RefitSettings { ContentSerializer new XmlContentSerializer( new XmlContentSerializerSettings { XmlReaderWriterSettings new XmlReaderWriterSettings() { ReaderSettings new XmlReaderSettings { IgnoreWhitespace true } } } ) });表单Post针对采用表单Post的API( 正文会被序列化成application/x-www-form-urlencoded ), 我们可以将指定参数的正文特性指定为BodySerializationMethod.UrlEncoded。这个参数可以是字典IDictionary接口对象。public interface IMeasurementProtocolApi { [Post(/collect)] Task Collect([Body(BodySerializationMethod.UrlEncoded)] Dictionarystring, object data); } var data new Dictionarystring, object { {v, 1}, {tid, UA-1234-5}, {cid, new Guid(d1e9ea6b-2e8b-4699-93e0-0bcbd26c206c)}, {t, event}, }; // 序列化为: v1tidUA-1234-5cidd1e9ea6b-2e8b-4699-93e0-0bcbd26c206ctevent await api.Collect(data);当然参数也可以是一个普通对象Refit会将对象中所有public, 可读取的属性序列化成表单字段。当然这里你可以使用AliasAs特性为序列化的表单字段起别名。public interface IMeasurementProtocolApi { [Post(/collect)] Task Collect([Body(BodySerializationMethod.UrlEncoded)] Measurement measurement); } public class Measurement { // Properties can be read-only and [AliasAs] isnt 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 }; // 序列化为: v1tidUA-1234-5cidd1e9ea6b-2e8b-4699-93e0-0bcbd26c206ctevent await api.Collect(measurement);如果当前属性同时指定了[JsonProperty(PropertyName)] 和AliasAs(), Refit会优先使用AliasAs() 中指定的名称。这意味着以下类型会被序列化成onevalue1twovalue2public class SomeObject { [JsonProperty(PropertyName one)] public string FirstProperty { get; set; } [JsonProperty(PropertyName notTwo)] [AliasAs(two)] public string SecondProperty { get; set; } }注意 AliasAs只能应用在请求参数和Form正文Post中不能应用于响应对象。如果要为响应对象属性起别名你依然需要使用[JsonProperty(full-property-name)]设置请求Header静态头你可以使用Headers特性指定一个或多个静态的请求头。[Headers(User-Agent: Awesome Octocat App)] [Get(/users/{user})] TaskUser GetUser(string user);为了简便使用你也可以将Headers特性放在接口定义上从而使当前接口中定义的所有Rest请求都添加相同的静态头。[Headers(User-Agent: Awesome Octocat App)] public interface IGitHubApi { [Get(/users/{user})] TaskUser GetUser(string user); [Post(/users/new)] Task CreateUser([Body] User user); }动态头如果头部内容需要在运行时动态设置你可以在方法签名处使用Header特性指定一个动态头部参数你可以在调用Api时为这个参数指定一个dynamic类型的值从而实现动态头。[Get(/users/{user})] TaskUser GetUser(string user, [Header(Authorization)] string authorization); // Will add the header Authorization: token OAUTH-TOKEN to the request var user await GetUser(octocat, token OAUTH-TOKEN); 授权(动态头的升级版)使用请求头的最常见场景就是授权。当今绝大多数的API都是使用OAuth, 它会提供一个带过期时间的access token和一个负责刷新access token的refresh token。为了封装这些授权令牌的使用我们可以自定义一个HttpClientHandler。class AuthenticatedHttpClientHandler : HttpClientHandler { private readonly FuncTaskstring getToken; public AuthenticatedHttpClientHandler(FuncTaskstring getToken) { if (getToken null) throw new ArgumentNullException(nameof(getToken)); this.getToken getToken; } protected override async TaskHttpResponseMessage 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); } }虽然HttpClient包含了几乎相同的方法签名但是它的使用方式不同。Refit不会调用HttpClient.SendAsync方法这里必须使用自定义的HttpClientHandler替换它。class LoginViewModel { AuthenticationContext context new AuthenticationContext(...); private async Taskstring 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.ForIMyRestService(new HttpClient(new AuthenticatedHttpClientHandler(GetToken)) { BaseAddress new Uri(https://the.end.point/) }); var location await api.GetLocationOfRebelBase(); } } interface IMyRestService { [Get(/getPublicInfo)] TaskFoobar SomePublicMethod(); [Get(/secretStuff)] [Headers(Authorization: Bearer)] TaskLocation GetLocationOfRebelBase(); }在以上代码中当任何需要身份验证的的方法被调用的时候AuthenticatedHttpClientHandler会尝试获取一个新的access token。 这里程序会检查access token是否到期并在需要时获取新的令牌。分段上传当一个接口方法被指定为[Multipart], 这意味着当前Api提交的内容中包含分段内容类型。针对分段方法Refit当前支持一下几种参数类型•字符串•二进制数组•Stream流•FileInfo这里参数名会作为分段数据的字段名。当然你可以用AliasAs特性复写它。为了给二进制数组Stream流以及FileInfo参数的内容指定文件名和内容类型我们必须要使用封装类。Refit中默认的封装类有3种ByteArrarPart, StreamPart, FileInfoPart。public interface ISomeApi { [Multipart] [Post(/users/{id}/photo)] Task UploadPhoto(int id, [AliasAs(myPhoto)] StreamPart stream); }为了将一个Stream流对象传递给以上定义的方法我们需要构建一个StreamObject对象someApiInstance.UploadPhoto(id, new StreamPart(myPhotoStream, photo.jpg, image/jpeg));异常处理为了封装可能来自服务的任何异常你可以捕获包含请求和响应信息的ApiException。 Refit还支持捕获由于不良请求而引发的验证异常以解决问题详细信息。 有关验证异常的问题详细信息的特定信息只需捕获ValidationApiException// ... try { var result await awesomeApi.GetFooAsync(bar); } catch (ValidationApiException validationException) { // handle validation here by using validationException.Content, // which is type of ProblemDetails according to RFC 7807 } catch (ApiException exception) { // other exception handling } // ...
http://www.zqtcl.cn/news/404665/

相关文章:

  • 政务网站建设发言材料知名互联网公司有哪些
  • 网站搭建制作建e室内设计网画图
  • 重庆市建设工程施工安全管理信息网北京seo公司网站
  • 国外做调查问卷的网站建设邮费自己的网站 要不要购买服务器的
  • 网站建设和优化排名四川建设网官网证书查询入口
  • 如何搜名字搜到自己做的网站电子商务平台icp备案证明
  • 网站建设与管理工作内容北京网站建设价
  • 做网站选哪个语言软文营销的方法
  • 青岛正规公司网站建设公司中国建设银行注册网站
  • 免费个人网站平台关键词检索
  • 定制型网站建设推广宁河网站建设
  • 主流网站开发语言有哪些电子邮件营销
  • 扫描二维码进入公司网站怎样做在万网上域名了怎么做网站
  • 销售型网站设计怎么做网站广告位
  • 网站推广的方法ppt购物网站logo
  • 网站关键词分割wordpress为展示的作品投票
  • 建立网站 域名 服务器吗wordpress超链接出错
  • 外贸开发网站建设注册会计师协会
  • 莆田建设网站dw网页设计作品及源码
  • 360免费建站视频淘宝客的网站怎么做
  • 四川自助seo建站短视频推广计划
  • 网站建设案例的公司黄冈网站建设公司
  • 做淘客网站需要营业执照吗制作网站公
  • 手机网站开发的目的鲁班设计远程工作
  • 宿迁网站建设要多少钱高密市住房和城乡建设局网站
  • 咸阳网站建设公司哪家好wordpress访客ip记录
  • 厦门建设银行网站那个网站做效果图电脑配置
  • 人才网站建设医院网站建设的好处
  • 房屋装修网站模板html5做网站
  • 网站建设需要的硬件网站建设知名公司排名