Skip to content

Commit

Permalink
Use System.Text.Json instead.
Browse files Browse the repository at this point in the history
  • Loading branch information
mayuki committed Nov 21, 2024
1 parent dcba401 commit 5ba747d
Show file tree
Hide file tree
Showing 9 changed files with 1,020 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace JsonTranscodingSample.Shared;

public interface IMyFirstService
public interface IMyFirstService : IService<IMyFirstService>
{
UnaryResult<string> SayHelloAsync(string name, int age);
UnaryResult<RegisterUserResponse> RegisterUserAsync(RegisterUserRequest request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@
<ProjectReference Include="..\MagicOnion.Server\MagicOnion.Server.csproj" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="MagicOnion.Server.JsonTranscoding.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f1ee449290a81377cf1a6d598f10a3e2de6c45ee5377140b179b7a2260007c4ba633a6f766a0b3392ae2160819d625d9d9d65a134b722fd4e637793479d6c8d72490f9992293ee53933205620245e55fcddb7ce6395d72c94365a432808fbcf1bf8ff2932a1263715f8bc73bb25b96366f118c58e24da5f2bee32223948d7bc5" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ILoggerFactory loggerFactory
{
public void BindUnary<TRequest, TResponse, TRawRequest, TRawResponse>(IMagicOnionUnaryMethod<TService, TRequest, TResponse, TRawRequest, TRawResponse> method) where TRawRequest : class where TRawResponse : class
{
var messageSerializer = new MessagePackJsonMessageSerializer(options.MessagePackSerializerOptions ?? MessagePackSerializer.DefaultOptions);
var messageSerializer = new SystemTextJsonMessageSerializer(options.JsonSerializerOptions ?? JsonSerializerOptions.Default);

var grpcMethod = GrpcMethodHelper.CreateMethod<TRequest, TResponse, TRawRequest, TRawResponse>(MethodType.Unary, method.ServiceName, method.MethodName, messageSerializer);

Expand All @@ -36,6 +36,9 @@ public void BindUnary<TRequest, TResponse, TRawRequest, TRawResponse>(IMagicOnio
context.AddMethod(grpcMethod, RoutePatternFactory.Parse(routePath), metadata, async (context) =>
{
var serverCallContext = new MagicOnionJsonTranscodingServerCallContext(method);
// Grpc.AspNetCore.Server expects that UserState has the key "__HttpContext" and that HttpContext is set to it.
// https://github.com/grpc/grpc-dotnet/blob/5a58c24efc1d0b7c5ff88e7b0582ea891b90b17f/src/Grpc.AspNetCore.Server/ServerCallContextExtensions.cs#L30
serverCallContext.UserState["__HttpContext"] = context;
context.Features.Set<IServerCallContextFeature>(serverCallContext);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using MessagePack;
using System.Text.Json;

namespace MagicOnion.Server.JsonTranscoding;

public class MagicOnionJsonTranscodingOptions
{
public MessagePackSerializerOptions? MessagePackSerializerOptions { get; set; }
public JsonSerializerOptions? JsonSerializerOptions { get; set; }
}

This file was deleted.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>

<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\src\MagicOnion\opensource.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
using System.Buffers;
using System.Text;
using System.Text.Json;
using MessagePack;

namespace MagicOnion.Server.JsonTranscoding.Tests;

public class SystemTextJsonMessageSerializerTest
{
[Fact]
public void Serialize_Primitive_BuiltIn_String()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, "FooBar");

// Assert
Assert.Equal("\"FooBar\""u8.ToArray(), writer.WrittenMemory.ToArray());
}

[Fact]
public void Serialize_Primitive_BuiltIn_Number()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, 123456789);

// Assert
Assert.Equal("123456789"u8.ToArray(), writer.WrittenMemory.ToArray());
}

[Fact]
public void Serialize_Primitive_BuiltIn_Null()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, default(string));

// Assert
Assert.Equal("null"u8.ToArray(), writer.WrittenMemory.ToArray());
}

[Fact]
public void Serialize_Primitive_Nil()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, Nil.Default);

// Assert
Assert.Equal("null"u8.ToArray(), writer.WrittenMemory.ToArray());
}

[Fact]
public void Serialize_DynamicArgumentTuple_2()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, new DynamicArgumentTuple<string, int>("Alice", 18));

// Assert
Assert.Equal("""["Alice",18]""", Encoding.UTF8.GetString(writer.WrittenMemory.Span));
}

[Fact]
public void Serialize_DynamicArgumentTuple_15()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, new DynamicArgumentTuple<string, int, bool, long, char, int, string, bool, Guid, byte, string, int, long, float>(
"Alice", 18, true, long.MaxValue, 'X', int.MaxValue, "Foo", false, Guid.Parse("4dfa3247-0686-4b07-9772-cfb7ef30c22c"), 255, "Bar", 12345, -12345, 3.14f));

