HttpContext与HttpListenerContext AcceptWebSocketRequest无法强制转换
本文关键字:转换 HttpListenerContext AcceptWebSocketRequest HttpContext | 更新日期: 2024-10-22 01:19:42
我正在尝试使用HttpContextBase
在HttpListener
和HttpHandler
之间共享代码。HttpContextWrapper
已经提供了,但我必须制作自己的HttpListenerContextWrapper
,这很容易,直到我到达AcceptWebSocketRequest
。问题是HttpContextBase.AcceptWebSocketRequest
中的回调类型是Func<AspNetWebSocketContext, Task>
而不是Func<WebSocketContext, Task>
,我很难在派生类中转换它。
public class HttpListenerContextWrapper : HttpContextBase
{
private HttpListenerContext _context;
public HttpListenerContextWrapper(HttpListenerContext context)
{
_context = context;
}
public override async void AcceptWebSocketRequest(Func<AspNetWebSocketContext, Task> callback)
{
// can't implicitly convert HttpListenerWebSocketContext to AspNetWebSocketContext..
await callback(await _context.AcceptWebSocketAsync(null));
// throws at runtime..
await callback((AspNetWebSocketContext)(WebSocketContext)await _context.AcceptWebSocketAsync(null));
// throws at runtime..
await ((Func<WebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null));
// throws at runtime..
await ((Func<HttpListenerWebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null))
}
// no suitable method found to override..
public override async void AcceptWebSocketRequest(Func<WebSocketContext, Task> callback)
{
运行时异常总是:Unable to cast object of type Func<AspNetWebSocketContext,Task> to type Func<WebSocketContext,Task>
..at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4
调用AcceptWebSocketRequest
的代码类型为WebSocketContext
,直接使用HttpContext
或HttpListenerContext
时效果良好。有没有办法创建一个兼容的回调?或者有更好的方法来抽象HttpContext
和HttpListenerContext
吗?
如果我复制HttpContextBase
的代码并将类型更改为WebSocketContext
,一切都会正常工作,但我不想在我的项目中保留HttpContextBase
和HttpContextWrapper
的屠宰副本。
edit:这是使用该方法的代码。
private async Task ProcessRequestAsync(HttpContextBase context)
{
if (context.IsWebSocketRequest)
await context.AcceptWebSocketRequest(HandleWebsocketRequest);
...
private async Task HandleWebsocketRequest(WebSocketContext context)
{
...
如果要将Func<WebSocketContext, Task>
传递到Func<AspNetWebSocketContext, Task>
参数中,然后将其强制转换回Func<WebSocketContext, Task>
,以便可以传递HttpListenerWebSocketContext
,则需要在创建委托时具体说明该类型。
如果让编译器推断它将创建一个不能接受HttpListenerWebSocketContext
的Func<AspNetWebSocketContext, Task>
委托。
所以不是:
await context.AcceptWebSocketRequest(HandleWebsocketRequest);
您需要:
Func<WebSocketContext, Task> action = HandleWebsocketRequest;
await context.AcceptWebSocketRequest(action);
在AcceptWebSocketRequest
中,您需要将其投射回去:
await ((Func<WebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null));
但是,这是非常危险和糟糕的设计,因为callback
参数的类型是Func<AspNetWebSocketContext, Task>
,并且不能保证所有调用方都会发送Func<WebSocketContext, Task>
而不是Func<AspNetWebSocketContext, Task>
作为参数。