[Preview 6] Use JsonReader interop with JsonSerializer (#10733)
This commit is contained in:
parent
f5020170ea
commit
c9724896e2
|
|
@ -1044,8 +1044,8 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(HubProtocolsAndTransportsAndHubPaths))]
|
[MemberData(nameof(HubProtocolsList))]
|
||||||
public async Task ServerThrowsHubExceptionOnHubMethodArgumentCountMismatch(string hubProtocolName, HttpTransportType transportType, string hubPath)
|
public async Task ServerThrowsHubExceptionOnHubMethodArgumentCountMismatch(string hubProtocolName)
|
||||||
{
|
{
|
||||||
bool ExpectedErrors(WriteContext writeContext)
|
bool ExpectedErrors(WriteContext writeContext)
|
||||||
{
|
{
|
||||||
|
|
@ -1056,7 +1056,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
var hubProtocol = HubProtocols[hubProtocolName];
|
var hubProtocol = HubProtocols[hubProtocolName];
|
||||||
using (StartServer<Startup>(out var server, ExpectedErrors))
|
using (StartServer<Startup>(out var server, ExpectedErrors))
|
||||||
{
|
{
|
||||||
var connection = CreateHubConnection(server.Url, hubPath, transportType, hubProtocol, LoggerFactory);
|
var connection = CreateHubConnection(server.Url, "/default", HttpTransportType.LongPolling, hubProtocol, LoggerFactory);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await connection.StartAsync().OrTimeout();
|
await connection.StartAsync().OrTimeout();
|
||||||
|
|
@ -1076,7 +1076,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory(Skip = "Will be fixed by https://github.com/dotnet/corefx/issues/36901")]
|
[Theory]
|
||||||
[MemberData(nameof(HubProtocolsAndTransportsAndHubPaths))]
|
[MemberData(nameof(HubProtocolsAndTransportsAndHubPaths))]
|
||||||
public async Task ServerThrowsHubExceptionOnHubMethodArgumentTypeMismatch(string hubProtocolName, HttpTransportType transportType, string hubPath)
|
public async Task ServerThrowsHubExceptionOnHubMethodArgumentTypeMismatch(string hubProtocolName, HttpTransportType transportType, string hubPath)
|
||||||
{
|
{
|
||||||
|
|
@ -1873,6 +1873,17 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> HubProtocolsList
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
foreach (var protocol in HubProtocols)
|
||||||
|
{
|
||||||
|
yield return new object[] { protocol.Key };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This list excludes "special" hub paths like "default-nowebsockets" which exist for specific tests.
|
// This list excludes "special" hub paths like "default-nowebsockets" which exist for specific tests.
|
||||||
public static string[] HubPaths = new[] { "/default", "/dynamic", "/hubT" };
|
public static string[] HubPaths = new[] { "/default", "/dynamic", "/hubT" };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace FunctionalTests
|
||||||
public string String { get; set; }
|
public string String { get; set; }
|
||||||
public int[] IntArray { get; set; }
|
public int[] IntArray { get; set; }
|
||||||
public byte[] ByteArray { get; set; }
|
public byte[] ByteArray { get; set; }
|
||||||
|
public Guid Guid { get; set; }
|
||||||
public DateTime DateTime { get;set; }
|
public DateTime DateTime { get;set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ namespace FunctionalTests
|
||||||
{
|
{
|
||||||
ByteArray = new byte[] { 0x1, 0x2, 0x3 },
|
ByteArray = new byte[] { 0x1, 0x2, 0x3 },
|
||||||
DateTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
DateTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
||||||
|
Guid = new Guid("00010203-0405-0607-0706-050403020100"),
|
||||||
IntArray = new int[] { 1, 2, 3 },
|
IntArray = new int[] { 1, 2, 3 },
|
||||||
String = "hello world",
|
String = "hello world",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -462,6 +462,7 @@ describe("hubConnection", () => {
|
||||||
DateTime: protocol.name === "json"
|
DateTime: protocol.name === "json"
|
||||||
? "2002-04-01T10:20:15Z"
|
? "2002-04-01T10:20:15Z"
|
||||||
: new Date(Date.UTC(2002, 3, 1, 10, 20, 15)), // Apr 1, 2002, 10:20:15am UTC
|
: new Date(Date.UTC(2002, 3, 1, 10, 20, 15)), // Apr 1, 2002, 10:20:15am UTC
|
||||||
|
Guid: "00010203-0405-0607-0706-050403020100",
|
||||||
IntArray: [0x01, 0x02, 0x03, 0xff],
|
IntArray: [0x01, 0x02, 0x03, 0xff],
|
||||||
String: "Hello, World!",
|
String: "Hello, World!",
|
||||||
};
|
};
|
||||||
|
|
@ -504,6 +505,7 @@ describe("hubConnection", () => {
|
||||||
DateTime: protocol.name === "json"
|
DateTime: protocol.name === "json"
|
||||||
? "2000-01-01T00:00:00Z"
|
? "2000-01-01T00:00:00Z"
|
||||||
: new Date(Date.UTC(2000, 0, 1)),
|
: new Date(Date.UTC(2000, 0, 1)),
|
||||||
|
Guid: "00010203-0405-0607-0706-050403020100",
|
||||||
IntArray: [0x01, 0x02, 0x03],
|
IntArray: [0x01, 0x02, 0x03],
|
||||||
String: "hello world",
|
String: "hello world",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>Implements the SignalR Hub Protocol using System.Text.Json.</Description>
|
<Description>Implements the SignalR Hub Protocol using System.Text.Json.</Description>
|
||||||
|
|
|
||||||
|
|
@ -124,9 +124,12 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
var hasArguments = false;
|
var hasArguments = false;
|
||||||
object[] arguments = null;
|
object[] arguments = null;
|
||||||
string[] streamIds = null;
|
string[] streamIds = null;
|
||||||
JsonDocument argumentsToken = null;
|
bool hasArgumentsToken = false;
|
||||||
JsonDocument itemsToken = null;
|
Utf8JsonReader argumentsToken = default;
|
||||||
JsonDocument resultToken = null;
|
bool hasItemsToken = false;
|
||||||
|
Utf8JsonReader itemsToken = default;
|
||||||
|
bool hasResultToken = false;
|
||||||
|
Utf8JsonReader resultToken = default;
|
||||||
ExceptionDispatchInfo argumentBindingException = null;
|
ExceptionDispatchInfo argumentBindingException = null;
|
||||||
Dictionary<string, string> headers = null;
|
Dictionary<string, string> headers = null;
|
||||||
var completed = false;
|
var completed = false;
|
||||||
|
|
@ -192,15 +195,16 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(invocationId))
|
if (string.IsNullOrEmpty(invocationId))
|
||||||
{
|
{
|
||||||
// If we don't have an invocation id then we need to store it as a JsonDocument so we can parse it later
|
// If we don't have an invocation id then we need to value copy the reader so we can parse it later
|
||||||
resultToken = JsonDocument.ParseValue(ref reader);
|
hasResultToken = true;
|
||||||
|
resultToken = reader;
|
||||||
|
reader.Skip();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If we have an invocation id already we can parse the end result
|
// If we have an invocation id already we can parse the end result
|
||||||
var returnType = binder.GetReturnType(invocationId);
|
var returnType = binder.GetReturnType(invocationId);
|
||||||
using var token = JsonDocument.ParseValue(ref reader);
|
result = BindType(ref reader, returnType);
|
||||||
result = BindType(token.RootElement, returnType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reader.TextEquals(ItemPropertyNameBytes.EncodedUtf8Bytes))
|
else if (reader.TextEquals(ItemPropertyNameBytes.EncodedUtf8Bytes))
|
||||||
|
|
@ -216,16 +220,17 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If we don't have an id yet then we need to store it as a JsonDocument to parse later
|
// If we don't have an id yet then we need to value copy the reader so we can parse it later
|
||||||
itemsToken = JsonDocument.ParseValue(ref reader);
|
hasItemsToken = true;
|
||||||
|
itemsToken = reader;
|
||||||
|
reader.Skip();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var itemType = binder.GetStreamItemType(id);
|
var itemType = binder.GetStreamItemType(id);
|
||||||
using var token = JsonDocument.ParseValue(ref reader);
|
item = BindType(ref reader, itemType);
|
||||||
item = BindType(token.RootElement, itemType);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -246,16 +251,17 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(target))
|
if (string.IsNullOrEmpty(target))
|
||||||
{
|
{
|
||||||
// We don't know the method name yet so just store the array in JsonDocument
|
// We don't know the method name yet so just value copy the reader so we can parse it later
|
||||||
argumentsToken = JsonDocument.ParseValue(ref reader);
|
hasArgumentsToken = true;
|
||||||
|
argumentsToken = reader;
|
||||||
|
reader.Skip();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var paramTypes = binder.GetParameterTypes(target);
|
var paramTypes = binder.GetParameterTypes(target);
|
||||||
using var token = JsonDocument.ParseValue(ref reader);
|
arguments = BindTypes(ref reader, paramTypes);
|
||||||
arguments = BindTypes(token.RootElement, paramTypes);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -295,22 +301,18 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
{
|
{
|
||||||
case HubProtocolConstants.InvocationMessageType:
|
case HubProtocolConstants.InvocationMessageType:
|
||||||
{
|
{
|
||||||
if (argumentsToken != null)
|
if (hasArgumentsToken)
|
||||||
{
|
{
|
||||||
// We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
|
// We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var paramTypes = binder.GetParameterTypes(target);
|
var paramTypes = binder.GetParameterTypes(target);
|
||||||
arguments = BindTypes(argumentsToken.RootElement, paramTypes);
|
arguments = BindTypes(ref argumentsToken, paramTypes);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
argumentBindingException = ExceptionDispatchInfo.Capture(ex);
|
argumentBindingException = ExceptionDispatchInfo.Capture(ex);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
argumentsToken.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message = argumentBindingException != null
|
message = argumentBindingException != null
|
||||||
|
|
@ -320,22 +322,18 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
break;
|
break;
|
||||||
case HubProtocolConstants.StreamInvocationMessageType:
|
case HubProtocolConstants.StreamInvocationMessageType:
|
||||||
{
|
{
|
||||||
if (argumentsToken != null)
|
if (hasArgumentsToken)
|
||||||
{
|
{
|
||||||
// We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
|
// We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var paramTypes = binder.GetParameterTypes(target);
|
var paramTypes = binder.GetParameterTypes(target);
|
||||||
arguments = BindTypes(argumentsToken.RootElement, paramTypes);
|
arguments = BindTypes(ref argumentsToken, paramTypes);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
argumentBindingException = ExceptionDispatchInfo.Capture(ex);
|
argumentBindingException = ExceptionDispatchInfo.Capture(ex);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
argumentsToken.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message = argumentBindingException != null
|
message = argumentBindingException != null
|
||||||
|
|
@ -344,38 +342,27 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HubProtocolConstants.StreamItemMessageType:
|
case HubProtocolConstants.StreamItemMessageType:
|
||||||
if (itemsToken != null)
|
if (hasItemsToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var returnType = binder.GetStreamItemType(invocationId);
|
var returnType = binder.GetStreamItemType(invocationId);
|
||||||
item = BindType(itemsToken.RootElement, returnType);
|
item = BindType(ref itemsToken, returnType);
|
||||||
}
|
}
|
||||||
catch (JsonException ex)
|
catch (JsonException ex)
|
||||||
{
|
{
|
||||||
message = new StreamBindingFailureMessage(invocationId, ExceptionDispatchInfo.Capture(ex));
|
message = new StreamBindingFailureMessage(invocationId, ExceptionDispatchInfo.Capture(ex));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
itemsToken.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message = BindStreamItemMessage(invocationId, item, hasItem, binder);
|
message = BindStreamItemMessage(invocationId, item, hasItem, binder);
|
||||||
break;
|
break;
|
||||||
case HubProtocolConstants.CompletionMessageType:
|
case HubProtocolConstants.CompletionMessageType:
|
||||||
if (resultToken != null)
|
if (hasResultToken)
|
||||||
{
|
{
|
||||||
try
|
var returnType = binder.GetReturnType(invocationId);
|
||||||
{
|
result = BindType(ref resultToken, returnType);
|
||||||
var returnType = binder.GetReturnType(invocationId);
|
|
||||||
result = BindType(resultToken.RootElement, returnType);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
resultToken.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message = BindCompletionMessage(invocationId, error, result, hasResult, binder);
|
message = BindCompletionMessage(invocationId, error, result, hasResult, binder);
|
||||||
|
|
@ -698,48 +685,47 @@ namespace Microsoft.AspNetCore.SignalR.Protocol
|
||||||
return new InvocationMessage(invocationId, target, arguments, streamIds);
|
return new InvocationMessage(invocationId, target, arguments, streamIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
private object BindType(JsonElement jsonObject, Type type)
|
private object BindType(ref Utf8JsonReader reader, Type type)
|
||||||
{
|
{
|
||||||
if (type == typeof(DateTime))
|
return JsonSerializer.ReadValue(ref reader, type, _payloadSerializerOptions);
|
||||||
{
|
|
||||||
return jsonObject.GetDateTime();
|
|
||||||
}
|
|
||||||
else if (type == typeof(DateTimeOffset))
|
|
||||||
{
|
|
||||||
return jsonObject.GetDateTimeOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonSerializer.Parse(jsonObject.GetRawText(), type, _payloadSerializerOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private object[] BindTypes(JsonElement jsonArray, IReadOnlyList<Type> paramTypes)
|
private object[] BindTypes(ref Utf8JsonReader reader, IReadOnlyList<Type> paramTypes)
|
||||||
{
|
{
|
||||||
object[] arguments = null;
|
object[] arguments = null;
|
||||||
var paramIndex = 0;
|
var paramIndex = 0;
|
||||||
var argumentsCount = jsonArray.GetArrayLength();
|
|
||||||
var paramCount = paramTypes.Count;
|
var paramCount = paramTypes.Count;
|
||||||
|
|
||||||
if (argumentsCount != paramCount)
|
var depth = reader.CurrentDepth;
|
||||||
|
reader.CheckRead();
|
||||||
|
|
||||||
|
while (reader.TokenType != JsonTokenType.EndArray && reader.CurrentDepth > depth)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException($"Invocation provides {argumentsCount} argument(s) but target expects {paramCount}.");
|
if (paramIndex < paramCount)
|
||||||
|
{
|
||||||
|
arguments ??= new object[paramCount];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
arguments[paramIndex] = BindType(ref reader, paramTypes[paramIndex]);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Skip extra arguments and throw error after reading them all
|
||||||
|
reader.Skip();
|
||||||
|
}
|
||||||
|
reader.CheckRead();
|
||||||
|
paramIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var element in jsonArray.EnumerateArray())
|
if (paramIndex != paramCount)
|
||||||
{
|
{
|
||||||
if (arguments == null)
|
throw new InvalidDataException($"Invocation provides {paramIndex} argument(s) but target expects {paramCount}.");
|
||||||
{
|
|
||||||
arguments = new object[paramCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
arguments[paramIndex] = BindType(element, paramTypes[paramIndex]);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new InvalidDataException("Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arguments ?? Array.Empty<object>();
|
return arguments ?? Array.Empty<object>();
|
||||||
|
|
|
||||||
|
|
@ -205,9 +205,8 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
[InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[ \"abc\", \"xyz\"]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
|
[InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[ \"abc\", \"xyz\"]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
|
||||||
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]}", "Invocation provides 3 argument(s) but target expects 2.")]
|
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]}", "Invocation provides 3 argument(s) but target expects 2.")]
|
||||||
[InlineData("{\"type\":1,\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]},\"invocationId\":\"42\",\"target\":\"foo\"", "Invocation provides 3 argument(s) but target expects 2.")]
|
[InlineData("{\"type\":1,\"arguments\":[1,\"\",{\"1\":1,\"2\":2}]},\"invocationId\":\"42\",\"target\":\"foo\"", "Invocation provides 3 argument(s) but target expects 2.")]
|
||||||
// Both of these should be fixed by https://github.com/dotnet/corefx/issues/36901
|
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[1]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
|
||||||
// [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[1]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
|
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
|
||||||
// [InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[1,[]]}", "Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.")]
|
|
||||||
public void ArgumentBindingErrors(string input, string expectedMessage)
|
public void ArgumentBindingErrors(string input, string expectedMessage)
|
||||||
{
|
{
|
||||||
input = Frame(input);
|
input = Frame(input);
|
||||||
|
|
@ -219,6 +218,18 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
Assert.Equal(expectedMessage, bindingFailure.BindingFailure.SourceException.Message);
|
Assert.Equal(expectedMessage, bindingFailure.BindingFailure.SourceException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[[}]}")]
|
||||||
|
public void InvalidNestingWhileBindingTypesFails(string input)
|
||||||
|
{
|
||||||
|
input = Frame(input);
|
||||||
|
|
||||||
|
var binder = new TestBinder(paramTypes: new[] { typeof(int[]) }, returnType: null);
|
||||||
|
var data = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(input));
|
||||||
|
var ex = Assert.Throws<InvalidDataException>(() => JsonHubProtocol.TryParseMessage(ref data, binder, out var message));
|
||||||
|
Assert.Equal("Error reading JSON.", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[\"2007-03-01T13:00:00Z\"]}")]
|
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":[\"2007-03-01T13:00:00Z\"]}")]
|
||||||
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"arguments\":[\"2007-03-01T13:00:00Z\"],\"target\":\"foo\"}")]
|
[InlineData("{\"type\":1,\"invocationId\":\"42\",\"arguments\":[\"2007-03-01T13:00:00Z\"],\"target\":\"foo\"}")]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue