Skip to content

Commit

Permalink
Utilize source generated json serializer (#90)
Browse files Browse the repository at this point in the history
* Drop NET7_0_OR_GREATER
* Pass JsonTypeInfo into IPayPayEncoder methods
* Use JsonTypeInfo in the JsonMessageSerializer
  • Loading branch information
trejjam authored Jun 7, 2023
1 parent 618b10a commit 5229665
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 52 deletions.
3 changes: 3 additions & 0 deletions src/PayPal.Sdk.Checkout/Core/Interfaces/IPayPayEncoder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -9,13 +10,15 @@ public interface IPayPayEncoder
{
Task<HttpContent> SerializeRequestAsync<TRequestBody>(
TRequestBody body,
JsonTypeInfo<TRequestBody>? requestBodyJsonTypeInfo,
string contentType,
CancellationToken cancellationToken = default
)
where TRequestBody : notnull;

Task<TResponse> DeserializeResponseAsync<TResponse>(
HttpContent httpContent,
JsonTypeInfo<TResponse>? responseJsonTypeInfo,
MediaTypeHeaderValue mediaTypeHeaderValue,
CancellationToken cancellationToken = default
) where TResponse : notnull;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -16,7 +17,9 @@ public bool CanSerialize<TRequestBody>(
) where TRequestBody : notnull => contentType == ApplicationXForm;

public Task<HttpContent> SerializeAsync<TRequestBody>(
TRequestBody body, string contentType,
TRequestBody body,
JsonTypeInfo<TRequestBody>? requestBodyJsonTypeInfo,
string contentType,
CancellationToken cancellationToken
)
where TRequestBody : notnull
Expand All @@ -26,15 +29,19 @@ CancellationToken cancellationToken
return Task.FromResult((HttpContent) new FormUrlEncodedContent(dictionary));
}

throw new ArgumentException("Request requestBody must be IDictionary<string, string> when Content-Type is application/x-www-form-urlencoded");
throw new ArgumentException(
"Request requestBody must be IDictionary<string, string> when Content-Type is application/x-www-form-urlencoded"
);
}

public bool CanDeserialize<TResponse>(
HttpContent response, MediaTypeHeaderValue contentType
) where TResponse : notnull => false;

public Task<TResponse> DeserializeAsync<TResponse>(
HttpContent response, MediaTypeHeaderValue contentType,
HttpContent response,
JsonTypeInfo<TResponse>? responseJsonTypeInfo,
MediaTypeHeaderValue contentType,
CancellationToken cancellationToken
)
where TResponse : notnull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -11,7 +12,9 @@ bool CanSerialize<TRequestBody>(TRequestBody body, string contentType)
where TRequestBody : notnull;

