From 978f5cebc089dc26e2ecb65fd60701e4307edfa7 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Wed, 23 Aug 2017 15:30:08 -0700 Subject: [PATCH] Starting HubOptions (#743) * Added JsonSerializerSettings --- .../SignalRDependencyInjectionExtensions.cs | 7 +++ .../HubEndPoint.cs | 6 ++- .../HubOptions.cs | 12 +++++ .../Internal/DefaultHubProtocolResolver.cs | 10 +++- .../HubEndpointTests.cs | 47 ++++++++++++++++++- .../DefaultHubProtocolResolverTests.cs | 5 +- 6 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 src/Microsoft.AspNetCore.SignalR/HubOptions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Http/SignalRDependencyInjectionExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Http/SignalRDependencyInjectionExtensions.cs index 83cc586f05..99431e7665 100644 --- a/src/Microsoft.AspNetCore.SignalR.Http/SignalRDependencyInjectionExtensions.cs +++ b/src/Microsoft.AspNetCore.SignalR.Http/SignalRDependencyInjectionExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNetCore.SignalR; namespace Microsoft.Extensions.DependencyInjection @@ -9,6 +10,12 @@ namespace Microsoft.Extensions.DependencyInjection { public static ISignalRBuilder AddSignalR(this IServiceCollection services) { + return AddSignalR(services, _ => { }); + } + + public static ISignalRBuilder AddSignalR(this IServiceCollection services, Action configure) + { + services.Configure(configure); services.AddSockets(); return services.AddSignalRCore(); } diff --git a/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs b/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs index c1aeb69c78..d903973e4f 100644 --- a/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs +++ b/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs @@ -13,13 +13,14 @@ using System.Threading.Tasks.Channels; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR.Features; using Microsoft.AspNetCore.SignalR.Internal; +using Microsoft.AspNetCore.SignalR.Internal.Encoders; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.Sockets; using Microsoft.AspNetCore.Sockets.Features; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; using Microsoft.Extensions.Logging; -using Microsoft.AspNetCore.SignalR.Internal.Encoders; +using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.SignalR { @@ -36,16 +37,19 @@ namespace Microsoft.AspNetCore.SignalR private readonly ILogger> _logger; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IHubProtocolResolver _protocolResolver; + private readonly IOptions _hubOptions; public HubEndPoint(HubLifetimeManager lifetimeManager, IHubProtocolResolver protocolResolver, IHubContext hubContext, + IOptions hubOptions, ILogger> logger, IServiceScopeFactory serviceScopeFactory) { _protocolResolver = protocolResolver; _lifetimeManager = lifetimeManager; _hubContext = hubContext; + _hubOptions = hubOptions; _logger = logger; _serviceScopeFactory = serviceScopeFactory; diff --git a/src/Microsoft.AspNetCore.SignalR/HubOptions.cs b/src/Microsoft.AspNetCore.SignalR/HubOptions.cs new file mode 100644 index 0000000000..830056bbdd --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR/HubOptions.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Newtonsoft.Json; + +namespace Microsoft.AspNetCore.SignalR +{ + public class HubOptions + { + public JsonSerializerSettings JsonSerializerSettings { get; set; } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR/Internal/DefaultHubProtocolResolver.cs b/src/Microsoft.AspNetCore.SignalR/Internal/DefaultHubProtocolResolver.cs index e6da126131..bb0d44bf97 100644 --- a/src/Microsoft.AspNetCore.SignalR/Internal/DefaultHubProtocolResolver.cs +++ b/src/Microsoft.AspNetCore.SignalR/Internal/DefaultHubProtocolResolver.cs @@ -3,18 +3,26 @@ using System; using Microsoft.AspNetCore.SignalR.Internal.Protocol; +using Microsoft.Extensions.Options; using Newtonsoft.Json; namespace Microsoft.AspNetCore.SignalR.Internal { public class DefaultHubProtocolResolver : IHubProtocolResolver { + private readonly IOptions _options; + + public DefaultHubProtocolResolver(IOptions options) + { + _options = options; + } + public IHubProtocol GetProtocol(string protocolName, HubConnectionContext connection) { switch (protocolName?.ToLowerInvariant()) { case "json": - return new JsonHubProtocol(new JsonSerializer()); + return new JsonHubProtocol(JsonSerializer.Create(_options.Value.JsonSerializerSettings)); case "messagepack": return new MessagePackHubProtocol(); default: diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs index 79d2a29e25..fce843d018 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs @@ -10,9 +10,10 @@ using System.Threading.Tasks.Channels; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.SignalR.Tests.Common; -using Microsoft.CSharp; using Microsoft.Extensions.DependencyInjection; using Moq; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using Xunit; namespace Microsoft.AspNetCore.SignalR.Tests @@ -491,7 +492,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests await Task.WhenAll(firstClient.Connected, secondClient.Connected).OrTimeout(); - await firstClient.SendInvocationAsync("BroadcastMethod", "test").OrTimeout(); + await firstClient.SendInvocationAsync(nameof(MethodHub.BroadcastMethod), "test").OrTimeout(); foreach (var result in await Task.WhenAll( firstClient.ReadAsync(), @@ -813,6 +814,43 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public async Task HubOptionsCanUseCustomJsonSerializerSettings() + { + var serviceProvider = CreateServiceProvider(services => + { + services.AddSignalR(o => + { + o.JsonSerializerSettings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + }); + }); + + var endPoint = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var endPointLifetime = endPoint.OnConnectedAsync(client.Connection); + + await client.Connected.OrTimeout(); + + await client.SendInvocationAsync(nameof(MethodHub.BroadcastItem)).OrTimeout(); + + var message = await client.ReadAsync().OrTimeout() as InvocationMessage; + + var customItem = message.Arguments[0].ToString(); + // Originally "Message" and "paramName" + Assert.Contains("message", customItem); + Assert.Contains("paramName", customItem); + + client.Dispose(); + + await endPointLifetime.OrTimeout(); + } + } + private static void AssertHubMessage(HubMessage expected, HubMessage actual) { // We aren't testing InvocationIds here @@ -1060,6 +1098,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests return Clients.All.InvokeAsync("Broadcast", message); } + public Task BroadcastItem() + { + return Clients.All.InvokeAsync("Broadcast", new { Message = "test", paramName = "test" }); + } + public Task TaskValueMethod() { return Task.FromResult(42); diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs index fc0defc8ad..39c77de93e 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks.Channels; using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.AspNetCore.Sockets; +using Microsoft.Extensions.Options; using Moq; using Newtonsoft.Json; using Xunit; @@ -22,7 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Protocol.Tests var mockConnection = new Mock(Channel.CreateUnbounded().Out, new Mock().Object); Assert.IsType( protocol.GetType(), - new DefaultHubProtocolResolver().GetProtocol(protocol.Name, mockConnection.Object)); + new DefaultHubProtocolResolver(Options.Create(new HubOptions())).GetProtocol(protocol.Name, mockConnection.Object)); } [Theory] @@ -32,7 +33,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Protocol.Tests { var mockConnection = new Mock(Channel.CreateUnbounded().Out, new Mock().Object); var exception = Assert.Throws( - () => new DefaultHubProtocolResolver().GetProtocol(protocolName, mockConnection.Object)); + () => new DefaultHubProtocolResolver(Options.Create(new HubOptions())).GetProtocol(protocolName, mockConnection.Object)); Assert.Equal($"The protocol '{protocolName ?? "(null)"}' is not supported.", exception.Message); }