SignalR 必须使用适当的属性或方法修改"用户代理"标头



我有C#.NET Framework SignalR客户端应用程序&ASP.NET Core 2.1服务器。当我试图通过WebSockets启动到SignalR Hub的连接时,我遇到了异常。

System.AggregateException: Unable to connect to the server with any of the available transports.

--->
Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException: WebSockets failed: The 'User-Agent' header must be modified using the appropriate property or method. Имя параметра: name

--->
System.ArgumentException: The 'User-Agent' header must be modified using the appropriate property or method. Parameter name: name
in System.Net.WebHeaderCollection.ThrowOnRestrictedHeader(String headerName)
in System.Net.WebHeaderCollection.Set(String name, String value)
in Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport..ctor(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory, Func`1 accessTokenProvider)
in Microsoft.AspNetCore.Http.Connections.Client.Internal.DefaultTransportFactory.CreateTransport(HttpTransportType availableServerTransports)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<StartTransport>d__47.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<SelectAndStartTransport>d__44.MoveNext() 
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<SelectAndStartTransport>d__44.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<StartAsyncCore>d__41.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<StartAsync>d__40.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.<ConnectAsync>d__3.MoveNext() 
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.<ConnectAsync>d__3.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in Microsoft.AspNetCore.SignalR.Client.HubConnection.<StartAsyncCore>d__58.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in Microsoft.AspNetCore.SignalR.Client.HubConnection.<StartAsyncInner>d__50.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in Microsoft.AspNetCore.SignalR.Client.HubConnection.<StartAsync>d__49.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.GetResult()
in WPF.MainWindow.<<-ctor>b__4_4>d.MoveNext() in repository/MainWindow.xaml.cs:line 90 
(#0) Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException: WebSockets failed: The 'User-Agent' header must be modified using the appropriate property or method Parameter name: name
---> System.ArgumentException: The 'User-Agent' header must be modified using the appropriate property or method Parameter name: name
in System.Net.WebHeaderCollection.ThrowOnRestrictedHeader(String headerName)
in System.Net.WebHeaderCollection.Set(String name, String value)
in Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport..ctor(HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory, Func`1 accessTokenProvider)
in Microsoft.AspNetCore.Http.Connections.Client.Internal.DefaultTransportFactory.CreateTransport(HttpTransportType availableServerTransports)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<StartTransport>d__47.MoveNext() 
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
in Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<SelectAndStartTransport>d__44.MoveNext() 
(#1) Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException: ServerSentEvents failed: The transport is disabled by the client.<--- 
(#2) Microsoft.AspNetCore.Http.Connections.Client.TransportFailedException: LongPolling failed: The transport is disabled by the client.
<---

代码:

HubConnection Connection = new HubConnectionBuilder().WithUrl($"..", options => {
options.UseDefaultCredentials = true; 
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
options.Headers["user-agent"] = "Mozilla/5.0";
}).Build();

Task.Run(async () =>
{
try
{
await Connection.StartAsync(); // exception thrown here
}
catch (Exception ex)
{
// handle ex
}
});

我看到了这个github问题,这个问题和这个问题,但我不理解附件中的解决方案。

为了避免此异常,我需要添加什么用户代理标头?

我认为这应该有效:

using System.Reflection;
using System.Net.WebSockets;
using Microsoft.AspNetCore.Http.Connections;
// 
static void HackWebSocketConfiguration( ClientWebSocketOptions wso )
{
FieldInfo whcField = typeof(ClientWebSocketOptions).GetField( "requestHeaders", BindingFlags.Instance | BindingFlags.NonPublic );
WebHeaderCollection whc = (WebHeaderCollection)whcField.GetValue( wso );

MethodInfo awov = typeof(ClientWebSocketOptions).GetMethod( "AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic );
awov.Invoke( whc, /*headerName:*/ "User-Agent", /*headerValue:*/ "Toaster/1.0" );
}
//
HubConnection Connection = new HubConnectionBuilder()
.WithUrl( $"..", options =>
{
options.UseDefaultCredentials = true; 
options.Transports = HttpTransportType.WebSockets;
options.WebSocketConfiguration = ( ClientWebSocketOptions wso ) =>
{
HackWebSocketConfiguration( wso );
};
})
.Build();

由于这是一个.NET Framework错误,切换到.NET Core帮助我解决了这个问题。

最新更新