Enabled nullable for most projects

This commit is contained in:
Jonas Dellinger 2020-05-25 18:00:38 +02:00
parent 020b60bec2
commit f1ca557c6e
157 changed files with 598 additions and 439 deletions

View File

@ -14,7 +14,7 @@ namespace SpotifyAPI.Web.Auth
System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { } System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
public string Error { get; set; } public string? Error { get; set; }
public string State { get; set; } public string? State { get; set; }
} }
} }

View File

@ -12,13 +12,13 @@ namespace SpotifyAPI.Web.Auth
{ {
public class EmbedIOAuthServer : IAuthServer public class EmbedIOAuthServer : IAuthServer
{ {
public event Func<object, AuthorizationCodeResponse, Task> AuthorizationCodeReceived; public event Func<object, AuthorizationCodeResponse, Task>? AuthorizationCodeReceived;
public event Func<object, ImplictGrantResponse, Task> ImplictGrantReceived; public event Func<object, ImplictGrantResponse, Task>? ImplictGrantReceived;
private const string AssetsResourcePath = "SpotifyAPI.Web.Auth.Resources.auth_assets"; private const string AssetsResourcePath = "SpotifyAPI.Web.Auth.Resources.auth_assets";
private const string DefaultResourcePath = "SpotifyAPI.Web.Auth.Resources.default_site"; private const string DefaultResourcePath = "SpotifyAPI.Web.Auth.Resources.default_site";
private CancellationTokenSource _cancelTokenSource; private CancellationTokenSource? _cancelTokenSource;
private readonly WebServer _webServer; private readonly WebServer _webServer;
public EmbedIOAuthServer(Uri baseUri, int port) public EmbedIOAuthServer(Uri baseUri, int port)
@ -76,7 +76,7 @@ namespace SpotifyAPI.Web.Auth
public Task Stop() public Task Stop()
{ {
_cancelTokenSource.Cancel(); _cancelTokenSource?.Cancel();
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -9,7 +9,7 @@ namespace SpotifyAPI.Web.Auth
Code = code; Code = code;
} }
public string Code { get; set; } public string Code { get; set; } = default!;
public string State { get; set; } public string State { get; set; } = default!;
} }
} }

View File

@ -14,10 +14,10 @@ namespace SpotifyAPI.Web.Auth
ExpiresIn = expiresIn; ExpiresIn = expiresIn;
} }
public string AccessToken { get; set; } public string AccessToken { get; set; } = default!;
public string TokenType { get; set; } public string TokenType { get; set; } = default!;
public int ExpiresIn { get; set; } public int ExpiresIn { get; set; }
public string State { get; set; } public string State { get; set; } = default!;
/// <summary> /// <summary>
/// Auto-Initalized to UTC Now /// Auto-Initalized to UTC Now

View File

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks> <TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<PackageId>SpotifyAPI.Web.Auth</PackageId> <PackageId>SpotifyAPI.Web.Auth</PackageId>
<Title>SpotifyAPI.Web.Auth</Title> <Title>SpotifyAPI.Web.Auth</Title>
<Authors>Jonas Dellinger</Authors> <Authors>Jonas Dellinger</Authors>

View File

