OWIN (Open Web Interface para .NET) com o ASP.NET Core
Por Steve Smith e Rick Anderson
ASP.NET Core:
- Dá suporte para OWIN (Open Web Interface para .NET).
- Tem substituições compatíveis com o .NET Core para as bibliotecas
Microsoft.Owin.*
(Katana).
O OWIN permite que os aplicativos Web sejam separados dos servidores Web. Ele define uma maneira padrão de usar o middleware em um pipeline para manipular solicitações e respostas associadas. O middleware e os aplicativos ASP.NET Core podem interoperar com aplicativos, servidores e middleware baseados no OWIN.
O OWIN fornece uma camada de desacoplamento que permite duas estruturas com modelos de objeto diferentes para ser usadas juntas. O pacote Microsoft.AspNetCore.Owin
fornece duas implementações de adaptador:
- ASP.NET Core para OWIN
- OWIN para ASP.NET Core
Isso permite que o ASP.NET Core seja hospedado em um servidor/host compatível com OWIN ou que outros componentes compatíveis com OWIN sejam executados no ASP.NET Core.
Observação
O uso desses adaptadores implica um custo de desempenho. Os aplicativos que usam somente componentes do ASP.NET Core não devem usar o pacote Microsoft.AspNetCore.Owin
ou os adaptadores.
Exibir ou baixar código de exemplo (como baixar)
Executando o middleware do OWIN no pipeline do ASP.NET Core
O suporte ao OWIN do ASP.NET Core é implantado como parte do pacote Microsoft.AspNetCore.Owin
. Importe o suporte ao OWIN para seu projeto instalando esse pacote.
O middleware do OWIN está em conformidade com a especificação do OWIN, que exige uma interface Func<IDictionary<string, object>, Task>
e a definição de chaves específicas (como owin.ResponseBody
). O seguinte middleware simples do OWIN exibe “Olá, Mundo”:
public Task OwinHello(IDictionary<string, object> environment)
{
string responseText = "Hello World via OWIN";
byte[] responseBytes = Encoding.UTF8.GetBytes(responseText);
// OWIN Environment Keys: https://owin.org/spec/spec/owin-1.0.0.html
var responseStream = (Stream)environment["owin.ResponseBody"];
var responseHeaders = (IDictionary<string, string[]>)environment["owin.ResponseHeaders"];
responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
responseHeaders["Content-Type"] = new string[] { "text/plain" };
return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length);
}
A assinatura de exemplo retorna uma Task
e aceita uma IDictionary<string, object>
, conforme solicitado pelo OWIN.
O código a seguir mostra como adicionar o middleware OwinHello
(mostrado acima) ao pipeline do ASP.NET Core com o método de extensão UseOwin
.
public void Configure(IApplicationBuilder app)
{
app.UseOwin(pipeline =>
{
pipeline(next => OwinHello);
});
}
Configure outras ações a serem executadas no pipeline do OWIN.
Observação
Os cabeçalhos de resposta devem ser modificados apenas antes da primeira gravação no fluxo de resposta.
Observação
Não é recomendado fazer várias chamadas a UseOwin
por motivos de desempenho. Os componentes do OWIN funcionarão melhor se forem agrupados.
app.UseOwin(pipeline =>
{
pipeline(next =>
{
return async environment =>
{
// Do something before.
await next(environment);
// Do something after.
};
});
});
Executar o ASP.NET Core em um servidor baseado no OWIN e usar seu suporte do WebSockets
Outro exemplo de como os recursos dos servidores baseados no OWIN podem ser aproveitados pelo ASP.NET Core é o acesso a recursos como o WebSockets. O servidor Web do OWIN para .NET usado no exemplo anterior aceita WebSockets internos, que podem ser usados por um aplicativo ASP.NET Core. O exemplo abaixo mostra um aplicativo Web simples que aceita WebSockets e repete tudo o que foi enviado ao servidor por meio de WebSockets.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
await EchoWebSocket(webSocket);
}
else
{
await next();
}
});
app.Run(context =>
{
return context.Response.WriteAsync("Hello World");
});
}
private async Task EchoWebSocket(WebSocket webSocket)
{
byte[] buffer = new byte[1024];
WebSocketReceiveResult received = await webSocket.ReceiveAsync(
new ArraySegment<byte>(buffer), CancellationToken.None);
while (!webSocket.CloseStatus.HasValue)
{
// Echo anything we receive
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, received.Count),
received.MessageType, received.EndOfMessage, CancellationToken.None);
received = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer),
CancellationToken.None);
}
await webSocket.CloseAsync(webSocket.CloseStatus.Value,
webSocket.CloseStatusDescription, CancellationToken.None);
}
}
Ambiente do OWIN
Você pode construir um ambiente do OWIN usando o HttpContext
.
var environment = new OwinEnvironment(HttpContext);
var features = new OwinFeatureCollection(environment);
Chaves do OWIN
O OWIN depende de um objeto IDictionary<string,object>
para transmitir informações em uma troca de Solicitação/Resposta HTTP. O ASP.NET Core implementa as chaves listadas abaixo. Consulte a especificação primária, extensões e as Diretrizes de chaves do OWIN e chaves comuns.
Dados de solicitação (OWIN v1.0.0)
Chave | Valor (tipo) | Descrição |
---|---|---|
owin.RequestScheme | String |
|
owin.RequestMethod | String |
|
owin.RequestPathBase | String |
|
owin.RequestPath | String |
|
owin.RequestQueryString | String |
|
owin.RequestProtocol | String |
|
owin.RequestHeaders | IDictionary<string,string[]> |
|
owin.RequestBody | Stream |
Dados de solicitação (OWIN v1.1.0)
Chave | Valor (tipo) | Descrição |
---|---|---|
owin.RequestId | String |
Opcional |
Dados de resposta (OWIN v1.0.0)
Chave | Valor (tipo) | Descrição |
---|---|---|
owin.ResponseStatusCode | int |
Opcional |
owin.ResponseReasonPhrase | String |
Opcional |
owin.ResponseHeaders | IDictionary<string,string[]> |
|
owin.ResponseBody | Stream |
Outros dados (OWIN v1.0.0)
Chave | Valor (tipo) | Descrição |
---|---|---|
owin.CallCancelled | CancellationToken |
|
owin.Version | String |
Chaves comuns
Chave | Valor (tipo) | Descrição |
---|---|---|
ssl.ClientCertificate | X509Certificate |
|
ssl.LoadClientCertAsync | Func<Task> |
|
server.RemoteIpAddress | String |
|
server.RemotePort | String |
|
server.LocalIpAddress | String |
|
server.LocalPort | String |
|
server.OnSendingHeaders | Action<Action<object>,object> |
SendFiles v0.3.0
Chave | Valor (tipo) | Descrição |
---|---|---|
sendfile.SendAsync | Consulte Assinatura do delegado | Por solicitação |
Opaque v0.3.0
Chave | Valor (tipo) | Descrição |
---|---|---|
opaque.Version | String |
|
opaque.Upgrade | OpaqueUpgrade |
Consulte Assinatura do delegado |
opaque.Stream | Stream |
|
opaque.CallCancelled | CancellationToken |
WebSocket v0.3.0
Chave | Valor (tipo) | Descrição |
---|---|---|
websocket.Version | String |
|
websocket.Accept | WebSocketAccept |
Consulte Assinatura do delegado |
websocket.AcceptAlt | Sem especificação | |
websocket.SubProtocol | String |
Consulte a etapa 5.5 RFC6455 Seção 4.2.2 |
websocket.SendAsync | WebSocketSendAsync |
Consulte Assinatura do delegado |
websocket.ReceiveAsync | WebSocketReceiveAsync |
Consulte Assinatura do delegado |
websocket.CloseAsync | WebSocketCloseAsync |
Consulte Assinatura do delegado |
websocket.CallCancelled | CancellationToken |
|
websocket.ClientCloseStatus | int |
Opcional |
websocket.ClientCloseDescription | String |
Opcional |
Recursos adicionais
- Confira a origem no GitHub para obter chaves OWIN com suporte na camada de tradução.
- Middleware
- Servidores