我正在尝试使用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
和{{1}的屠宰副本在我的项目中。
编辑:这是使用该方法的代码。
HttpContextWrapper
答案 0 :(得分:1)
如果您想将Func<WebSocketContext, Task>
传递给Func<AspNetWebSocketContext, Task>
参数,然后将其转发回Func<WebSocketContext, Task>
,那么您可以传入HttpListenerWebSocketContext
,您需要明确说明该类型你创建了委托。
如果您让编译器推断它将创建一个无法接受Func<AspNetWebSocketContext, Task>
的{{1}}委托。
所以而不是:
HttpListenerWebSocketContext
你需要:
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>
作为论据。