@ -3,6 +3,8 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,4 +1,3 @@
using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using System; using System;
@ -18,12 +17,19 @@ namespace Example.CLI.PersistentConfig
public class Program public class Program
{ {
private const string CredentialsPath = "credentials.json"; private const string CredentialsPath = "credentials.json";
private static readonly string clientId = Environment.GetEnvironmentVariable("SPOTIFY_CLIENT_ID"); private static readonly string? clientId = Environment.GetEnvironmentVariable("SPOTIFY_CLIENT_ID");
private static readonly string clientSecret = Environment.GetEnvironmentVariable("SPOTIFY_CLIENT_SECRET"); private static readonly string? clientSecret = Environment.GetEnvironmentVariable("SPOTIFY_CLIENT_SECRET");
private static EmbedIOAuthServer _server; private static readonly EmbedIOAuthServer _server = new EmbedIOAuthServer(new Uri("http://localhost:5000/callback"), 5000);
public static async Task<int> Main() public static async Task<int> Main()
{ {
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
{
throw new NullReferenceException(
"Please set SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET via environment variables before starting the program"
);
}
if (File.Exists(CredentialsPath)) if (File.Exists(CredentialsPath))
{ {
await Start(); await Start();
@ -42,7 +48,7 @@ namespace Example.CLI.PersistentConfig
var json = await File.ReadAllTextAsync(CredentialsPath); var json = await File.ReadAllTextAsync(CredentialsPath);
var token = JsonConvert.DeserializeObject<AuthorizationCodeTokenResponse>(json); var token = JsonConvert.DeserializeObject<AuthorizationCodeTokenResponse>(json);
var authenticator = new AuthorizationCodeAuthenticator(clientId, clientSecret, token); var authenticator = new AuthorizationCodeAuthenticator(clientId!, clientSecret!, token);
authenticator.TokenRefreshed += (sender, token) => File.WriteAllText(CredentialsPath, JsonConvert.SerializeObject(token)); authenticator.TokenRefreshed += (sender, token) => File.WriteAllText(CredentialsPath, JsonConvert.SerializeObject(token));
var config = SpotifyClientConfig.CreateDefault() var config = SpotifyClientConfig.CreateDefault()
@ -61,11 +67,10 @@ namespace Example.CLI.PersistentConfig
private static async Task StartAuthentication() private static async Task StartAuthentication()
{ {
_server = new EmbedIOAuthServer(new Uri("http://localhost:5000/callback"), 5000);
await _server.Start(); await _server.Start();
_server.AuthorizationCodeReceived += OnAuthorizationCodeReceived; _server.AuthorizationCodeReceived += OnAuthorizationCodeReceived;
var request = new LoginRequest(_server.BaseUri, clientId, LoginRequest.ResponseType.Code) var request = new LoginRequest(_server.BaseUri, clientId!, LoginRequest.ResponseType.Code)
{ {
Scope = new List<string> { UserReadEmail, UserReadPrivate, PlaylistReadPrivate } Scope = new List<string> { UserReadEmail, UserReadPrivate, PlaylistReadPrivate }
}; };
@ -85,7 +90,7 @@ namespace Example.CLI.PersistentConfig
{ {
await _server.Stop(); await _server.Stop();
AuthorizationCodeTokenResponse token = await new OAuthClient().RequestToken( AuthorizationCodeTokenResponse token = await new OAuthClient().RequestToken(
new AuthorizationCodeTokenRequest(clientId, clientSecret, response.Code, _server.BaseUri) new AuthorizationCodeTokenRequest(clientId!, clientSecret!, response.Code, _server.BaseUri)
); );
await File.WriteAllTextAsync(CredentialsPath, JsonConvert.SerializeObject(token)); await File.WriteAllTextAsync(CredentialsPath, JsonConvert.SerializeObject(token));

View File

@ -28,7 +28,7 @@ namespace SpotifyAPI.Web
await client.Get(userId); await client.Get(userId);
api.Verify(a => a.Get<PublicUser>(SpotifyUrls.User("userId")), Times.Once); api.Verify(a => a.Get<PublicUser>(SpotifyUrls.User(userId)), Times.Once);
} }
} }
} }

View File

@ -101,6 +101,7 @@ namespace SpotifyAPI.Web
private static APIConnector ValidateConfig(SpotifyClientConfig config) private static APIConnector ValidateConfig(SpotifyClientConfig config)
{ {
Ensure.ArgumentNotNull(config, nameof(config)); Ensure.ArgumentNotNull(config, nameof(config));
return new APIConnector( return new APIConnector(
config.BaseAddress, config.BaseAddress,
config.Authenticator, config.Authenticator,

View File

@ -7,11 +7,11 @@ namespace SpotifyAPI.Web
public class SpotifyClientConfig public class SpotifyClientConfig
{ {
public Uri BaseAddress { get; private set; } public Uri BaseAddress { get; private set; }
public IAuthenticator Authenticator { get; private set; } public IAuthenticator? Authenticator { get; private set; }
public IJSONSerializer JSONSerializer { get; private set; } public IJSONSerializer JSONSerializer { get; private set; }
public IHTTPClient HTTPClient { get; private set; } public IHTTPClient HTTPClient { get; private set; }
public IHTTPLogger HTTPLogger { get; private set; } public IHTTPLogger? HTTPLogger { get; private set; }
public IRetryHandler RetryHandler { get; private set; } public IRetryHandler? RetryHandler { get; private set; }
public IPaginator DefaultPaginator { get; private set; } public IPaginator DefaultPaginator { get; private set; }
/// <summary> /// <summary>
@ -26,11 +26,11 @@ namespace SpotifyAPI.Web
/// <param name="defaultPaginator"></param> /// <param name="defaultPaginator"></param>
public SpotifyClientConfig( public SpotifyClientConfig(
Uri baseAddress, Uri baseAddress,
IAuthenticator authenticator, IAuthenticator? authenticator,
IJSONSerializer jsonSerializer, IJSONSerializer jsonSerializer,
IHTTPClient httpClient, IHTTPClient httpClient,
IRetryHandler retryHandler, IRetryHandler? retryHandler,
IHTTPLogger httpLogger, IHTTPLogger? httpLogger,
IPaginator defaultPaginator IPaginator defaultPaginator
) )
{ {

View File

@ -7,9 +7,9 @@ using System.Runtime.Serialization;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
[Serializable] [Serializable]
public class APIException : System.Exception public class APIException : Exception
{ {
public IResponse Response { get; set; } public IResponse? Response { get; set; }
public APIException(IResponse response) : base(ParseAPIErrorMessage(response)) public APIException(IResponse response) : base(ParseAPIErrorMessage(response))
{ {
@ -26,7 +26,7 @@ namespace SpotifyAPI.Web
{ {
} }
public APIException(string message, System.Exception innerException) : base(message, innerException) public APIException(string message, Exception innerException) : base(message, innerException)
{ {
} }
@ -35,7 +35,7 @@ namespace SpotifyAPI.Web
Response = info.GetValue("APIException.Response", typeof(IResponse)) as IResponse; Response = info.GetValue("APIException.Response", typeof(IResponse)) as IResponse;
} }
private static string ParseAPIErrorMessage(IResponse response) private static string? ParseAPIErrorMessage(IResponse response)
{ {
var body = response.Body as string; var body = response.Body as string;
if (string.IsNullOrEmpty(body)) if (string.IsNullOrEmpty(body))
@ -44,7 +44,7 @@ namespace SpotifyAPI.Web
} }
try try
{ {
JObject bodyObject = JObject.Parse(body); JObject bodyObject = JObject.Parse(body!);
JObject error = bodyObject.Value<JObject>("error"); JObject error = bodyObject.Value<JObject>("error");
if (error != null) if (error != null)
{ {

View File

@ -9,22 +9,22 @@ namespace SpotifyAPI.Web.Http
public class APIConnector : IAPIConnector public class APIConnector : IAPIConnector
{ {
private readonly Uri _baseAddress; private readonly Uri _baseAddress;
private readonly IAuthenticator _authenticator; private readonly IAuthenticator? _authenticator;
private readonly IJSONSerializer _jsonSerializer; private readonly IJSONSerializer _jsonSerializer;
private readonly IHTTPClient _httpClient; private readonly IHTTPClient _httpClient;
private readonly IRetryHandler _retryHandler; private readonly IRetryHandler? _retryHandler;
private readonly IHTTPLogger _httpLogger; private readonly IHTTPLogger? _httpLogger;
public APIConnector(Uri baseAddress, IAuthenticator authenticator) : public APIConnector(Uri baseAddress, IAuthenticator authenticator) :
this(baseAddress, authenticator, new NewtonsoftJSONSerializer(), new NetHttpClient(), null, null) this(baseAddress, authenticator, new NewtonsoftJSONSerializer(), new NetHttpClient(), null, null)
{ } { }
public APIConnector( public APIConnector(
Uri baseAddress, Uri baseAddress,
IAuthenticator authenticator, IAuthenticator? authenticator,
IJSONSerializer jsonSerializer, IJSONSerializer jsonSerializer,
IHTTPClient httpClient, IHTTPClient httpClient,
IRetryHandler retryHandler, IRetryHandler? retryHandler,
IHTTPLogger httpLogger) IHTTPLogger? httpLogger)
{ {
_baseAddress = baseAddress; _baseAddress = baseAddress;
_authenticator = authenticator; _authenticator = authenticator;
@ -41,21 +41,21 @@ namespace SpotifyAPI.Web.Http
return SendAPIRequest<T>(uri, HttpMethod.Delete); return SendAPIRequest<T>(uri, HttpMethod.Delete);
} }
public Task<T> Delete<T>(Uri uri, IDictionary<string, string> parameters) public Task<T> Delete<T>(Uri uri, IDictionary<string, string>? parameters)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Delete, parameters); return SendAPIRequest<T>(uri, HttpMethod.Delete, parameters);
} }
public Task<T> Delete<T>(Uri uri, IDictionary<string, string> parameters, object body) public Task<T> Delete<T>(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Delete, parameters, body); return SendAPIRequest<T>(uri, HttpMethod.Delete, parameters, body);
} }
public async Task<HttpStatusCode> Delete(Uri uri, IDictionary<string, string> parameters, object body) public async Task<HttpStatusCode> Delete(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
@ -70,14 +70,14 @@ namespace SpotifyAPI.Web.Http
return SendAPIRequest<T>(uri, HttpMethod.Get); return SendAPIRequest<T>(uri, HttpMethod.Get);
} }
public Task<T> Get<T>(Uri uri, IDictionary<string, string> parameters) public Task<T> Get<T>(Uri uri, IDictionary<string, string>? parameters)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Get, parameters); return SendAPIRequest<T>(uri, HttpMethod.Get, parameters);
} }
public async Task<HttpStatusCode> Get(Uri uri, IDictionary<string, string> parameters, object body) public async Task<HttpStatusCode> Get(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
@ -92,28 +92,28 @@ namespace SpotifyAPI.Web.Http
return SendAPIRequest<T>(uri, HttpMethod.Post); return SendAPIRequest<T>(uri, HttpMethod.Post);
} }
public Task<T> Post<T>(Uri uri, IDictionary<string, string> parameters) public Task<T> Post<T>(Uri uri, IDictionary<string, string>? parameters)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Post, parameters); return SendAPIRequest<T>(uri, HttpMethod.Post, parameters);
} }
public Task<T> Post<T>(Uri uri, IDictionary<string, string> parameters, object body) public Task<T> Post<T>(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Post, parameters, body); return SendAPIRequest<T>(uri, HttpMethod.Post, parameters, body);
} }
public Task<T> Post<T>(Uri uri, IDictionary<string, string> parameters, object body, Dictionary<string, string> headers) public Task<T> Post<T>(Uri uri, IDictionary<string, string>? parameters, object? body, Dictionary<string, string>? headers)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Post, parameters, body, headers); return SendAPIRequest<T>(uri, HttpMethod.Post, parameters, body, headers);
} }
public async Task<HttpStatusCode> Post(Uri uri, IDictionary<string, string> parameters, object body) public async Task<HttpStatusCode> Post(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
@ -128,21 +128,21 @@ namespace SpotifyAPI.Web.Http
return SendAPIRequest<T>(uri, HttpMethod.Put); return SendAPIRequest<T>(uri, HttpMethod.Put);
} }
public Task<T> Put<T>(Uri uri, IDictionary<string, string> parameters) public Task<T> Put<T>(Uri uri, IDictionary<string, string>? parameters)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Put, parameters); return SendAPIRequest<T>(uri, HttpMethod.Put, parameters);
} }
public Task<T> Put<T>(Uri uri, IDictionary<string, string> parameters, object body) public Task<T> Put<T>(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
return SendAPIRequest<T>(uri, HttpMethod.Put, parameters, body); return SendAPIRequest<T>(uri, HttpMethod.Put, parameters, body);
} }
public async Task<HttpStatusCode> Put(Uri uri, IDictionary<string, string> parameters, object body) public async Task<HttpStatusCode> Put(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
@ -150,7 +150,7 @@ namespace SpotifyAPI.Web.Http
return response.StatusCode; return response.StatusCode;
} }
public async Task<HttpStatusCode> PutRaw(Uri uri, IDictionary<string, string> parameters, object body) public async Task<HttpStatusCode> PutRaw(Uri uri, IDictionary<string, string>? parameters, object? body)
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
@ -166,19 +166,21 @@ namespace SpotifyAPI.Web.Http
private IRequest CreateRequest( private IRequest CreateRequest(
Uri uri, Uri uri,
HttpMethod method, HttpMethod method,
IDictionary<string, string> parameters, IDictionary<string, string>? parameters,
object body, object? body,
IDictionary<string, string> headers IDictionary<string, string>? headers
) )
{ {
Ensure.ArgumentNotNull(uri, nameof(uri)); Ensure.ArgumentNotNull(uri, nameof(uri));
Ensure.ArgumentNotNull(method, nameof(method)); Ensure.ArgumentNotNull(method, nameof(method));
return new Request(headers ?? new Dictionary<string, string>(), parameters ?? new Dictionary<string, string>()) return new Request(
_baseAddress,
uri,
method,
headers ?? new Dictionary<string, string>(),
parameters ?? new Dictionary<string, string>())
{ {
BaseAddress = _baseAddress,
Endpoint = uri,
Method = method,
Body = body Body = body
}; };
} }
@ -222,16 +224,16 @@ namespace SpotifyAPI.Web.Http
|| request.Endpoint.AbsoluteUri.Contains("https://api.spotify.com", StringComparison.InvariantCulture)) || request.Endpoint.AbsoluteUri.Contains("https://api.spotify.com", StringComparison.InvariantCulture))
#endif #endif
{ {
await _authenticator.Apply(request, this).ConfigureAwait(false); await _authenticator!.Apply(request, this).ConfigureAwait(false);
} }
} }
public Task<IResponse> SendRawRequest( public Task<IResponse> SendRawRequest(
Uri uri, Uri uri,
HttpMethod method, HttpMethod method,
IDictionary<string, string> parameters = null, IDictionary<string, string>? parameters = null,
object body = null, object? body = null,
IDictionary<string, string> headers = null IDictionary<string, string>? headers = null
) )
{ {
var request = CreateRequest(uri, method, parameters, body, headers); var request = CreateRequest(uri, method, parameters, body, headers);
@ -241,9 +243,9 @@ namespace SpotifyAPI.Web.Http
public async Task<T> SendAPIRequest<T>( public async Task<T> SendAPIRequest<T>(
Uri uri, Uri uri,
HttpMethod method, HttpMethod method,
IDictionary<string, string> parameters = null, IDictionary<string, string>? parameters = null,
object body = null, object? body = null,
IDictionary<string, string> headers = null IDictionary<string, string>? headers = null
) )
{ {
var request = CreateRequest(uri, method, parameters, body, headers); var request = CreateRequest(uri, method, parameters, body, headers);
@ -254,9 +256,9 @@ namespace SpotifyAPI.Web.Http
public async Task<IResponse> SendAPIRequestDetailed( public async Task<IResponse> SendAPIRequestDetailed(
Uri uri, Uri uri,
HttpMethod method, HttpMethod method,
IDictionary<string, string> parameters = null, IDictionary<string, string>? parameters = null,
object body = null, object? body = null,
IDictionary<string, string> headers = null IDictionary<string, string>? headers = null
) )
{ {
var request = CreateRequest(uri, method, parameters, body, headers); var request = CreateRequest(uri, method, parameters, body, headers);

View File

@ -9,7 +9,7 @@ namespace SpotifyAPI.Web.Http
/// </summary> /// </summary>
public class AuthorizationCodeAuthenticator : IAuthenticator public class AuthorizationCodeAuthenticator : IAuthenticator
{ {
public event EventHandler<AuthorizationCodeTokenResponse> TokenRefreshed; public event EventHandler<AuthorizationCodeTokenResponse>? TokenRefreshed;
/// <summary> /// <summary>
/// Initiate a new instance. The token will be refreshed once it expires. /// Initiate a new instance. The token will be refreshed once it expires.

View File

@ -8,7 +8,7 @@ namespace SpotifyAPI.Web.Http
/// </summary> /// </summary>
public class CredentialsAuthenticator : IAuthenticator public class CredentialsAuthenticator : IAuthenticator
{ {
private CredentialsTokenResponse _token; private CredentialsTokenResponse? _token;
/// <summary> /// <summary>
/// Initiate a new instance. The first token will be fetched when the first API call occurs /// Initiate a new instance. The first token will be fetched when the first API call occurs

View File

@ -17,32 +17,32 @@ namespace SpotifyAPI.Web.Http
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<T> Get<T>(Uri uri); Task<T> Get<T>(Uri uri);
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<T> Get<T>(Uri uri, IDictionary<string, string> parameters); Task<T> Get<T>(Uri uri, IDictionary<string, string>? parameters);
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<HttpStatusCode> Get(Uri uri, IDictionary<string, string> parameters, object body); Task<HttpStatusCode> Get(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<T> Post<T>(Uri uri); Task<T> Post<T>(Uri uri);
Task<T> Post<T>(Uri uri, IDictionary<string, string> parameters); Task<T> Post<T>(Uri uri, IDictionary<string, string>? parameters);
Task<T> Post<T>(Uri uri, IDictionary<string, string> parameters, object body); Task<T> Post<T>(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<T> Post<T>(Uri uri, IDictionary<string, string> parameters, object body, Dictionary<string, string> headers); Task<T> Post<T>(Uri uri, IDictionary<string, string>? parameters, object? body, Dictionary<string, string>? headers);
Task<HttpStatusCode> Post(Uri uri, IDictionary<string, string> parameters, object body); Task<HttpStatusCode> Post(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<T> Put<T>(Uri uri); Task<T> Put<T>(Uri uri);
Task<T> Put<T>(Uri uri, IDictionary<string, string> parameters); Task<T> Put<T>(Uri uri, IDictionary<string, string>? parameters);
Task<T> Put<T>(Uri uri, IDictionary<string, string> parameters, object body); Task<T> Put<T>(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<HttpStatusCode> Put(Uri uri, IDictionary<string, string> parameters, object body); Task<HttpStatusCode> Put(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<HttpStatusCode> PutRaw(Uri uri, IDictionary<string, string> parameters, object body); Task<HttpStatusCode> PutRaw(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<T> Delete<T>(Uri uri); Task<T> Delete<T>(Uri uri);
Task<T> Delete<T>(Uri uri, IDictionary<string, string> parameters); Task<T> Delete<T>(Uri uri, IDictionary<string, string>? parameters);
Task<T> Delete<T>(Uri uri, IDictionary<string, string> parameters, object body); Task<T> Delete<T>(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<HttpStatusCode> Delete(Uri uri, IDictionary<string, string> parameters, object body); Task<HttpStatusCode> Delete(Uri uri, IDictionary<string, string>? parameters, object? body);
Task<T> SendAPIRequest<T>( Task<T> SendAPIRequest<T>(
Uri uri, HttpMethod method, Uri uri, HttpMethod method,
IDictionary<string, string> parameters = null, IDictionary<string, string>? parameters = null,
object body = null, object? body = null,
IDictionary<string, string> headers = null); IDictionary<string, string>? headers = null);
void SetRequestTimeout(TimeSpan timeout); void SetRequestTimeout(TimeSpan timeout);
} }

View File

@ -4,8 +4,8 @@ namespace SpotifyAPI.Web
{ {
string Host { get; } string Host { get; }
int Port { get; } int Port { get; }
string User { get; } string? User { get; }
string Password { get; } string? Password { get; }
bool SkipSSLCheck { get; } bool SkipSSLCheck { get; }
/// <summary> /// <summary>
/// Whether to bypass the proxy server for local addresses. /// Whether to bypass the proxy server for local addresses.

View File

@ -16,6 +16,6 @@ namespace SpotifyAPI.Web.Http
HttpMethod Method { get; } HttpMethod Method { get; }
object Body { get; set; } object? Body { get; set; }
} }
} }

View File

@ -5,12 +5,12 @@ namespace SpotifyAPI.Web.Http
{ {
public interface IResponse public interface IResponse
{ {
object Body { get; } object? Body { get; }
IReadOnlyDictionary<string, string> Headers { get; } IReadOnlyDictionary<string, string> Headers { get; }
HttpStatusCode StatusCode { get; } HttpStatusCode StatusCode { get; }
string ContentType { get; } string? ContentType { get; }
} }
} }

View File

@ -10,7 +10,7 @@ namespace SpotifyAPI.Web.Http
{ {
public class NetHttpClient : IHTTPClient public class NetHttpClient : IHTTPClient
{ {
private readonly HttpMessageHandler _httpMessageHandler; private readonly HttpMessageHandler? _httpMessageHandler;
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
public NetHttpClient() public NetHttpClient()

View File

@ -31,10 +31,13 @@ namespace SpotifyAPI.Web.Http
{ {
Ensure.ArgumentNotNull(response, nameof(response)); Ensure.ArgumentNotNull(response, nameof(response));
if (response.ContentType?.Equals("application/json", StringComparison.Ordinal) is true || response.ContentType == null) if (
(
response.ContentType?.Equals("application/json", StringComparison.Ordinal) is true || response.ContentType == null
))
{ {
var body = JsonConvert.DeserializeObject<T>(response.Body as string, _serializerSettings); var body = JsonConvert.DeserializeObject<T>(response.Body as string ?? "", _serializerSettings);
return new APIResponse<T>(response, body); return new APIResponse<T>(response, body!);
} }
return new APIResponse<T>(response); return new APIResponse<T>(response);
} }

View File

@ -12,8 +12,8 @@ namespace SpotifyAPI.Web
public string Host { get; } public string Host { get; }
public int Port { get; } public int Port { get; }
public string User { get; set; } public string? User { get; set; }
public string Password { get; set; } public string? Password { get; set; }
public bool BypassProxyOnLocal { get; set; } public bool BypassProxyOnLocal { get; set; }
public bool SkipSSLCheck { get; set; } public bool SkipSSLCheck { get; set; }
} }

View File

@ -6,22 +6,36 @@ namespace SpotifyAPI.Web.Http
{ {
public class Request : IRequest public class Request : IRequest
{ {
public Request() public Request(Uri baseAddress, Uri endpoint, HttpMethod method)
{ {
Headers = new Dictionary<string, string>(); Headers = new Dictionary<string, string>();
Parameters = new Dictionary<string, string>(); Parameters = new Dictionary<string, string>();
BaseAddress = baseAddress;
Endpoint = endpoint;
Method = method;
} }
public Request(IDictionary<string, string> headers) public Request(Uri baseAddress, Uri endpoint, HttpMethod method, IDictionary<string, string> headers)
{ {
Headers = headers; Headers = headers;
Parameters = new Dictionary<string, string>(); Parameters = new Dictionary<string, string>();
BaseAddress = baseAddress;
Endpoint = endpoint;
Method = method;
} }
public Request(IDictionary<string, string> headers, IDictionary<string, string> parameters) public Request(
Uri baseAddress,
Uri endpoint,
HttpMethod method,
IDictionary<string, string> headers,
IDictionary<string, string> parameters)
{ {
Headers = headers; Headers = headers;
Parameters = parameters; Parameters = parameters;
BaseAddress = baseAddress;
Endpoint = endpoint;
Method = method;
} }
public Uri BaseAddress { get; set; } public Uri BaseAddress { get; set; }
@ -34,6 +48,6 @@ namespace SpotifyAPI.Web.Http
public HttpMethod Method { get; set; } public HttpMethod Method { get; set; }
public object Body { get; set; } public object? Body { get; set; }
} }
} }

View File

@ -14,12 +14,12 @@ namespace SpotifyAPI.Web.Http
Headers = new ReadOnlyDictionary<string, string>(headers); Headers = new ReadOnlyDictionary<string, string>(headers);
} }
public object Body { get; set; } public object? Body { get; set; }
public IReadOnlyDictionary<string, string> Headers { get; set; } public IReadOnlyDictionary<string, string> Headers { get; set; }
public HttpStatusCode StatusCode { get; set; } public HttpStatusCode StatusCode { get; set; }
public string ContentType { get; set; } public string? ContentType { get; set; }
} }
} }

View File

@ -12,7 +12,7 @@ namespace SpotifyAPI.Web.Http
{ {
Ensure.ArgumentNotNull(request, nameof(request)); Ensure.ArgumentNotNull(request, nameof(request));
string parameters = null; string? parameters = null;
if (request.Parameters != null) if (request.Parameters != null)
{ {
parameters = string.Join(",", request.Parameters?.Select(kv => kv.Key + "=" + kv.Value).ToArray()); parameters = string.Join(",", request.Parameters?.Select(kv => kv.Key + "=" + kv.Value).ToArray());
@ -26,9 +26,9 @@ namespace SpotifyAPI.Web.Http
{ {
Ensure.ArgumentNotNull(response, nameof(response)); Ensure.ArgumentNotNull(response, nameof(response));
#if NETSTANDARD2_0 #if NETSTANDARD2_0
string body = response.Body?.ToString().Replace("\n", ""); string? body = response.Body?.ToString().Replace("\n", "");
#else #else
string body = response.Body?.ToString().Replace("\n", "", StringComparison.InvariantCulture); string? body = response.Body?.ToString().Replace("\n", "", StringComparison.InvariantCulture);
#endif #endif
body = body?.Substring(0, Math.Min(50, body?.Length ?? 0)); body = body?.Substring(0, Math.Min(50, body?.Length ?? 0));

View File

@ -8,8 +8,8 @@ namespace SpotifyAPI.Web
{ {
public override bool CanConvert(Type objectType) => true; public override bool CanConvert(Type objectType) => true;
public override object ReadJson(JsonReader reader, Type objectType, public override object? ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer) object? existingValue, JsonSerializer serializer)
{ {
Ensure.ArgumentNotNull(serializer, nameof(serializer)); Ensure.ArgumentNotNull(serializer, nameof(serializer));
@ -19,7 +19,7 @@ namespace SpotifyAPI.Web
return null; return null;
} }
var type = token["type"].Value<string>(); var type = token["type"]?.Value<string>();
if (type == "track") if (type == "track")
{ {
var obj = new FullTrack(); var obj = new FullTrack();
@ -38,10 +38,10 @@ namespace SpotifyAPI.Web
} }
} }
public override void WriteJson(JsonWriter writer, object value, public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
JsonSerializer serializer)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
} }
} }

View File

@ -3,6 +3,6 @@ namespace SpotifyAPI.Web
public class AlbumRequest : RequestParams public class AlbumRequest : RequestParams
{ {
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -3,7 +3,7 @@ namespace SpotifyAPI.Web
public class AlbumTracksRequest : RequestParams public class AlbumTracksRequest : RequestParams
{ {
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
@ -12,3 +12,4 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
} }
} }

View File

@ -15,6 +15,7 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -8,7 +8,7 @@ namespace SpotifyAPI.Web
public IncludeGroups? IncludeGroupsParam { get; set; } public IncludeGroups? IncludeGroupsParam { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
@ -34,3 +34,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -13,3 +13,4 @@ namespace SpotifyAPI.Web
public string Market { get; } public string Market { get; }
} }
} }

View File

@ -21,3 +21,4 @@ namespace SpotifyAPI.Web
public string ClientSecret { get; } public string ClientSecret { get; }
} }
} }

View File

@ -25,3 +25,4 @@ namespace SpotifyAPI.Web
public Uri RedirectUri { get; } public Uri RedirectUri { get; }
} }
} }

