Вэб-приложение на Katana OWIN для уже существующего сайта

от автора

В этой статье я расскажу как применить Katana OWIN к уже существующему сайту на ASP NET, который написан с использованием WebForms, Web API и Generic Handler (*.ashx).

В сущности говоря, OWIN — это спецификация описывающая процесс обработки входящего запроса подключаемыми модулями. Каждый модуль по порядку своего следования получит запрос и будет работать с ним. По завершении он передаст запрос следующему модулю.

Для того чтобы новое вэб-приложение на OWIN смогло выполнять нужные мне базовые функции, надо подключить как минимум 3 модуля. У меня это: Nancy, Web API, SignalR.
После подключения этих модулей приложение сможет генерировать статические страницы на html (за это отвечает Nancy), делать ajax — запросы (Web API) и работать с событиями и уведомлениями в реальном времени (например чат) (за это отвечает модуль SignalR).

Так как все это должно работать под IIS, я использую реализацию спецификации OWIN Katana.

Итак, сначала надо установить все необходимое из NuGet Gallery:

Install-Package Nancy.Owin Install-Package Microsoft.AspNet.WebApi.Owin Install-Package Microsoft.AspNet.SignalR 

После установки библиотек можно приступить к написанию кода. По соглашению, для Katana нужен класс Startup. После запуска будет создан его экземпляр и вызван метод Configuration.

using Microsoft.AspNet.SignalR; using Microsoft.Owin; using Nancy; using Owin; using System.Web.Http;  [assembly: OwinStartup(typeof(test_namespace.Startup))] namespace test_namespace {     public class Startup     {         public void Configuration(IAppBuilder app)         {                   //SignalR             var hubConfiguration = new HubConfiguration();             hubConfiguration.EnableDetailedErrors = true;             app.MapSignalR(hubConfiguration);                                      //Web API             HttpConfiguration config = new HttpConfiguration();             config.MapHttpAttributeRoutes();             config.Routes.MapHttpRoute("def","api/{Controller}");             config.Formatters.Remove(config.Formatters.XmlFormatter);              app.UseWebApi(config);                          //Nancy             app.UseNancy(options =>               options.PerformPassThrough = context =>                   context.Response.StatusCode == HttpStatusCode.NotFound);         }     } } 

SignalR

Как видно из листинга, первый подключенный модуль это — SignalR. Я так же передаю дополнительные параметры, чтобы включить лог ошибок. Для этого модуля также требуется определить класс, который будет работать с уведомлениями в реальном времени.

namespace test_namespace {     public class TestHub : Hub     {         public void send_message(string message)         {              Clients.All.message_to_client(message);         }     } } 

А также код на стороне клиентов, который мы будем включать в статическую страницу, генерируемой модулем Nancy:

    <script src="/Scripts/jquery.signalR-2.0.0.min.js"></script>     <script src="/signalr/hubs"></script> 
$(function(){      var hub1 = $.connection.testHub; // замечу, что testHub с маленькой буквы.      hub1.client.message_to_client = function(s){ alert(s); }; //Функция, которую можно вызывать из TestHub     $.connection.hub.logging = true; //Включаем подробный лог     $.connection.hub.start().done(function () {          hub1.server.send_message('Hello, world!').done(function(){             console.log('сообщение было послано всем пользователям');         }); //вызываю функцию в TestHub, которая в свою очередь пошлет сообщение всем клиентам.     });  }); 

В итоге, после загрузки страницы, все клиенты получат сообщение «Hello, world!».

Web API

Переходим к определению следующего модуля, это Web API. Я также передаю в модуль дополнительные параметры, чтобы api отдавала json-строку. Теперь напишем класс контроллера:

public class TestController : ApiController {     [HttpPost]     [HttpGet]     [Route("api/all")]     public object All()     {         return new { a = 1,b = 2, c = 4 };     }      public object Get()     {         return new { a = 1, b = 3 };     }  } 

Get запросом мы получим json с двумя переменными а и b. При «post» и «get» запросе по адресу "/api/all" получим 3 переменные a, b, c.

Nancy

Далее перейдем к созданию класса для модуля генерации страниц Nancy. Я также передаю параметр, который позволит функционировать остальным страницам на моем сайте. В противном случае, если в модуле не будет найдено соответствие адресу, то клиенту придет ошибка «404 not found», несмотря на то, что, например, соответствующие .aspx страницы существуют.

public class DefNancy : NancyModule {     public TestNancy() : base("/nancy") {         Get["/"] = _ => {             var model = new { title = "Hello, world!" };             return View["testpage", model];         };     } } 

Вместе с тем, в корне я создам html страницу с именем «testpage»:

<!DOCTYPE html> <html > <head>   <title>@Model.title</title> </head>   <body> <header>       <h1>@Model.title</h1>     </header>   </body> </html> 

И, по адресу "/nancy", я получу эту созданную страницу с надписью «Hello, world!». Далее, в эту страницу я включил клиентский код, который делает ajax-запросы и уведомления в реальном времени. В итоге, была получена необходимая базовая функциональность, это — генерация страниц, ajax-запросы и «Real time pushing» уведомления.

The Katana Project — OWIN for ASP.NET — полезное видео про Katana.
Katana — проект Katana.
OWIN — проект OWIN.
SignalR — проект SignalR.
Nancy with OWIN — как работать с Nancy и OWIN
Use OWIN to Self-Host ASP.NET Web API — как работать с Web API и OWIN.

ссылка на оригинал статьи http://habrahabr.ru/post/209964/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *