如何通过 signalR header 或 .net core 2.0 应用程序中的查询字符串传递一些数据
How to pass some data through signalR header or query string in .net core 2.0 app
在 .net 4.7 中使用 signalR,我们能够将两个变量从客户端应用程序传递到 signalR 服务器。这是代码片段:
public class MyHub : Hub
{
protected (string myVar1, string myVar2) GetValues() =>
(
Context.QueryString["MyVariable1"] ?? string.Empty,
Context.QueryString["MyVariable2"] ?? string.Empty,
);
}
javascript 客户端将这些变量设置如下:
$.connection.hub.qs = {'MyVariable1' : 'val1', 'MyVariable2' : 'val2'};
现在,我们正在尝试迁移到适用于 .net core 2.0 应用程序的 signalR 的 alpha 版本。障碍是我们不能再使用此方法来获取 myVar1 和 myVar2 值。不仅QueryString不可用,而且headers。克服这种情况以便能够将变量从客户端应用程序 (Typescript) 甚至 .net 核心应用程序传递到 signalR 服务器端的最佳方法是什么?
另外 - 你如何在客户端设置变量?
您可以像这样在您的中心访问 HttpContext
:
var httpContext = Context.Connection.GetHttpContext();
然后用httpContext.Request.Query["MyVariable"]
得到变量值
为 ASPNetCore 2.1 及更高版本编辑
GetHttpContext()
扩展方法可直接在 Context
对象上访问
using Microsoft.AspNetCore.Http.Connections;
....
var httpContext = Context.GetHttpContext();
晚加入此话题。我能让这个机制在 .net core 2.2 中工作的唯一方法是:
#1 添加两个 Nuget 包
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Connections" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
</ItemGroup>
#2 然后在我们的方法中 pe OnConnectedAsync():
public override Task OnConnectedAsync()
{
var httpContext = Context.GetHttpContext();
if (httpContext == null)
throw new Exception("...");
var query = httpContext.Request.Query;
var userId = query.GetQueryParameterValue<long>("Foo");
var clientId = query.GetQueryParameterValue<string>("Bar");
var connectionId = Context.ConnectionId;
[...]
return base.OnConnectedAsync();
}
#3 还介绍了一些方便的 SignalR 扩展:
static public class SignalrExtensions
{
static public HttpContext GetHttpContext(this HubCallerContext context) =>
context
?.Features
.Select(x => x.Value as IHttpContextFeature)
.FirstOrDefault(x => x != null)
?.HttpContext;
static public T GetQueryParameterValue<T>(this IQueryCollection httpQuery, string queryParameterName) =>
httpQuery.TryGetValue(queryParameterName, out var value) && value.Any()
? (T) Convert.ChangeType(value.FirstOrDefault(), typeof(T))
: default;
}
希望对您有所帮助。
在 .net 4.7 中使用 signalR,我们能够将两个变量从客户端应用程序传递到 signalR 服务器。这是代码片段:
public class MyHub : Hub
{
protected (string myVar1, string myVar2) GetValues() =>
(
Context.QueryString["MyVariable1"] ?? string.Empty,
Context.QueryString["MyVariable2"] ?? string.Empty,
);
}
javascript 客户端将这些变量设置如下:
$.connection.hub.qs = {'MyVariable1' : 'val1', 'MyVariable2' : 'val2'};
现在,我们正在尝试迁移到适用于 .net core 2.0 应用程序的 signalR 的 alpha 版本。障碍是我们不能再使用此方法来获取 myVar1 和 myVar2 值。不仅QueryString不可用,而且headers。克服这种情况以便能够将变量从客户端应用程序 (Typescript) 甚至 .net 核心应用程序传递到 signalR 服务器端的最佳方法是什么? 另外 - 你如何在客户端设置变量?
您可以像这样在您的中心访问 HttpContext
:
var httpContext = Context.Connection.GetHttpContext();
然后用httpContext.Request.Query["MyVariable"]
得到变量值
为 ASPNetCore 2.1 及更高版本编辑
GetHttpContext()
扩展方法可直接在 Context
对象上访问
using Microsoft.AspNetCore.Http.Connections;
....
var httpContext = Context.GetHttpContext();
晚加入此话题。我能让这个机制在 .net core 2.2 中工作的唯一方法是:
#1 添加两个 Nuget 包
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Connections" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
</ItemGroup>
#2 然后在我们的方法中 pe OnConnectedAsync():
public override Task OnConnectedAsync()
{
var httpContext = Context.GetHttpContext();
if (httpContext == null)
throw new Exception("...");
var query = httpContext.Request.Query;
var userId = query.GetQueryParameterValue<long>("Foo");
var clientId = query.GetQueryParameterValue<string>("Bar");
var connectionId = Context.ConnectionId;
[...]
return base.OnConnectedAsync();
}
#3 还介绍了一些方便的 SignalR 扩展:
static public class SignalrExtensions
{
static public HttpContext GetHttpContext(this HubCallerContext context) =>
context
?.Features
.Select(x => x.Value as IHttpContextFeature)
.FirstOrDefault(x => x != null)
?.HttpContext;
static public T GetQueryParameterValue<T>(this IQueryCollection httpQuery, string queryParameterName) =>
httpQuery.TryGetValue(queryParameterName, out var value) && value.Any()
? (T) Convert.ChangeType(value.FirstOrDefault(), typeof(T))
: default;
}
希望对您有所帮助。