View File

@ -3,10 +3,10 @@ namespace SpotifyAPI.Web
public class CategoriesRequest : RequestParams public class CategoriesRequest : RequestParams
{ {
[QueryParam("country")] [QueryParam("country")]
public string Country { get; set; } public string? Country { get; set; }
[QueryParam("locale")] [QueryParam("locale")]
public string Locale { get; set; } public string? Locale { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
} }
} }

View File

@ -3,7 +3,7 @@ namespace SpotifyAPI.Web
public class CategoriesPlaylistsRequest : RequestParams public class CategoriesPlaylistsRequest : RequestParams
{ {
[QueryParam("country")] [QueryParam("country")]
public string Country { get; set; } public string? Country { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
@ -12,3 +12,4 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
} }
} }

View File

@ -3,9 +3,10 @@ namespace SpotifyAPI.Web
public class CategoryRequest : RequestParams public class CategoryRequest : RequestParams
{ {
[QueryParam("country")] [QueryParam("country")]
public string Country { get; set; } public string? Country { get; set; }
[QueryParam("locale")] [QueryParam("locale")]
public string Locale { get; set; } public string? Locale { get; set; }
} }
} }

View File

@ -17,3 +17,4 @@ namespace SpotifyAPI.Web
public string ClientSecret { get; } public string ClientSecret { get; }
} }
} }

