Skip to content
Open
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// <auto-generated>
{{>partial_header}}

{{#nrt}}
#nullable enable

{{/nrt}}
using System;
using System.IO;

namespace {{packageName}}.{{clientPackage}}
{
Expand All @@ -28,20 +28,27 @@ namespace {{packageName}}.{{clientPackage}}
/// The raw data returned by the api
/// </summary>
public string RawContent { get; }

/// <summary>
/// The HttpResponseMessage object
/// </summary>
public System.Net.Http.HttpResponseMessage{{#nrt}}?{{/nrt}} RawResponse { get; }

/// <summary>
/// Construct the ApiException from parts of the response
/// </summary>
/// <param name="reasonPhrase"></param>
/// <param name="statusCode"></param>
/// <param name="rawContent"></param>
public ApiException(string{{nrt?}} reasonPhrase, System.Net.HttpStatusCode statusCode, string rawContent) : base(reasonPhrase ?? rawContent)
public ApiException(string{{nrt?}} reasonPhrase, System.Net.HttpStatusCode statusCode, string rawContent, System.Net.Http.HttpResponseMessage{{#nrt}}?{{/nrt}} rawResponse = null) : base(reasonPhrase ?? rawContent)
{
ReasonPhrase = reasonPhrase;

StatusCode = statusCode;

RawContent = rawContent;

RawResponse = rawResponse;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ namespace {{packageName}}.{{clientPackage}}
/// </summary>
System.Net.Http.Headers.HttpResponseHeaders Headers { get; }

/// <summary>
/// The headers contained in the api response related to the content
/// </summary>
System.Net.Http.Headers.HttpContentHeaders ContentHeaders { get; }

/// <summary>
/// The path used when making the request.
/// </summary>
Expand Down Expand Up @@ -106,6 +111,11 @@ namespace {{packageName}}.{{clientPackage}}
/// </summary>
public System.Net.Http.Headers.HttpResponseHeaders Headers { get; }

/// <summary>
/// The headers contained in the api response related to the content
/// </summary>
public System.Net.Http.Headers.HttpContentHeaders ContentHeaders { get; }

/// <summary>
/// The DateTime when the request was retrieved.
/// </summary>
Expand Down Expand Up @@ -144,6 +154,7 @@ namespace {{packageName}}.{{clientPackage}}
{
StatusCode = httpResponseMessage.StatusCode;
Headers = httpResponseMessage.Headers;
ContentHeaders = httpResponseMessage.Content.Headers;
IsSuccessStatusCode = httpResponseMessage.IsSuccessStatusCode;
ReasonPhrase = httpResponseMessage.ReasonPhrase;
RawContent = rawContent;
Expand All @@ -167,6 +178,7 @@ namespace {{packageName}}.{{clientPackage}}
{
StatusCode = httpResponseMessage.StatusCode;
Headers = httpResponseMessage.Headers;
ContentHeaders = httpResponseMessage.Content.Headers;
IsSuccessStatusCode = httpResponseMessage.IsSuccessStatusCode;
ReasonPhrase = httpResponseMessage.ReasonPhrase;
ContentStream = contentStream;
Expand All @@ -178,6 +190,7 @@ namespace {{packageName}}.{{clientPackage}}
OnCreated(httpRequestMessage, httpResponseMessage);
}


partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage);
}
{{#x-http-statuses-with-return}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ using {{packageName}}.{{modelPackage}};
{{/-first}}
{{/models}}
using System.Runtime.CompilerServices;
using System.Net.Http.Headers;

{{>Assembly}}namespace {{packageName}}.{{clientPackage}}
{
Expand Down Expand Up @@ -311,6 +312,31 @@ using System.Runtime.CompilerServices;
return string.Join(",", accepts);
}



/// <summary>
/// Select the Accept header's value from the given accepts array:
/// if JSON exists in the given array, use it;
/// otherwise use all of them.
/// </summary>
/// <param name="accepts">The accepts array to select from.</param>
/// <returns>The Accept header values to use.</returns>
public static IEnumerable<MediaTypeWithQualityHeaderValue> SelectHeaderAcceptArray(string[] accepts)
{
if (accepts.Length == 0)
return null;

if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase))
{{#net80OrLater}}
return [MediaTypeWithQualityHeaderValue.Parse("application/json")];
{{/net80OrLater}}
{{^net80OrLater}}
return new [] { MediaTypeWithQualityHeaderValue.Parse("application/json") };
{{/net80OrLater}}

return accepts.Select(MediaTypeWithQualityHeaderValue.Parse);
}

/// <summary>
/// Provides a case-insensitive check that a provided content type is a known JSON-like content type.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ namespace {{packageName}}.{{clientPackage}}
/// </summary>
public static string[] Formats { get; } = {
{{>DateFormats}}

};

/// <summary>
Expand All @@ -34,7 +33,7 @@ namespace {{packageName}}.{{clientPackage}}
string value = reader.GetString(){{nrt!}};

foreach(string format in Formats)
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out DateOnly result))
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly result))
return result;

throw new NotSupportedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ namespace {{packageName}}.{{clientPackage}}
/// </summary>
public static string[] Formats { get; } = {
{{>DateFormats}}

};

/// <summary>
Expand All @@ -34,7 +33,7 @@ namespace {{packageName}}.{{clientPackage}}
string value = reader.GetString(){{nrt!}};

foreach(string format in Formats)
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out DateOnly result))
if (DateOnly.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly result))
return result;

throw new NotSupportedException();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// <auto-generated>
{{>partial_header}}

{{#nrt}}
#nullable enable

Expand All @@ -17,21 +16,21 @@ namespace {{packageName}}.{{clientPackage}}
/// <typeparam name="TTokenBase"></typeparam>
{{>visibility}} class RateLimitProvider<TTokenBase> : TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
internal Dictionary<string, global::System.Threading.Channels.Channel<TTokenBase>> AvailableTokens { get; } = new{{^net70OrLater}} Dictionary<string, global::System.Threading.Channels.Channel<TTokenBase>>{{/net70OrLater}}();
public Dictionary<string, global::System.Threading.Channels.Channel<TTokenBase>> AvailableTokens { get; } = new{{^net70OrLater}} Dictionary<string, global::System.Threading.Channels.Channel<TTokenBase>>{{/net70OrLater}}();

/// <summary>
/// Instantiates a ThrottledTokenProvider. Your tokens will be rate limited based on the token's timeout.
/// </summary>
/// <param name="container"></param>
public RateLimitProvider(TokenContainer<TTokenBase> container) : base(container.Tokens)
public RateLimitProvider(TokenContainer<TTokenBase> container) : base()
{
foreach(TTokenBase token in _tokens)
foreach(TTokenBase token in container.Tokens)
token.StartTimer(token.Timeout ?? TimeSpan.FromMilliseconds(40));

{{#lambda.copy}}
global::System.Threading.Channels.BoundedChannelOptions options = new global::System.Threading.Channels.BoundedChannelOptions(_tokens.Length)
global::System.Threading.Channels.BoundedChannelOptions options = new global::System.Threading.Channels.BoundedChannelOptions(container.Tokens.Count)
{
FullMode = global::System.Threading.Channels.BoundedChannelFullMode.DropWrite
FullMode = global::System.Threading.Channels.BoundedChannelFullMode.DropOldest
};

AvailableTokens.Add(string.Empty, global::System.Threading.Channels.Channel.CreateBounded<TTokenBase>(options));
Expand All @@ -45,7 +44,7 @@ namespace {{packageName}}.{{clientPackage}}
{
global::System.Threading.Channels.BoundedChannelOptions options = new global::System.Threading.Channels.BoundedChannelOptions(apiKeyTokenContainer.Tokens.Count(t => ClientUtils.ApiKeyHeaderToString(t.Header).Equals(header)))
{
FullMode = global::System.Threading.Channels.BoundedChannelFullMode.DropWrite
FullMode = global::System.Threading.Channels.BoundedChannelFullMode.DropOldest
};

AvailableTokens.Add(header, global::System.Threading.Channels.Channel.CreateBounded<TTokenBase>(options));
Expand All @@ -65,7 +64,7 @@ namespace {{packageName}}.{{clientPackage}}
{{/hasApiKeyMethods}}

foreach (var availableToken in AvailableTokens)
foreach(TTokenBase token in _tokens)
foreach(TTokenBase token in container.Tokens)
{
{{#hasApiKeyMethods}}
if (token is ApiKeyToken apiKeyToken)
Expand All @@ -85,7 +84,7 @@ namespace {{packageName}}.{{clientPackage}}
}
}

internal override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(global::System.Threading.CancellationToken){{/netstandard20OrLater}})
public override async System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(global::System.Threading.CancellationToken){{/netstandard20OrLater}})
{
if (!AvailableTokens.TryGetValue(header, out global::System.Threading.Channels.Channel<TTokenBase>{{nrt?}} tokens))
throw new KeyNotFoundException($"Could not locate a token for header '{header}'.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ namespace {{packageName}}.{{clientPackage}}


internal TimeSpan? Timeout { get; set; }
internal delegate void TokenBecameAvailableEventHandler(object sender);
internal event TokenBecameAvailableEventHandler{{nrt?}} TokenBecameAvailable;
public delegate void TokenBecameAvailableEventHandler(object sender);
public event TokenBecameAvailableEventHandler{{nrt?}} TokenBecameAvailable;


/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// <auto-generated>
{{>partial_header}}

{{#nrt}}
#nullable enable

Expand All @@ -17,23 +16,6 @@ namespace {{packageName}}
/// </summary>
{{>visibility}} abstract class TokenProvider<TTokenBase> where TTokenBase : TokenBase
{
/// <summary>
/// The array of tokens.
/// </summary>
protected TTokenBase[] _tokens;

internal abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(global::System.Threading.CancellationToken){{/netstandard20OrLater}});

/// <summary>
/// Instantiates a TokenProvider.
/// </summary>
/// <param name="tokens"></param>
public TokenProvider(IEnumerable<TTokenBase> tokens)
{
_tokens = tokens.ToArray();

if (_tokens.Length == 0)
throw new ArgumentException("You did not provide any tokens.");
}
public abstract System.Threading.Tasks.ValueTask<TTokenBase> GetAsync(string header = "", System.Threading.CancellationToken cancellation = default{{^netstandard20OrLater}}(global::System.Threading.CancellationToken){{/netstandard20OrLater}});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{{/nrt}}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
{{#net80OrLater}}
{{#lambda.uniqueLines}}
{{#operations}}
Expand All @@ -20,6 +21,7 @@ using System.Linq;
{{/lambda.uniqueLines}}
{{/net80OrLater}}
using System.Net;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using System.Net.Http;
Expand Down Expand Up @@ -605,10 +607,10 @@ namespace {{packageName}}.{{apiPackage}}
{{#produces}}
{{#-first}}

string{{nrt?}} acceptLocalVar = ClientUtils.SelectHeaderAccept(acceptLocalVars);
IEnumerable<MediaTypeWithQualityHeaderValue> acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars);

if (acceptLocalVar != null)
httpRequestMessageLocalVar.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(acceptLocalVar));
foreach (var acceptLocalVar in acceptHeaderValuesLocalVar)
httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar);
{{/-first}}
{{/produces}}
{{#net60OrLater}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,68 @@
<PackageReference Include="RestSharp" Version="112.0.0" />
{{/useRestSharp}}
{{#useGenericHost}}
<PackageReference Include="Microsoft.Extensions.Http" Version="{{#lambda.first}}{{#netStandard}}5.0.0 {{/netStandard}}{{#net47}}7.0.0 {{/net47}}{{#net48}}7.0.0 {{/net48}}{{#net6.0}}6.0.0 {{/net6.0}}{{#net7.0}}7.0.0 {{/net7.0}}{{#net8.0}}8.0.0 {{/net8.0}}{{#net9.0}}9.0.5 {{/net9.0}}{{/lambda.first}}" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="{{#lambda.first}}{{#netStandard}}5.0.0 {{/netStandard}}{{#net47}}7.0.0 {{/net47}}{{#net48}}7.0.0 {{/net48}}{{#net6.0}}6.0.1 {{/net6.0}}{{#net7.0}}7.0.1 {{/net7.0}}{{#net8.0}}8.0.0 {{/net8.0}}{{#net9.0}}9.0.5 {{/net9.0}}{{/lambda.first}}" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
{{#netStandard}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard1.4' or '$(TargetFramework)' == 'netstandard1.5' or '$(TargetFramework)' == 'netstandard1.6' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard1.4' or '$(TargetFramework)' == 'netstandard1.5' or '$(TargetFramework)' == 'netstandard1.6' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'" Version="6.0.1" />
{{/netStandard}}
{{#net47}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'net47' or '$(TargetFramework)' == 'net471' or '$(TargetFramework)' == 'net472'" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'net47' or '$(TargetFramework)' == 'net471' or '$(TargetFramework)' == 'net472'" Version="6.0.1" />
{{/net47}}
{{#net48}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'net48' or '$(TargetFramework)' == 'net481'" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'net48' or '$(TargetFramework)' == 'net481'" Version="6.0.1" />
{{/net48}}

{{#net6.0}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'net6.0'" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'net6.0'" Version="6.0.1" />
{{/net6.0}}
{{#net7.0}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'net7.0'" Version=7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'net7.0'" Version="7.0.1" />
{{/net7.0}}
{{#net8.0}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'net8.0'" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'net8.0'" Version="8.0.1" />
{{/net8.0}}
{{#net9.0}}
<PackageReference Include="Microsoft.Extensions.Http" Condition="'$(TargetFramework)' == 'net9.0'" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.Hosting" Condition="'$(TargetFramework)' == 'net9.0'" Version="9.0.6" />
{{/net9.0}}
{{#supportsRetry}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="{{#lambda.first}}{{#netStandard}}5.0.1 {{/netStandard}}{{#net47}}7.0.0 {{/net47}}{{#net48}}7.0.0 {{/net48}}{{#net6.0}}6.0.19 {{/net6.0}}{{#net7.0}}7.0.11 {{/net7.0}}{{#net8.0}}8.0.8 {{/net8.0}}{{#net9.0}}9.0.5 {{/net9.0}}{{/lambda.first}}" />
{{#netStandard}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard1.4' or '$(TargetFramework)' == 'netstandard1.5' or '$(TargetFramework)' == 'netstandard1.6' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'" Version="6.0.36" />
{{/netStandard}}
{{#net47}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'net47' or '$(TargetFramework)' == 'net471' or '$(TargetFramework)' == 'net472'" Version="6.0.36" />
{{/net47}}
{{#net48}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'net48' or '$(TargetFramework)' == 'net481'" Version="6.0.36" />
{{/net48}}
{{#net6.0}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'net6.0'" Version="6.0.36" />
{{/net6.0}}
{{#net7.0}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'net7.0'" Version="7.0.20" />
{{/net7.0}}
{{#net8.0}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'net8.0'" Version="8.0.20" />
{{/net8.0}}
{{#net9.0}}
<PackageReference Include="Microsoft.Extensions.Http.Polly" Condition="'$(TargetFramework)' == 'net9.0'" Version="9.0.6" />
{{/net9.0}}
{{/supportsRetry}}
{{#net80OrLater}}
<PackageReference Include="Microsoft.Net.Http.Headers" Version="{{#lambda.first}}{{#net8.0}}8.0.8 {{/net8.0}}{{#net9.0}}9.0.5 {{/net9.0}}{{/lambda.first}}" />
{{#net8.0}}
<PackageReference Include="Microsoft.Net.Http.Headers" Condition="'$(TargetFramework)' == 'net8.0'" Version="8.0.17" />
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Condition="'$(TargetFramework)' == 'net8.0'" Version="8.0.17" />
{{/net8.0}}
{{#net9.0}}
<PackageReference Include="Microsoft.Net.Http.Headers" Condition="'$(TargetFramework)' == 'net9.0'" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Condition="'$(TargetFramework)' == 'net9.0'" Version="9.0.6" />
{{/net9.0}}
{{/net80OrLater}}
{{^net60OrLater}}
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
Expand Down
Loading
Loading