diff --git a/global.json b/global.json
index 8efcac913bea..ea54b3a4a7fc 100644
--- a/global.json
+++ b/global.json
@@ -1,9 +1,9 @@
{
"sdk": {
- "version": "5.0.100-rc.1.20452.10"
+ "version": "6.0.100-alpha.1.20472.11"
},
"tools": {
- "dotnet": "5.0.100-rc.1.20452.10",
+ "dotnet": "6.0.100-alpha.1.20472.11",
"runtimes": {
"dotnet/x64": [
"2.1.18",
diff --git a/src/Shared/OperatingSystem.cs b/src/Shared/OperatingSystem.cs
new file mode 100644
index 000000000000..e9ca7a717296
--- /dev/null
+++ b/src/Shared/OperatingSystem.cs
@@ -0,0 +1,19 @@
+// 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.
+
+#if NETCOREAPP
+#error Use System.OperatingSystem instead.
+#else
+
+using System.Runtime.InteropServices;
+
+namespace Microsoft.AspNetCore
+{
+ internal sealed class OperatingSystem
+ {
+ private static readonly bool _isBrowser = RuntimeInformation.IsOSPlatform(OSPlatform.Create("browser"));
+
+ public static bool IsBrowser() => _isBrowser;
+ }
+}
+#endif
diff --git a/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs b/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs
index c6e2878f2f36..6352e3ede330 100644
--- a/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs
+++ b/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs
@@ -1459,7 +1459,7 @@ private async Task ReconnectAsync(Exception closeException)
private OperationCanceledException GetOperationCanceledException(string message, Exception innerException, CancellationToken cancellationToken)
{
-#if NETSTANDARD2_1
+#if NETSTANDARD2_1 || NETCOREAPP
return new OperationCanceledException(message, innerException, _state.StopCts.Token);
#else
return new OperationCanceledException(message, innerException);
diff --git a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj
index 3fd4728dc69a..422af4542721 100644
--- a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj
+++ b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj
@@ -2,7 +2,7 @@
Client for ASP.NET Core SignalR
- $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1
+ $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1
Microsoft.AspNetCore.SignalR.Client
@@ -38,4 +38,8 @@
+
+
+
+
diff --git a/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj b/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj
index 47444465b45f..594f04355836 100644
--- a/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj
+++ b/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj
@@ -1,8 +1,8 @@
-
+
Client for ASP.NET Core SignalR
- $(DefaultNetFxTargetFramework);netstandard2.0
+ $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0
@@ -14,4 +14,8 @@
+
+
+
+
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
index 1af8f917f82d..8eb9e2ff15dc 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs
@@ -8,6 +8,7 @@
using System.Linq;
using System.Net.Http;
using System.Net.WebSockets;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
@@ -38,7 +39,6 @@ public partial class HttpConnection : ConnectionContext, IConnectionInherentKeep
private bool _started;
private bool _disposed;
private bool _hasInherentKeepAlive;
- private bool _isRunningInBrowser;
private readonly HttpClient _httpClient;
private readonly HttpConnectionOptions _httpConnectionOptions;
@@ -152,9 +152,7 @@ public HttpConnection(HttpConnectionOptions httpConnectionOptions, ILoggerFactor
_httpClient = CreateHttpClient();
}
- _isRunningInBrowser = Utils.IsRunningInBrowser();
-
- if (httpConnectionOptions.Transports == HttpTransportType.ServerSentEvents && _isRunningInBrowser)
+ if (httpConnectionOptions.Transports == HttpTransportType.ServerSentEvents && OperatingSystem.IsBrowser())
{
throw new ArgumentException("ServerSentEvents can not be the only transport specified when running in the browser.", nameof(httpConnectionOptions));
}
@@ -376,7 +374,7 @@ private async Task SelectAndStartTransport(TransferFormat transferFormat, Cancel
continue;
}
- if (transportType == HttpTransportType.ServerSentEvents && _isRunningInBrowser)
+ if (transportType == HttpTransportType.ServerSentEvents && OperatingSystem.IsBrowser())
{
Log.ServerSentEventsNotSupportedByBrowser(_logger);
transportExceptions.Add(new TransportFailedException("ServerSentEvents", "The transport is not supported in the browser."));
@@ -529,42 +527,49 @@ private HttpClient CreateHttpClient()
var httpClientHandler = new HttpClientHandler();
HttpMessageHandler httpMessageHandler = httpClientHandler;
+ var isBrowser = OperatingSystem.IsBrowser();
+
if (_httpConnectionOptions != null)
{
- if (_httpConnectionOptions.Proxy != null)
+ if (!isBrowser)
{
- httpClientHandler.Proxy = _httpConnectionOptions.Proxy;
- }
+ // Configure options that do not work in the browser inside this if-block
+ if (_httpConnectionOptions.Proxy != null)
+ {
+ httpClientHandler.Proxy = _httpConnectionOptions.Proxy;
+ }
- try
- {
- // On supported platforms, we need to pass the cookie container to the http client
- // so that we can capture any cookies from the negotiate response and give them to WebSockets.
- httpClientHandler.CookieContainer = _httpConnectionOptions.Cookies;
- }
- // Some variants of Mono do not support client certs or cookies and will throw NotImplementedException or NotSupportedException
- // Also WASM doesn't support some settings in the browser
- catch (Exception ex) when (ex is NotSupportedException || ex is NotImplementedException)
- {
- Log.CookiesNotSupported(_logger);
- }
+ try
+ {
+ // On supported platforms, we need to pass the cookie container to the http client
+ // so that we can capture any cookies from the negotiate response and give them to WebSockets.
+ httpClientHandler.CookieContainer = _httpConnectionOptions.Cookies;
+ }
+ catch (Exception ex) when (ex is NotSupportedException || ex is NotImplementedException)
+ {
+ // Some variants of Mono do not support client certs or cookies and will throw NotImplementedException or NotSupportedException
+ Log.CookiesNotSupported(_logger);
+ }
- // Only access HttpClientHandler.ClientCertificates
- // if the user has configured those options
- // https://github.com/aspnet/SignalR/issues/2232
- var clientCertificates = _httpConnectionOptions.ClientCertificates;
- if (clientCertificates?.Count > 0)
- {
- httpClientHandler.ClientCertificates.AddRange(clientCertificates);
- }
+ // Only access HttpClientHandler.ClientCertificates
+ // if the user has configured those options
+ // https://github.com/aspnet/SignalR/issues/2232
- if (_httpConnectionOptions.UseDefaultCredentials != null)
- {
- httpClientHandler.UseDefaultCredentials = _httpConnectionOptions.UseDefaultCredentials.Value;
- }
- if (_httpConnectionOptions.Credentials != null)
- {
- httpClientHandler.Credentials = _httpConnectionOptions.Credentials;
+ var clientCertificates = _httpConnectionOptions.ClientCertificates;
+ if (clientCertificates?.Count > 0)
+ {
+ httpClientHandler.ClientCertificates.AddRange(clientCertificates);
+ }
+
+ if (_httpConnectionOptions.UseDefaultCredentials != null)
+ {
+ httpClientHandler.UseDefaultCredentials = _httpConnectionOptions.UseDefaultCredentials.Value;
+ }
+
+ if (_httpConnectionOptions.Credentials != null)
+ {
+ httpClientHandler.Credentials = _httpConnectionOptions.Credentials;
+ }
}
httpMessageHandler = httpClientHandler;
@@ -645,7 +650,7 @@ private void CheckDisposed()
private static bool IsWebSocketsSupported()
{
-#if NETSTANDARD2_1
+#if NETSTANDARD2_1 || NETCOREAPP
// .NET Core 2.1 and above has a managed implementation
return true;
#else
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs
index cb3ca3d28ab8..6c26c84e71f4 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs
@@ -3,6 +3,7 @@
using System;
using System.Net;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
@@ -86,23 +87,22 @@ internal static HttpConnectionOptions ShallowCopyHttpConnectionOptions(HttpConne
{
HttpMessageHandlerFactory = options.HttpMessageHandlerFactory,
Headers = options.Headers,
- Cookies = options.Cookies,
Url = options.Url,
Transports = options.Transports,
SkipNegotiation = options.SkipNegotiation,
AccessTokenProvider = options.AccessTokenProvider,
CloseTimeout = options.CloseTimeout,
- Credentials = options.Credentials,
- Proxy = options.Proxy,
- UseDefaultCredentials = options.UseDefaultCredentials,
DefaultTransferFormat = options.DefaultTransferFormat,
- WebSocketConfiguration = options.WebSocketConfiguration,
};
- // WASM doesn't support Crypto APIs and our setter throws if you try to assign null
- if (options.ClientCertificates != null)
+ if (!OperatingSystem.IsBrowser())
{
+ newOptions.Cookies = options.Cookies;
newOptions.ClientCertificates = options.ClientCertificates;
+ newOptions.Credentials = options.Credentials;
+ newOptions.Proxy = options.Proxy;
+ newOptions.UseDefaultCredentials = options.UseDefaultCredentials;
+ newOptions.WebSocketConfiguration = options.WebSocketConfiguration;
}
return newOptions;
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs
index cfbe155e9b0c..523a34ed0611 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs
@@ -6,11 +6,12 @@
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
-using Microsoft.AspNetCore.Http.Connections.Client.Internal;
namespace Microsoft.AspNetCore.Http.Connections.Client
{
@@ -22,6 +23,10 @@ public class HttpConnectionOptions
private IDictionary _headers;
private X509CertificateCollection _clientCertificates;
private CookieContainer _cookies;
+ private ICredentials _credentials;
+ private IWebProxy _proxy;
+ private bool? _useDefaultCredentials;
+ private Action _webSocketConfiguration;
///
/// Initializes a new instance of the class.
@@ -31,7 +36,7 @@ public HttpConnectionOptions()
_headers = new Dictionary();
// System.Security.Cryptography isn't supported on WASM currently
- if (!Utils.IsRunningInBrowser())
+ if (!OperatingSystem.IsBrowser())
{
_clientCertificates = new X509CertificateCollection();
}
@@ -59,19 +64,37 @@ public IDictionary Headers
///
/// Gets or sets a collection of client certificates that will be sent with HTTP requests.
///
+ [UnsupportedOSPlatform("browser")]
public X509CertificateCollection ClientCertificates
{
- get => _clientCertificates;
- set => _clientCertificates = value ?? throw new ArgumentNullException(nameof(value));
+ get
+ {
+ ThrowIfUnsupportedPlatform();
+ return _clientCertificates;
+ }
+ set
+ {
+ ThrowIfUnsupportedPlatform();
+ _clientCertificates = value ?? throw new ArgumentNullException(nameof(value));
+ }
}
///
/// Gets or sets a collection of cookies that will be sent with HTTP requests.
///
+ [UnsupportedOSPlatform("browser")]
public CookieContainer Cookies
{
- get => _cookies;
- set => _cookies = value ?? throw new ArgumentNullException(nameof(value));
+ get
+ {
+ ThrowIfUnsupportedPlatform();
+ return _cookies;
+ }
+ set
+ {
+ ThrowIfUnsupportedPlatform();
+ _cookies = value ?? throw new ArgumentNullException(nameof(value));
+ }
}
///
@@ -105,17 +128,56 @@ public CookieContainer Cookies
///
/// Gets or sets the credentials used when making HTTP requests.
///
- public ICredentials Credentials { get; set; }
+ [UnsupportedOSPlatform("browser")]
+ public ICredentials Credentials
+ {
+ get
+ {
+ ThrowIfUnsupportedPlatform();
+ return _credentials;
+ }
+ set
+ {
+ ThrowIfUnsupportedPlatform();
+ _credentials = value;
+ }
+ }
///
/// Gets or sets the proxy used when making HTTP requests.
///
- public IWebProxy Proxy { get; set; }
+ [UnsupportedOSPlatform("browser")]
+ public IWebProxy Proxy
+ {
+ get
+ {
+ ThrowIfUnsupportedPlatform();
+ return _proxy;
+ }
+ set
+ {
+ ThrowIfUnsupportedPlatform();
+ _proxy = value;
+ }
+ }
///
/// Gets or sets a value indicating whether default credentials are used when making HTTP requests.
///
- public bool? UseDefaultCredentials { get; set; }
+ [UnsupportedOSPlatform("browser")]
+ public bool? UseDefaultCredentials
+ {
+ get
+ {
+ ThrowIfUnsupportedPlatform();
+ return _useDefaultCredentials;
+ }
+ set
+ {
+ ThrowIfUnsupportedPlatform();
+ _useDefaultCredentials = value;
+ }
+ }
///
/// Gets or sets the default to use if
@@ -131,6 +193,27 @@ public CookieContainer Cookies
/// This delegate is invoked after headers from and the access token from
/// has been applied.
///
- public Action WebSocketConfiguration { get; set; }
+ [UnsupportedOSPlatform("browser")]
+ public Action WebSocketConfiguration
+ {
+ get
+ {
+ ThrowIfUnsupportedPlatform();
+ return _webSocketConfiguration;
+ }
+ set
+ {
+ ThrowIfUnsupportedPlatform();
+ _webSocketConfiguration = value;
+ }
+ }
+
+ private static void ThrowIfUnsupportedPlatform()
+ {
+ if (OperatingSystem.IsBrowser())
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
}
}
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.cs
index e9f5b21a5be2..902f823e87f8 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/LongPollingTransport.cs
@@ -5,11 +5,13 @@
using System.IO.Pipelines;
using System.Net;
using System.Net.Http;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
+using static Microsoft.AspNetCore.Http.Connections.Client.Internal.Utils;
namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
{
@@ -161,7 +163,7 @@ private async Task Poll(Uri pollUrl, CancellationToken cancellationToken)
// just want to start a new poll.
continue;
}
- catch (WebException ex) when (ex.Status == WebExceptionStatus.RequestCanceled)
+ catch (WebException ex) when (!OperatingSystem.IsBrowser() && ex.Status == WebExceptionStatus.RequestCanceled)
{
// SendAsync on .NET Framework doesn't reliably throw OperationCanceledException.
// Catch the WebException and test it.
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs
index 8071a054a3ab..f92f89a3a044 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Utils.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Http.Connections.Client.Internal
{
@@ -42,10 +41,5 @@ internal static Uri AppendQueryString(Uri url, string qs)
builder.Query = newQueryString;
return builder.Uri;
}
-
- internal static bool IsRunningInBrowser()
- {
- return RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));
- }
}
}
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.Log.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.Log.cs
index 5012d65d64df..a7d110cf244a 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.Log.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.Log.cs
@@ -69,6 +69,12 @@ private static class Log
private static readonly Action _startedTransport =
LoggerMessage.Define(LogLevel.Debug, new EventId(19, "StartedTransport"), "Started transport.");
+ private static readonly Action _headersNotSupported =
+ LoggerMessage.Define(LogLevel.Warning, new EventId(20, "HeadersNotSupported"),
+ $"Configuring request headers using {nameof(HttpConnectionOptions)}.{nameof(HttpConnectionOptions.Headers)} is not supported when using websockets transport " +
+ "on the browser platform.");
+
+
public static void StartTransport(ILogger logger, TransferFormat transferFormat, Uri webSocketUrl)
{
_startTransport(logger, transferFormat, webSocketUrl, null);
@@ -163,6 +169,11 @@ public static void StartedTransport(ILogger logger)
{
_startedTransport(logger, null);
}
+
+ public static void HeadersNotSupported(ILogger logger)
+ {
+ _headersNotSupported(logger, null);
+ }
}
}
}
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
index 02c3a9748e2d..dde6c5e01611 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs
@@ -24,7 +24,6 @@ internal partial class WebSocketsTransport : ITransport
private readonly ILogger _logger;
private readonly TimeSpan _closeTimeout;
private volatile bool _aborted;
- private bool _isRunningInBrowser;
private IDuplexPipe _transport;
@@ -37,10 +36,8 @@ internal partial class WebSocketsTransport : ITransport
public WebSocketsTransport(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory, Func> accessTokenProvider)
{
_webSocket = new ClientWebSocket();
- _isRunningInBrowser = Utils.IsRunningInBrowser();
-
- // ClientWebSocketOptions throws PNSE when accessing and setting properties
- if (!_isRunningInBrowser)
+ var isBrowser = OperatingSystem.IsBrowser();
+ if (!isBrowser)
{
// Full Framework will throw when trying to set the User-Agent header
// So avoid setting it in netstandard2.0 and only set it in netstandard2.1 and higher
@@ -51,16 +48,30 @@ public WebSocketsTransport(HttpConnectionOptions httpConnectionOptions, ILoggerF
_webSocket.Options.SetRequestHeader("X-SignalR-User-Agent", Constants.UserAgentHeader.ToString());
#endif
- if (httpConnectionOptions != null)
+ // Set this header so the server auth middleware will set an Unauthorized instead of Redirect status code
+ // See: https://github.com/aspnet/Security/blob/ff9f145a8e89c9756ea12ff10c6d47f2f7eb345f/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs#L42
+ _webSocket.Options.SetRequestHeader("X-Requested-With", "XMLHttpRequest");
+ }
+
+ if (httpConnectionOptions != null)
+ {
+ if (httpConnectionOptions.Headers.Count > 0)
{
- if (httpConnectionOptions.Headers != null)
+ if (isBrowser)
+ {
+ Log.HeadersNotSupported(_logger);
+ }
+ else
{
foreach (var header in httpConnectionOptions.Headers)
{
_webSocket.Options.SetRequestHeader(header.Key, header.Value);
}
}
+ }
+ if (!isBrowser)
+ {
if (httpConnectionOptions.Cookies != null)
{
_webSocket.Options.Cookies = httpConnectionOptions.Cookies;
@@ -88,11 +99,6 @@ public WebSocketsTransport(HttpConnectionOptions httpConnectionOptions, ILoggerF
httpConnectionOptions.WebSocketConfiguration?.Invoke(_webSocket.Options);
}
-
-
- // Set this header so the server auth middleware will set an Unauthorized instead of Redirect status code
- // See: https://github.com/aspnet/Security/blob/ff9f145a8e89c9756ea12ff10c6d47f2f7eb345f/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs#L42
- _webSocket.Options.SetRequestHeader("X-Requested-With", "XMLHttpRequest");
}
_closeTimeout = httpConnectionOptions?.CloseTimeout ?? default;
@@ -128,7 +134,7 @@ public async Task StartAsync(Uri url, TransferFormat transferFormat, Cancellatio
if (!string.IsNullOrEmpty(accessToken))
{
// We can't use request headers in the browser, so instead append the token as a query string in that case
- if (_isRunningInBrowser)
+ if (OperatingSystem.IsBrowser())
{
var accessTokenEncoded = UrlEncoder.Default.Encode(accessToken);
accessTokenEncoded = "access_token=" + accessTokenEncoded;
@@ -136,7 +142,9 @@ public async Task StartAsync(Uri url, TransferFormat transferFormat, Cancellatio
}
else
{
+#pragma warning disable CA1416 // Analyzer bug
_webSocket.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}");
+#pragma warning restore CA1416 // Analyzer bug
}
}
}
@@ -228,7 +236,7 @@ private async Task StartReceiving(WebSocket socket)
{
while (true)
{
-#if NETSTANDARD2_1
+#if NETSTANDARD2_1 || NETCOREAPP
// Do a 0 byte read so that idle connections don't allocate a buffer when waiting for a read
var result = await socket.ReceiveAsync(Memory.Empty, CancellationToken.None);
@@ -245,7 +253,7 @@ private async Task StartReceiving(WebSocket socket)
}
#endif
var memory = _application.Output.GetMemory();
-#if NETSTANDARD2_1
+#if NETSTANDARD2_1 || NETCOREAPP
// Because we checked the CloseStatus from the 0 byte read above, we don't need to check again after reading
var receiveResult = await socket.ReceiveAsync(memory, CancellationToken.None);
#elif NETSTANDARD2_0 || NET461
diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj b/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj
index bae3bab800ac..840c26e9a10a 100644
--- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj
+++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj
@@ -2,7 +2,7 @@
Client for ASP.NET Core Connection Handlers
- $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1
+ $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1
@@ -11,6 +11,8 @@
+
+
@@ -31,4 +33,8 @@
+
+
+
+
diff --git a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj
index 02f97edfb68c..a6327955968f 100644
--- a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj
+++ b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj
@@ -23,4 +23,8 @@
+
+
+
+
diff --git a/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj b/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj
index 314ab57e6e36..9497a7c8ac8f 100644
--- a/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj
+++ b/src/SignalR/common/Http.Connections/src/Microsoft.AspNetCore.Http.Connections.csproj
@@ -42,4 +42,8 @@
+
+
+
+
diff --git a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj
index cae05aae1122..34a5f17dd19d 100644
--- a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj
+++ b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj
@@ -23,4 +23,8 @@
+
+
+
+
diff --git a/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj b/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj
index 8ed07be5dcdc..69554b03f11a 100644
--- a/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj
+++ b/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj
@@ -2,7 +2,7 @@
Implements the SignalR Hub Protocol over MsgPack.
- $(DefaultNetFxTargetFramework);netstandard2.0
+ $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0
Microsoft.AspNetCore.SignalR
true
enable
@@ -20,4 +20,8 @@
+
+
+
+
diff --git a/src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocolWorker.cs b/src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocolWorker.cs
index 43c9a8392980..6c36e33751d3 100644
--- a/src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocolWorker.cs
+++ b/src/SignalR/common/Protocols.MessagePack/src/Protocol/MessagePackHubProtocolWorker.cs
@@ -21,7 +21,7 @@ internal abstract class MessagePackHubProtocolWorker
private const int VoidResult = 2;
private const int NonVoidResult = 3;
- public bool TryParseMessage(ref ReadOnlySequence input, IInvocationBinder binder, out HubMessage message)
+ public bool TryParseMessage(ref ReadOnlySequence input, IInvocationBinder binder, out HubMessage? message)
{
if (!BinaryMessageParser.TryParseMessage(ref input, out var payload))
{
@@ -34,7 +34,7 @@ public bool TryParseMessage(ref ReadOnlySequence input, IInvocationBinder
return true;
}
- private HubMessage ParseMessage(ref MessagePackReader reader, IInvocationBinder binder)
+ private HubMessage? ParseMessage(ref MessagePackReader reader, IInvocationBinder binder)
{
var itemCount = reader.ReadArrayHeader();
@@ -76,7 +76,7 @@ private HubMessage CreateInvocationMessage(ref MessagePackReader reader, IInvoca
var target = ReadString(ref reader, "target");
- object[] arguments = null;
+ object[]? arguments;
try
{
var parameterTypes = binder.GetParameterTypes(target);
@@ -87,7 +87,7 @@ private HubMessage CreateInvocationMessage(ref MessagePackReader reader, IInvoca
return new InvocationBindingFailureMessage(invocationId, target, ExceptionDispatchInfo.Capture(ex));
}
- string[] streams = null;
+ string[]? streams = null;
// Previous clients will send 5 items, so we check if they sent a stream array or not
if (itemCount > 5)
{
@@ -103,7 +103,7 @@ private HubMessage CreateStreamInvocationMessage(ref MessagePackReader reader, I
var invocationId = ReadInvocationId(ref reader);
var target = ReadString(ref reader, "target");
- object[] arguments = null;
+ object[] arguments;
try
{
var parameterTypes = binder.GetParameterTypes(target);
@@ -114,7 +114,7 @@ private HubMessage CreateStreamInvocationMessage(ref MessagePackReader reader, I
return new InvocationBindingFailureMessage(invocationId, target, ExceptionDispatchInfo.Capture(ex));
}
- string[] streams = null;
+ string[]? streams = null;
// Previous clients will send 5 items, so we check if they sent a stream array or not
if (itemCount > 5)
{
@@ -148,8 +148,8 @@ private CompletionMessage CreateCompletionMessage(ref MessagePackReader reader,
var invocationId = ReadInvocationId(ref reader);
var resultKind = ReadInt32(ref reader, "resultKind");
- string error = null;
- object result = null;
+ string? error = null;
+ object? result = null;
var hasResult = false;
switch (resultKind)
@@ -198,7 +198,7 @@ private CloseMessage CreateCloseMessage(ref MessagePackReader reader, int itemCo
return new CloseMessage(error, allowReconnect);
}
- private Dictionary ReadHeaders(ref MessagePackReader reader)
+ private Dictionary? ReadHeaders(ref MessagePackReader reader)
{
var headerCount = ReadMapLength(ref reader, "headers");
if (headerCount > 0)
@@ -219,10 +219,10 @@ private Dictionary ReadHeaders(ref MessagePackReader reader)
}
}
- private string[] ReadStreamIds(ref MessagePackReader reader)
+ private string[]? ReadStreamIds(ref MessagePackReader reader)
{
var streamIdCount = ReadArrayLength(ref reader, "streamIds");
- List streams = null;
+ List? streams = null;
if (streamIdCount > 0)
{
@@ -264,7 +264,7 @@ private object[] BindArguments(ref MessagePackReader reader, IReadOnlyList
protected abstract object DeserializeObject(ref MessagePackReader reader, Type type, string field);
- private T ApplyHeaders(IDictionary source, T destination) where T : HubInvocationMessage
+ private T ApplyHeaders(IDictionary? source, T destination) where T : HubInvocationMessage
{
if (source != null && source.Count > 0)
{
@@ -374,10 +374,18 @@ private void WriteInvocationMessage(InvocationMessage message, ref MessagePackWr
writer.Write(message.InvocationId);
}
writer.Write(message.Target);
- writer.WriteArrayHeader(message.Arguments.Length);
- foreach (var arg in message.Arguments)
+
+ if (message.Arguments is null)
{
- WriteArgument(arg, ref writer);
+ writer.WriteArrayHeader(0);
+ }
+ else
+ {
+ writer.WriteArrayHeader(message.Arguments.Length);
+ foreach (var arg in message.Arguments)
+ {
+ WriteArgument(arg, ref writer);
+ }
}
WriteStreamIds(message.StreamIds, ref writer);
@@ -392,10 +400,17 @@ private void WriteStreamInvocationMessage(StreamInvocationMessage message, ref M
writer.Write(message.InvocationId);
writer.Write(message.Target);
- writer.WriteArrayHeader(message.Arguments.Length);
- foreach (var arg in message.Arguments)
+ if (message.Arguments is null)
{
- WriteArgument(arg, ref writer);
+ writer.WriteArrayHeader(0);
+ }
+ else
+ {
+ writer.WriteArrayHeader(message.Arguments.Length);
+ foreach (var arg in message.Arguments)
+ {
+ WriteArgument(arg, ref writer);
+ }
}
WriteStreamIds(message.StreamIds, ref writer);
@@ -410,7 +425,7 @@ private void WriteStreamingItemMessage(StreamItemMessage message, ref MessagePac
WriteArgument(message.Item, ref writer);
}
- private void WriteArgument(object argument, ref MessagePackWriter writer)
+ private void WriteArgument(object? argument, ref MessagePackWriter writer)
{
if (argument == null)
{
@@ -424,7 +439,7 @@ private void WriteArgument(object argument, ref MessagePackWriter writer)
protected abstract void Serialize(ref MessagePackWriter writer, Type type, object value);
- private void WriteStreamIds(string[] streamIds, ref MessagePackWriter writer)
+ private void WriteStreamIds(string[]? streamIds, ref MessagePackWriter writer)
{
if (streamIds != null)
{
@@ -493,7 +508,7 @@ private void WritePingMessage(PingMessage pingMessage, ref MessagePackWriter wri
writer.Write(HubProtocolConstants.PingMessageType);
}
- private void PackHeaders(IDictionary headers, ref MessagePackWriter writer)
+ private void PackHeaders(IDictionary? headers, ref MessagePackWriter writer)
{
if (headers != null)
{
diff --git a/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj b/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj
index 00e59a9ceef2..51d392697c8d 100644
--- a/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj
+++ b/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj
@@ -2,7 +2,7 @@
Implements the SignalR Hub Protocol using Newtonsoft.Json.
- $(DefaultNetFxTargetFramework);netstandard2.0
+ $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework);netstandard2.0
Microsoft.AspNetCore.SignalR
true
enable
@@ -21,4 +21,8 @@
+
+
+
+
diff --git a/src/SignalR/common/Shared/JsonUtils.cs b/src/SignalR/common/Shared/JsonUtils.cs
index 22a369047004..f1591cae84c1 100644
--- a/src/SignalR/common/Shared/JsonUtils.cs
+++ b/src/SignalR/common/Shared/JsonUtils.cs
@@ -143,7 +143,7 @@ public static bool ReadAsBoolean(JsonTextReader reader, string propertyName)
return Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
}
- public static string ReadAsString(JsonTextReader reader, string propertyName)
+ public static string? ReadAsString(JsonTextReader reader, string propertyName)
{
reader.Read();
diff --git a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj
index 1206aeed6833..5aedb5e72287 100644
--- a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj
+++ b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj
@@ -38,4 +38,8 @@
+
+
+
+
diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/HubMethodInvocationMessage.cs b/src/SignalR/common/SignalR.Common/src/Protocol/HubMethodInvocationMessage.cs
index cbe3f23ce30d..12dece0f5d9d 100644
--- a/src/SignalR/common/SignalR.Common/src/Protocol/HubMethodInvocationMessage.cs
+++ b/src/SignalR/common/SignalR.Common/src/Protocol/HubMethodInvocationMessage.cs
@@ -146,7 +146,7 @@ public StreamInvocationMessage(string invocationId, string target, object[] argu
/// The target method name.
/// The target method arguments.
/// The target methods stream IDs.
- public StreamInvocationMessage(string invocationId, string target, object[] arguments, string[] streamIds)
+ public StreamInvocationMessage(string invocationId, string target, object[] arguments, string[]? streamIds)
: base(invocationId, target, arguments, streamIds)
{
}
diff --git a/src/SignalR/common/SignalR.Common/src/Protocol/InvocationBindingFailureMessage.cs b/src/SignalR/common/SignalR.Common/src/Protocol/InvocationBindingFailureMessage.cs
index 0b866f871e0f..a07a32e9f5af 100644
--- a/src/SignalR/common/SignalR.Common/src/Protocol/InvocationBindingFailureMessage.cs
+++ b/src/SignalR/common/SignalR.Common/src/Protocol/InvocationBindingFailureMessage.cs
@@ -26,7 +26,7 @@ public class InvocationBindingFailureMessage : HubInvocationMessage
/// The invocation ID.
/// The target method name.
/// The exception thrown during binding.
- public InvocationBindingFailureMessage(string invocationId, string target, ExceptionDispatchInfo bindingFailure) : base(invocationId)
+ public InvocationBindingFailureMessage(string? invocationId, string target, ExceptionDispatchInfo bindingFailure) : base(invocationId)
{
Target = target;
BindingFailure = bindingFailure;