View File

@ -3,6 +3,7 @@ namespace SpotifyAPI.Web
public class EpisodeRequest : RequestParams public class EpisodeRequest : RequestParams
{ {
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -12,9 +12,10 @@ namespace SpotifyAPI.Web
} }
[QueryParam("ids")] [QueryParam("ids")]
public IList<string> Ids { get; set; } public IList<string> Ids { get; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -5,19 +5,24 @@ namespace SpotifyAPI.Web
public class FeaturedPlaylistsRequest : RequestParams public class FeaturedPlaylistsRequest : RequestParams
{ {
[QueryParam("country")] [QueryParam("country")]
public string Country { get; set; } public string? Country { get; set; }
[QueryParam("locale")] [QueryParam("locale")]
public string Locale { get; set; } public string? Locale { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
[QueryParam("offset")] [QueryParam("offset")]
public int? Offset { get; set; } public int? Offset { get; set; }
public DateTime? Timestamp { get; set; } public DateTime? Timestamp { get; set; }
[QueryParam("timestamp")] [QueryParam("timestamp")]
protected string TimestampFormatted protected string? TimestampFormatted
{ {
get => Timestamp?.ToString("o", CultureInfo.InvariantCulture); get => Timestamp?.ToString("o", CultureInfo.InvariantCulture);
} }
} }
} }

