Создаем первое приложение на NancyFX. Часть четвертая. Продолжаем работу с модулями

    В предыдущей статье Создаем первое приложение на NancyFX. Часть третья. Модули Nancy. мы познакомились с модулями Nancy. В данной статье мы продолжим их изучение.


    Как я упоминал в предыдущей статье Nancy использует свойство запроса Request.Form. Form — это DynamicDictionary значения которого берутся из тела запроса. Для того чтобы Nancy корректно распарсило значения передаваемые в теле запроса нужно верно задать Content-Type: application/x-www-form-urlencoded. Если Content-Type был задан не верно, не удивляйтесь если в качестве значений Вам будут приходить nullы. Автоматически Nancy парсит только данные в формате x-www-form-urlencoded. И так давайте попробуем создать модуль обрабатывающий Post запрос. Для начала создадим следующий класс:

    namespace NancyFxApplication
    {
        public class Dish
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public bool IsSpicy { get; set; }
        }
    }
    


    и класс

    using System.Collections.Generic;
    
    namespace NancyFxApplication
    {
        public static class DishesRepository
        {
            public static List<Dish> Dishes = new List<Dish>
                    {
                        new Dish { Id=1, Name = "Porridge", IsSpicy = false},
                        new Dish {Id = 2, Name = "Chili", IsSpicy = true},
                        new Dish {Id = 3, Name = "Icecream", IsSpicy = false}
                    };
    
            public static List<Dish> GetAllDishes()
            {
                return Dishes;
            }
    
            public static void AddDish(Dish dish)
            {
                Dishes.Add(dish);
            }
        }
    }
    


    далее определим новый модуль Nancy

    using Nancy;
    
    namespace NancyFxApplication
    {
        public class DishModule : NancyModule
        {
            public DishModule() : base("/Dish")
            {
                Post["/Add"] = ctx =>
                    {
                        var dish = new Dish {Id = Request.Form.Id, Name = Request.Form.Name, IsSpicy = Request.Form.IsSpicy};
                        DishesRepository.AddDish(dish);
                        return new Response { StatusCode = HttpStatusCode.Accepted };
                    };
    
                Get["/GetAll"] = ctx => Response.AsJson(DishesRepository.GetAllDishes());
    
            }
        }
    }
    


    Теперь после запуска приложения и перехода по роуту Dish/GetAll получаем следующий результат
    [
        {"Id":1,"Name":"Porridge","IsSpicy":false},
        {"Id":2,"Name":"Chili","IsSpicy":true},
        {"Id":3,"Name":"Icecream","IsSpicy":false}
    ]
    


    Теперь воспользуемся фиддлером и сделаем запрос Post к роуту Dish/Add



    И снова делаем Get запрос о роуту Dish/GetAll и получаем
    [
        {"Id":1,"Name":"Porridge","IsSpicy":false},
        {"Id":2,"Name":"Chili","IsSpicy":true},
        {"Id":3,"Name":"Icecream","IsSpicy":false},
        {"Id":1,"Name":"Borsh","IsSpicy":false}
    ]
    


    Как видите все работает. Однако x-www-form-urlencoded хорош только для простых форматов данных. Но для сложных данных он не подходит. Для передачи сложных форматов данных на помогут JSON и XML. Давайте модифицируем класс Dish следующим образом:

    public class Dish
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public bool IsSpicy { get; set; }
            public List<Ingridients> Ingridientses { get; set; }
        }
    


    Добавим в наш проект класс:
    public class Ingridients
        {
            public int Id { get; set; }
            public string Name { get;set; }
        }
    


    Nancy включает в себя два дессериализатора для двух семейств контент типов. Для JSONа(«application/json», «text/json», «application/vnd...+json») и XML(«application/xml»,«text/xml», «application/vnc...+xml»). Nancy также может быть расширена для работы с другими типами контентов, такими как Protocol Buffers, CSV и т.д. Вы даже можете написать свой собственный дессериализатор для своего типа контента.
    И так давайте модифицируем наш модуль таким образом чтобы он мог принимать данные в формате JSON

    using Nancy;
    using Nancy.ModelBinding;
    
    namespace NancyFxApplication
    {
        public class DishModule : NancyModule
        {
            public DishModule() : base("/Dish")
            {
                Post["/Add"] = ctx =>
                    {
                        var dish = this.Bind<Dish>();
                        DishesRepository.AddDish(dish);
                        return new Response { StatusCode = HttpStatusCode.Accepted };
                    };
    
                Get["/GetAll"] = ctx => Response.AsJson(DishesRepository.GetAllDishes());
    
            }
        }
    }
    


    Метод Bind — экстеншен методкоторый находится в пространстве имен Nancy.ModelBinding. Он позволяет Вам маппить ваш JSON на Ваш бизнес объект. Теперь если вы запустите приложение и выполните в фиддлере следующий запрос POST на роут "/Add"



    А потом выполним Dish/GetAl то получим
    [
    {"Id":1,"Name":"Porridge","IsSpicy":false,"Ingridientses":null},
    {"Id":2,"Name":"Chili","IsSpicy":true,"Ingridientses":null},
    {"Id":3,"Name":"Icecream","IsSpicy":false,"Ingridientses":null},
    {"Id":12,"Name":"Salad","IsSpicy":false,
    "Ingridientses":[{"Id":1,"Name":"Salad"}]}
    ]
    


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

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

    Подробнее
    Реклама
    Комментарии 5
    • +1
      Довольно не плохо. Я имею не замечание, а пожелание на будущее. Было бы очень интересно увидеть как написать свой Restful сервис подключить к этому angular и увидеть возможность создавать реалтайм приложение. Я знаю, что для этого есть SignalR, но мне просто интересно, есть ли что-то для NancyFx нативное.
      • 0
        За наводку на SignalR спасибо!
        Подумывал на днях использовать NancyFx для хостинга WCF службы и простых HTML-страниц в которых через XHR будут браться данные с этой WCF службы и отображаться на странице. Релтаймность тут конечное не сильная, WCF-служба будет передавать данные с различных БД.
        А так статья интересная, Спасибо!
      • 0
        И еще, могли бы вы дать ссылки на изучения материалов по NancyFX?
        • 0
          В первой статье есть ссылки материалы, к сожалению, больше ничего пока нет. Насчет приложения — в конце курса статей будет приведен пример использования Нэнси с рабочим приложением. Это будет где то недельки через две три… Спасибо за хорошие отзывы!
          • НЛО прилетело и опубликовало эту надпись здесь

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.