// Assert
Assert.Equal("""["Alice",18,true,9223372036854775807,"X",2147483647,"Foo",false,"4dfa3247-0686-4b07-9772-cfb7ef30c22c",255,"Bar",12345,-12345,3.14]""", Encoding.UTF8.GetString(writer.WrittenMemory.Span));
}

[Fact]
public void Serialize_Complex()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, new TestResponse()
{
A = 1234,
B = "Alice",
C = true,
Inner = new TestResponse.InnerResponse()
{
D = 98765432100,
E = "Hello!",
},
});

// Assert
Assert.Equal("""{"A":1234,"B":"Alice","C":true,"Inner":{"D":98765432100,"E":"Hello!"}}""", Encoding.UTF8.GetString(writer.WrittenMemory.Span));
}

[Fact]
public void Deserialize_Primitive_BuiltIn_String()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);

// Act
var value = messageSerializer.Deserialize<string>(new ReadOnlySequence<byte>("\"FooBar\""u8.ToArray()));

// Assert
Assert.Equal("FooBar", value);
}

[Fact]
public void Deserialize_Primitive_BuiltIn_Number()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);

// Act
var value = messageSerializer.Deserialize<long>(new ReadOnlySequence<byte>("""123456789"""u8.ToArray()));

// Assert
Assert.Equal(123456789, value);
}

[Fact]
public void Deserialize_Primitive_BuiltIn_Null()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);

// Act
var value = messageSerializer.Deserialize<object>(new ReadOnlySequence<byte>("""null"""u8.ToArray()));

// Assert
Assert.Null(value);
}

[Fact]
public void Deserialize_Primitive_Nil()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);

// Act
var value = messageSerializer.Deserialize<Nil>(new ReadOnlySequence<byte>("""null"""u8.ToArray()));

// Assert
Assert.Equal(Nil.Default, value);
}

[Fact]
public void Deserialize_DynamicArgumentTuple_2()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);

// Act
var value = messageSerializer.Deserialize<DynamicArgumentTuple<string, int>>(new ReadOnlySequence<byte>("""["Alice",18]"""u8.ToArray()));

// Assert
Assert.Equal("Alice", value.Item1);
Assert.Equal(18, value.Item2);
}

[Fact]
public void Deserialize_DynamicArgumentTuple_15()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);

// Act
var value = messageSerializer.Deserialize<DynamicArgumentTuple<string, int, bool, long, char, int, string, bool, Guid, byte, string, int, long, float>>(new ReadOnlySequence<byte>(
"""["Alice",18,true,9223372036854775807,"X",2147483647,"Foo",false,"4dfa3247-0686-4b07-9772-cfb7ef30c22c",255,"Bar",12345,-12345,3.14]"""u8.ToArray()));

// Assert
Assert.Equal("Alice", value.Item1);
Assert.Equal(18, value.Item2);
Assert.True(value.Item3);
Assert.Equal(long.MaxValue, value.Item4);
Assert.Equal('X', value.Item5);
Assert.Equal(int.MaxValue, value.Item6);
Assert.Equal("Foo", value.Item7);
Assert.False(value.Item8);
Assert.Equal(Guid.Parse("{4dfa3247-0686-4b07-9772-cfb7ef30c22c}"), value.Item9);
Assert.Equal(255, value.Item10);
Assert.Equal("Bar", value.Item11);
Assert.Equal(12345, value.Item12);
Assert.Equal(-12345, value.Item13);
Assert.Equal(3.14, value.Item14, precision: 5);
}

[Fact]
public void Deserialize_Complex()
{
// Arrange
var options = JsonSerializerOptions.Default;
var messageSerializer = new SystemTextJsonMessageSerializer(options);
var writer = new ArrayBufferWriter<byte>();

// Act
messageSerializer.Serialize(writer, new TestResponse()
{
A = 1234,
B = "Alice",
C = true,
Inner = new TestResponse.InnerResponse()
{
D = 98765432100,
E = "Hello!",
},
});

// Assert
Assert.Equal("""{"A":1234,"B":"Alice","C":true,"Inner":{"D":98765432100,"E":"Hello!"}}""", Encoding.UTF8.GetString(writer.WrittenMemory.Span));
}


[MessagePackObject]
public class TestResponse
{
[Key(0)]
public int A { get; set; }
[Key(1)]
public required string B { get; init; }
[Key(2)]
public bool C { get; set; }
[Key(3)]
public required InnerResponse Inner { get; init; }

[MessagePackObject]
public class InnerResponse
{
[Key(0)]
public long D { get; set; }
[Key(1)]
public required string E { get; init; }
}
}
}
Loading

0 comments on commit 5ba747d

Please sign in to comment.