View File

@ -28,3 +28,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -14,7 +14,7 @@ namespace SpotifyAPI.Web
public int? Limit { get; set; } public int? Limit { get; set; }
[QueryParam("after")] [QueryParam("after")]
public string After { get; set; } public string? After { get; set; }
public enum Type public enum Type
{ {
@ -23,3 +23,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -6,3 +6,4 @@ namespace SpotifyAPI.Web
public bool? Public { get; set; } public bool? Public { get; set; }
} }
} }

View File

@ -28,3 +28,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -9,6 +9,7 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -16,3 +16,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
} }
} }

View File

@ -9,6 +9,7 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -9,6 +9,7 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -21,8 +21,8 @@ namespace SpotifyAPI.Web
public Uri RedirectUri { get; } public Uri RedirectUri { get; }
public ResponseType ResponseTypeParam { get; } public ResponseType ResponseTypeParam { get; }
public string ClientId { get; } public string ClientId { get; }
public string State { get; set; } public string? State { get; set; }
public ICollection<string> Scope { get; set; } public ICollection<string>? Scope { get; set; }
public bool? ShowDialog { get; set; } public bool? ShowDialog { get; set; }
public Uri ToUri() public Uri ToUri()
@ -54,3 +54,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -3,7 +3,7 @@ namespace SpotifyAPI.Web
public class NewReleasesRequest : RequestParams public class NewReleasesRequest : RequestParams
{ {
[QueryParam("country")] [QueryParam("country")]
public string Country { get; set; } public string? Country { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
@ -12,3 +12,4 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
} }
} }