Task<HttpContent> SerializeAsync<TRequestBody>(
TRequestBody body, string contentType,
TRequestBody body,
JsonTypeInfo<TRequestBody>? requestBodyJsonTypeInfo,
string contentType,
CancellationToken cancellationToken
)
where TRequestBody : notnull;
Expand All @@ -20,7 +23,9 @@ bool CanDeserialize<TResponse>(HttpContent response, MediaTypeHeaderValue conten
where TResponse : notnull;

Task<TResponse> DeserializeAsync<TResponse>(
HttpContent response, MediaTypeHeaderValue contentType,
HttpContent response,
JsonTypeInfo<TResponse>? responseJsonTypeInfo,
MediaTypeHeaderValue contentType,
CancellationToken cancellationToken
)
where TResponse : notnull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using PayPal.Sdk.Checkout.Core.Converters;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -18,26 +18,22 @@ public bool CanSerialize<TRequestBody>(
TRequestBody body, string contentType
) where TRequestBody : notnull => contentType == ApplicationJson;

private JsonSerializerOptions GetJsonSerializerOptions()
{
var jsonSerializerOptions = new JsonSerializerOptions();
jsonSerializerOptions.Converters.Add(new JsonStringEnumConverterFactory());

return jsonSerializerOptions;
}

public async Task<HttpContent> SerializeAsync<TRequestBody>(
TRequestBody body, string contentType,
TRequestBody body,
JsonTypeInfo<TRequestBody>? requestBodyJsonTypeInfo,
string contentType,
CancellationToken cancellationToken
)
where TRequestBody : notnull
{
_ = requestBodyJsonTypeInfo ?? throw new ArgumentNullException(nameof(requestBodyJsonTypeInfo));

var memoryStream = new MemoryStream();

await JsonSerializer.SerializeAsync(
memoryStream,
body,
GetJsonSerializerOptions(),
requestBodyJsonTypeInfo,
cancellationToken
);

Expand All @@ -57,20 +53,22 @@ public bool CanDeserialize<TResponse>(
) where TResponse : notnull => contentType.MediaType == ApplicationJson;

public async Task<TResponse> DeserializeAsync<TResponse>(
HttpContent response, MediaTypeHeaderValue contentType,
HttpContent response,
JsonTypeInfo<TResponse>? responseJsonTypeInfo,
MediaTypeHeaderValue contentType,
CancellationToken cancellationToken
)
where TResponse : notnull
{
_ = responseJsonTypeInfo ?? throw new ArgumentNullException(nameof(responseJsonTypeInfo));

var stream = await response.ReadAsStreamAsync(
#if NET7_0_OR_GREATER
cancellationToken
#endif
);

var deserializedResponse = await JsonSerializer.DeserializeAsync<TResponse>(
var deserializedResponse = await JsonSerializer.DeserializeAsync(
stream,
GetJsonSerializerOptions(),
responseJsonTypeInfo,
cancellationToken
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json.Serialization.Metadata;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -16,7 +17,9 @@ public bool CanSerialize<TRequestBody>(
) where TRequestBody : notnull => _contentTypeRegex.Match(contentType).Success;

public Task<HttpContent> SerializeAsync<TRequestBody>(
TRequestBody body, string contentType,
TRequestBody body,
JsonTypeInfo<TRequestBody>? requestBodyJsonTypeInfo,
string contentType,
CancellationToken cancellationToken
)
where TRequestBody : notnull
Expand All @@ -34,15 +37,15 @@ public bool CanDeserialize<TResponse>(
) where TResponse : notnull => _contentTypeRegex.Match(contentType.MediaType!).Success;

public async Task<TResponse> DeserializeAsync<TResponse>(
HttpContent response, MediaTypeHeaderValue contentType,
HttpContent response,
JsonTypeInfo<TResponse>? responseJsonTypeInfo,
MediaTypeHeaderValue contentType,
CancellationToken cancellationToken
)
where TResponse : notnull
{
return (TResponse) (object) await response.ReadAsStringAsync(
#if NET7_0_OR_GREATER
cancellationToken
#endif
cancellationToken
);
}
}
34 changes: 28 additions & 6 deletions src/PayPal.Sdk.Checkout/Core/PayPayEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -26,7 +27,9 @@ public PayPayEncoder()
}

public async Task<HttpContent> SerializeRequestAsync<TRequestBody>(
TRequestBody body, string contentType,
TRequestBody body,
JsonTypeInfo<TRequestBody>? requestBodyJsonTypeInfo,
string contentType,
CancellationToken cancellationToken
)
where TRequestBody : notnull
Expand All @@ -35,22 +38,41 @@ CancellationToken cancellationToken

if (serializer != null)
{
return await serializer.SerializeAsync(body, contentType, cancellationToken);
return await serializer.SerializeAsync(
body,
requestBodyJsonTypeInfo,
contentType,
cancellationToken
);
}

throw new ArgumentException($"Not found serializer for message {contentType}");
}

public async Task<TResponse> DeserializeResponseAsync<TResponse>(HttpContent httpContent, MediaTypeHeaderValue mediaTypeHeaderValue, CancellationToken cancellationToken)
public async Task<TResponse> DeserializeResponseAsync<TResponse>(
HttpContent httpContent,
JsonTypeInfo<TResponse>? responseJsonTypeInfo,
MediaTypeHeaderValue mediaTypeHeaderValue,
CancellationToken cancellationToken
)
where TResponse : notnull
{
var serializer = _messageSerializers.FirstOrDefault(x => x.CanDeserialize<TResponse>(httpContent, mediaTypeHeaderValue));
var serializer = _messageSerializers.FirstOrDefault(
x => x.CanDeserialize<TResponse>(httpContent, mediaTypeHeaderValue)
);

if (serializer != null)
{
return await serializer.DeserializeAsync<TResponse>(httpContent, mediaTypeHeaderValue, cancellationToken);
return await serializer.DeserializeAsync(
httpContent,
responseJsonTypeInfo,
mediaTypeHeaderValue,
cancellationToken
);
}

throw new ArgumentException($"Not found serializer for message CharSet={mediaTypeHeaderValue.CharSet} MediaType={mediaTypeHeaderValue.MediaType}");
throw new ArgumentException(
$"Not found serializer for message CharSet={mediaTypeHeaderValue.CharSet} MediaType={mediaTypeHeaderValue.MediaType}"
);
}
}
Loading

0 comments on commit 5229665

Please sign in to comment.