Открытый веб-интерфейс для .NET (OWIN) в ASP.NET Core
Авторы: Стив Смит (Steve Smith) и Рик Андерсон (Rick Anderson)
ASP.NET Core:
- поддерживает открытый веб-интерфейс для .NET (OWIN);
- имеет совместимые с .NET Core замены для библиотек
Microsoft.Owin.*
(Katana).
OWIN позволяет ослабить зависимость веб-приложений от веб-сервера. Он определяет стандартный способ использования ПО промежуточного в конвейере для обработки запросов и связанных с ними откликов. Приложения ASP.NET Core и ПО промежуточного слоя могут взаимодействовать с приложениями, серверами и ПО промежуточного слоя, основанными на OWIN.
OWIN обеспечивает разделительный уровень, позволяющий совместно использовать две платформы с разнородными объектными моделями. Пакет Microsoft.AspNetCore.Owin
содержит две реализации адаптера:
- ASP.NET Core в OWIN
- OWIN в ASP.NET Core
Это позволяет размещать ASP.NET Core поверх сервера или узла, совместимого с OWIN, а также запускать другие совместимые с OWIN компоненты поверх ASP.NET Core.
Примечание.
Использование этих адаптеров сопряжено с потерями производительности. Приложениям, использующим только компоненты ASP.NET Core, не следует использовать адаптеры или пакет Microsoft.AspNetCore.Owin
.
Просмотреть или скачать образец кода (описание загрузки)
Выполнение ПО промежуточного слоя OWIN в конвейере ASP.NET Core
Поддержка OWIN для ASP.NET Core развертывается в составе пакета Microsoft.AspNetCore.Owin
. Вы можете импортировать поддержку OWIN в проект, установив этот пакет.
ПО промежуточного слоя OWIN соответствует спецификации OWIN, где требуется задать интерфейс Func<IDictionary<string, object>, Task>
и определенные ключи (такие как owin.ResponseBody
). Следующее простое ПО промежуточного слоя OWIN отображает сообщение "Hello World":
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);
}
Сигнатура примера возвращает Task
и принимает IDictionary<string, object>
, как того требует OWIN.
Приведенный ниже код показывает, как добавить ПО промежуточного слоя OwinHello
(показано выше) в конвейер ASP.NET Core с помощью метода расширения UseOwin
.
public void Configure(IApplicationBuilder app)
{
app.UseOwin(pipeline =>
{
pipeline(next => OwinHello);
});
}
В конвейере OWIN можно настроить и другие действия.
Примечание.
Заголовки отклика можно изменять только до первой записи в поток отклика.
Примечание.
Из соображений производительности не рекомендуется выполнять несколько вызовов UseOwin
. Компоненты OWIN лучше всего работают, когда сгруппированы друг с другом.
app.UseOwin(pipeline =>
{
pipeline(next =>
{
return async environment =>
{
// Do something before.
await next(environment);
// Do something after.
};
});
});
Запуск ASP.NET Core на основанном на OWIN сервере и использование его поддержки WebSocket
Другим примером того, как ASP.NET Core может использовать функции сервера на основе OWIN, является доступ к таким функциям, как WebSocket. Веб-сервер .NET OWIN, используемый в предыдущем примере, поддерживает встроенные webSockets, которые могут использоваться приложением ASP.NET Core. В приведенном ниже примере показано простое веб-приложение, поддерживающее WebSockets и отправляемое на сервер все, отправленное через 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);
}
}
Среда OWIN
Вы можете создать среду OWIN с помощью HttpContext
.
var environment = new OwinEnvironment(HttpContext);
var features = new OwinFeatureCollection(environment);
Ключи OWIN
OWIN использует объект IDictionary<string,object>
для передачи сведений через систему обмена запросами и откликами HTTP. ASP.NET Core реализует указанные ниже ключи. См. основную спецификацию, расширения, а также статью Рекомендации по ключам OWIN и общие ключи.
Данные запроса (OWIN версии 1.0.0)
Ключ | Значение (тип) | Description |
---|---|---|
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 |
Данные запроса (OWIN версии 1.1.0)
Ключ | Значение (тип) | Description |
---|---|---|
owin.RequestId | String |
Необязательно |
Данные отклика (OWIN версии 1.0.0)
Ключ | Значение (тип) | Description |
---|---|---|
owin.ResponseStatusCode | int |
Необязательно |
owin.ResponseReasonPhrase | String |
Необязательно |
owin.ResponseHeaders | IDictionary<string,string[]> |
|
owin.ResponseBody | Stream |
Другие данные (OWIN версии 1.0.0)
Ключ | Значение (тип) | Description |
---|---|---|
owin.CallCancelled | CancellationToken |
|
owin.Version | String |
Общие ключи
Ключ | Значение (тип) | Description |
---|---|---|
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 версии 0.3.0
Ключ | Значение (тип) | Description |
---|---|---|
sendfile.SendAsync | См. описание сигнатуры делегата | Для каждого запроса |
Opaque версии 0.3.0
Ключ | Значение (тип) | Description |
---|---|---|
opaque.Version | String |
|
opaque.Upgrade | OpaqueUpgrade |
См. описание сигнатуры делегата |
opaque.Stream | Stream |
|
opaque.CallCancelled | CancellationToken |
WebSocket версии 0.3.0
Ключ | Значение (тип) | Description |
---|---|---|
websocket.Version | String |
|
websocket.Accept | WebSocketAccept |
См. описание сигнатуры делегата |
websocket.AcceptAlt | Нет в спецификации | |
websocket.SubProtocol | String |
См. раздел 4.2.2 RFC6455, шаг 5.5 |
websocket.SendAsync | WebSocketSendAsync |
См. описание сигнатуры делегата |
websocket.ReceiveAsync | WebSocketReceiveAsync |
См. описание сигнатуры делегата |
websocket.CloseAsync | WebSocketCloseAsync |
См. описание сигнатуры делегата |
websocket.CallCancelled | CancellationToken |
|
websocket.ClientCloseStatus | int |
Необязательно |
websocket.ClientCloseDescription | String |
Необязательно |
Дополнительные ресурсы
- См. источник на GitHub для ключей OWIN, поддерживаемых на уровне перевода.
- ПО промежуточного слоя
- Servers
ASP.NET Core