View File

@ -24,3 +24,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -13,6 +13,7 @@ namespace SpotifyAPI.Web
public string Uri { get; } public string Uri { get; }
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -12,7 +12,7 @@ namespace SpotifyAPI.Web
} }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
/// <summary> /// <summary>
/// This is set to `"track", "episode"` by default. /// This is set to `"track", "episode"` by default.
@ -32,3 +32,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -34,3 +34,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -3,6 +3,7 @@ namespace SpotifyAPI.Web
public class PlayerPausePlaybackRequest : RequestParams public class PlayerPausePlaybackRequest : RequestParams
{ {
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -12,3 +12,4 @@ namespace SpotifyAPI.Web
public long? Before { get; set; } public long? Before { get; set; }
} }
} }

View File

@ -6,17 +6,17 @@ namespace SpotifyAPI.Web
public class PlayerResumePlaybackRequest : RequestParams public class PlayerResumePlaybackRequest : RequestParams
{ {
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
[BodyParam("context_uri")] [BodyParam("context_uri")]
public string ContextUri { get; set; } public string? ContextUri { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227")]
[BodyParam("uris")] [BodyParam("uris")]
public IList<string> Uris { get; set; } public IList<string>? Uris { get; set; }
[BodyParam("offset")] [BodyParam("offset")]
public Offset OffsetParam { get; set; } public Offset? OffsetParam { get; set; }
[BodyParam("position_ms")] [BodyParam("position_ms")]
public int? PositionMs { get; set; } public int? PositionMs { get; set; }
@ -24,10 +24,11 @@ namespace SpotifyAPI.Web
public class Offset public class Offset
{ {
[JsonProperty("uri", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("uri", NullValueHandling = NullValueHandling.Ignore)]
public string Uri { get; set; } public string? Uri { get; set; }
[JsonProperty("position", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("position", NullValueHandling = NullValueHandling.Ignore)]
public int? Position { get; set; } public int? Position { get; set; }
} }
} }
} }

View File

@ -11,6 +11,7 @@ namespace SpotifyAPI.Web
public long PositonMs { get; } public long PositonMs { get; }
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -10,7 +10,7 @@ namespace SpotifyAPI.Web
} }
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
[QueryParam("state")] [QueryParam("state")]
public State StateParam { get; } public State StateParam { get; }
@ -28,3 +28,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -11,6 +11,7 @@ namespace SpotifyAPI.Web
public bool State { get; } public bool State { get; }
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -3,6 +3,7 @@ namespace SpotifyAPI.Web
public class PlayerSkipNextRequest : RequestParams public class PlayerSkipNextRequest : RequestParams
{ {
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -3,6 +3,7 @@ namespace SpotifyAPI.Web
public class PlayerSkipPreviousRequest : RequestParams public class PlayerSkipPreviousRequest : RequestParams
{ {
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -18,3 +18,4 @@ namespace SpotifyAPI.Web
public bool? Play { get; set; } public bool? Play { get; set; }
} }
} }

View File

@ -11,6 +11,7 @@ namespace SpotifyAPI.Web
public int VolumePercent { get; } public int VolumePercent { get; }
[QueryParam("device_id")] [QueryParam("device_id")]
public string DeviceId { get; set; } public string? DeviceId { get; set; }
} }
} }

View File

@ -18,3 +18,4 @@ namespace SpotifyAPI.Web
public int? Position { get; set; } public int? Position { get; set; }
} }
} }

View File

@ -3,7 +3,7 @@ namespace SpotifyAPI.Web
public class PlaylistChangeDetailsRequest : RequestParams public class PlaylistChangeDetailsRequest : RequestParams
{ {
[BodyParam("name")] [BodyParam("name")]
public string Name { get; set; } public string? Name { get; set; }
[BodyParam("public")] [BodyParam("public")]
public bool? Public { get; set; } public bool? Public { get; set; }
@ -12,6 +12,7 @@ namespace SpotifyAPI.Web
public bool? Collaborative { get; set; } public bool? Collaborative { get; set; }
[BodyParam("description")] [BodyParam("description")]
public string Description { get; set; } public string? Description { get; set; }
} }
} }

View File

@ -19,6 +19,7 @@ namespace SpotifyAPI.Web
public bool? Collaborative { get; set; } public bool? Collaborative { get; set; }
[BodyParam("description")] [BodyParam("description")]
public string Description { get; set; } public string? Description { get; set; }
} }
} }

View File

@ -9,3 +9,4 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
} }
} }

View File

@ -23,7 +23,7 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
/// <summary> /// <summary>
/// This is set to `"track", "episode"` by default. /// This is set to `"track", "episode"` by default.
@ -43,3 +43,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -30,3 +30,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -9,3 +9,4 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
} }
} }

View File

@ -16,17 +16,18 @@ namespace SpotifyAPI.Web
public IList<Item> Tracks { get; } public IList<Item> Tracks { get; }
[BodyParam("snapshot_id")] [BodyParam("snapshot_id")]
public string SnapshotId { get; set; } public string? SnapshotId { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034")]
public class Item public class Item
{ {
[JsonProperty("uri", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("uri", NullValueHandling = NullValueHandling.Ignore)]
public string Uri { get; set; } public string? Uri { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227")]
[JsonProperty("positions", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("positions", NullValueHandling = NullValueHandling.Ignore)]
public List<int> Positions { get; set; } public List<int>? Positions { get; set; }
} }
} }
} }

View File

@ -18,6 +18,7 @@ namespace SpotifyAPI.Web
public int? RangeLength { get; set; } public int? RangeLength { get; set; }
[BodyParam("snapshot_id")] [BodyParam("snapshot_id")]
public string SnapshotId { get; set; } public string? SnapshotId { get; set; }
} }
} }

View File

@ -15,3 +15,4 @@ namespace SpotifyAPI.Web
public IList<string> Uris { get; } public IList<string> Uris { get; }
} }
} }

View File

@ -28,7 +28,7 @@ namespace SpotifyAPI.Web
public int? Limit { get; set; } public int? Limit { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
public Dictionary<string, string> Min { get; } public Dictionary<string, string> Min { get; }
public Dictionary<string, string> Max { get; } public Dictionary<string, string> Max { get; }
@ -61,3 +61,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -20,9 +20,8 @@ namespace SpotifyAPI.Web
var obj = new JObject(); var obj = new JObject();
foreach (var prop in bodyProps) foreach (var prop in bodyProps)
{ {
var attribute = prop.GetCustomAttribute(typeof(BodyParamAttribute)) as BodyParamAttribute;
object value = prop.GetValue(this); object value = prop.GetValue(this);
if (value != null) if (value != null && prop.GetCustomAttribute(typeof(BodyParamAttribute)) is BodyParamAttribute attribute)
{ {
obj[attribute.Key ?? prop.Name] = JToken.FromObject(value); obj[attribute.Key ?? prop.Name] = JToken.FromObject(value);
} }
@ -41,9 +40,8 @@ namespace SpotifyAPI.Web
var queryParams = new Dictionary<string, string>(); var queryParams = new Dictionary<string, string>();
foreach (var prop in queryProps) foreach (var prop in queryProps)
{ {
var attribute = prop.GetCustomAttribute(typeof(QueryParamAttribute)) as QueryParamAttribute;
object value = prop.GetValue(this); object value = prop.GetValue(this);
if (value != null) if (value != null && prop.GetCustomAttribute(typeof(QueryParamAttribute)) is QueryParamAttribute attribute)
{ {
if (value is IList<string> list && list.Count > 0) if (value is IList<string> list && list.Count > 0)
{ {
@ -91,7 +89,6 @@ namespace SpotifyAPI.Web
{ {
public string Key { get; } public string Key { get; }
public QueryParamAttribute() { }
public QueryParamAttribute(string key) public QueryParamAttribute(string key)
{ {
Key = key; Key = key;
@ -103,10 +100,10 @@ namespace SpotifyAPI.Web
{ {
public string Key { get; } public string Key { get; }
public BodyParamAttribute() { }
public BodyParamAttribute(string key) public BodyParamAttribute(string key)
{ {
Key = key; Key = key;
} }
} }
} }

View File

@ -20,7 +20,7 @@ namespace SpotifyAPI.Web
public string Query { get; set; } public string Query { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
[QueryParam("limit")] [QueryParam("limit")]
public int? Limit { get; set; } public int? Limit { get; set; }
@ -57,3 +57,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -9,6 +9,7 @@ namespace SpotifyAPI.Web
public int? Offset { get; set; } public int? Offset { get; set; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -3,6 +3,7 @@ namespace SpotifyAPI.Web
public class ShowRequest : RequestParams public class ShowRequest : RequestParams
{ {
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -15,6 +15,7 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -3,6 +3,7 @@ namespace SpotifyAPI.Web
public class TrackRequest : RequestParams public class TrackRequest : RequestParams
{ {
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -12,6 +12,7 @@ namespace SpotifyAPI.Web
} }
[QueryParam("ids")] [QueryParam("ids")]
public IList<string> Ids { get; private set; } public IList<string> Ids { get; }
} }
} }

View File

@ -15,6 +15,7 @@ namespace SpotifyAPI.Web
public IList<string> Ids { get; } public IList<string> Ids { get; }
[QueryParam("market")] [QueryParam("market")]
public string Market { get; set; } public string? Market { get; set; }
} }
} }

View File

@ -27,3 +27,4 @@ namespace SpotifyAPI.Web
} }
} }
} }

View File

@ -4,6 +4,7 @@ namespace SpotifyAPI.Web
{ {
public class Actions public class Actions
{ {
public Dictionary<string, bool> Disallows { get; set; } public Dictionary<string, bool> Disallows { get; set; } = default!;
} }
} }

View File

@ -4,6 +4,7 @@ namespace SpotifyAPI.Web
{ {
public class AlbumsResponse public class AlbumsResponse
{ {
public List<FullAlbum> Albums { get; set; } public List<FullAlbum> Albums { get; set; } = default!;
} }
} }

View File

@ -4,6 +4,7 @@ namespace SpotifyAPI.Web
{ {
public class ArtistsRelatedArtistsResponse public class ArtistsRelatedArtistsResponse
{ {
public List<FullArtist> Artists { get; set; } public List<FullArtist> Artists { get; set; } = default!;
} }
} }

View File

@ -4,6 +4,7 @@ namespace SpotifyAPI.Web
{ {
public class ArtistsResponse public class ArtistsResponse
{ {
public List<FullArtist> Artists { get; set; } public List<FullArtist> Artists { get; set; } = default!;
} }
} }

View File

@ -4,6 +4,7 @@ namespace SpotifyAPI.Web
{ {
public class ArtistsTopTracksResponse public class ArtistsTopTracksResponse
{ {
public List<FullTrack> Tracks { get; set; } public List<FullTrack> Tracks { get; set; } = default!;
} }
} }

View File

@ -1,14 +1,13 @@
using System; using System;
using System.Collections.Generic;
namespace SpotifyAPI.Web namespace SpotifyAPI.Web
{ {
public class AuthorizationCodeRefreshResponse public class AuthorizationCodeRefreshResponse
{ {
public string AccessToken { get; set; } public string AccessToken { get; set; } = default!;
public string TokenType { get; set; } public string TokenType { get; set; } = default!;
public int ExpiresIn { get; set; } public int ExpiresIn { get; set; }
public string Scope { get; set; } public string Scope { get; set; } = default!;
/// <summary> /// <summary>
/// Auto-Initalized to UTC Now /// Auto-Initalized to UTC Now
@ -19,3 +18,4 @@ namespace SpotifyAPI.Web
public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; }
} }
} }

View File

@ -5,11 +5,11 @@ namespace SpotifyAPI.Web
{ {
public class AuthorizationCodeTokenResponse public class AuthorizationCodeTokenResponse
{ {
public string AccessToken { get; set; } public string AccessToken { get; set; } = default!;
public string TokenType { get; set; } public string TokenType { get; set; } = default!;
public int ExpiresIn { get; set; } public int ExpiresIn { get; set; }
public string Scope { get; set; } public string Scope { get; set; } = default!;
public string RefreshToken { get; set; } public string RefreshToken { get; set; } = default!;
/// <summary> /// <summary>
/// Auto-Initalized to UTC Now /// Auto-Initalized to UTC Now
@ -20,3 +20,4 @@ namespace SpotifyAPI.Web
public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; }
} }
} }

Some files were not shown because too many files have changed in this diff Show More