ASP.NET Web API и Kendo UI Grid - Андрей Моряков

ASP.NET Web API и Kendo UI Grid

Добавлено: 28 Января 2018 в 05:09,  Категория: ASP.NET

Если вы хотите делать современный Web applications, то уже пора посмотреть в сторону Web API . По Web API много статей в Интернете например - на metanit. По всему по этому, я не буду рассказывать разжёвывать работу Web API, а просто покажу как сделать ваше приложение, уже клиентское, приложение ещё лучше с помощью Kendo UI Grid. Сегодня мы увидим как вообще использовать Kendo UI Grid.


Go

Нам нужен контроллер, который способен:
  • возвращать список записей из базы данных (или откуда угодно)- удалять записи
  • обновлять
  • добавлять запись.

Я приведу пример метода контроллера, который возвращает список сущностей. К этому методу будет обращаться наша Kendo UI таблица. Точнее она будет обращаться к контролеру, а контроллер сам поймет, что нам нужно вызвать метод GetUsers.

public async Task<List<dynamic>> GetUsers()
        {
       using(var db = new ApplicationDbContext())
                                      {
                                          var users = db.Users.ToList();
                                          var modelView = new List<dynamic>();
                                          users.ForEach(el=>modelView.Add(new
                                          {
                                              Id = el.Id,
                                              Name = el.Name,
                                              SurName = el.SurName,
                                              Adress = el.Adress,
                                              Email = el.Email
                                          }));
                                          return modelView;
                                      }
 
        }

Начиная с конструкции csharp using(ApplicationDbContext db = new ApplicationDbContext()) мы извлекаем нужные нам записи из базы данных. Метод GetUsers возвращает список пользователей из базы данных, так же нам нужны другие методы: обновления, добавления, удаления. Поэтому ниже я приведу полный контроллер:

public class UserController : ApiController
    {
        private ApplicationDbContext db = new ApplicationDbContext();
        // GET: api/User/5
        public async Task<IHttpActionResult> GetUser(string id)
        {
            ApplicationUser applicationUser = db.Users.Find(id);
            if (applicationUser == null)
            {
                return NotFound();
            }
            return Ok(applicationUser);
        }
        
        [HttpPut]
        public async Task<IHttpActionResult> UpdateUser([FromUri]ApplicationUser applicationUser)
        {
            db.Entry(applicationUser).State = EntityState.Modified;
            await db.SaveChangesAsync();
            return StatusCode(HttpStatusCode.NoContent);
        }
 
       [HttpPost]
        public async Task<IHttpActionResult> CreateUser(ApplicationUser applicationUser)
        {
            db.Users.Add(applicationUser);
            return CreatedAtRoute("DefaultApi", new { id = applicationUser.Id }, applicationUser);
        }
        
        [ResponseType(typeof(ApplicationUser))]
        [HttpDelete]
        public async Task<IHttpActionResult> DeleteUser(string Id)
        {
            db.Users.Remove(applicationUser);
            await db.SaveChangesAsync();
            return Ok(applicationUser);
        }
    }

В коде я оставил только бизнес логику, чтобы сконцентрировать внимание на главном. Каждый метод класса UserController соответствует методам HTTP.

  • GET (получить),
  • PUT (Изменить),
  • POST (добавить),
  • DELETE (удалить). Именно поэтому мы пометили каждое действие контроллера аттрибутом котоырй определяет какой HTTP запрос он обрабатывает, например [HttpPost] Поэтому давайте перейдем к разработке клиентской части с использованием Kend UI Grid.

Разработка и настройка клиентской части (FrontEnd)

Сейчас мы будем работать с HTML но модуль Kendo UI Grid есть даже для WPF, поэтому FrontEnd может быть даже обычным приложением разработанном на языке C#. И так подключите нужные, для Kend UI Grid, скрипты и стили на страницу:

 <!--Kendo UI start-->
    <link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.3.1111/styles/kendo.common-bootstrap.min.css" />
    <link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.3.1111/styles/kendo.bootstrap.min.css" />
    <script src="//kendo.cdn.telerik.com/2015.3.1111/js/kendo.all.min.js"></script>
    <!--Kendo UI end-->

На странице объявите элемент, который будет нашей таблицей

<div id="grid"></div>

Теперь создайте файл *.js в котором будет следующий javascript код. Он будет настраивать поведение таблицы, а так-же загружать данные с сервера и отображать

function obj_to_query(data) {//Функция преобразующая объект в строку запроса
    var url = '';
    for (var prop in data) {
        url += encodeURIComponent(prop) + '=' +
            encodeURIComponent(data[prop]) + '&';
    }
    return url.substring(0, url.length - 1);
}
 
$(document).ready(function () {
    var crudServiceBaseUrl = "/api/User/", //Имя нашего контроллера (в соответствие с маршрутом настроенным на сервере
        dataSource//Переменная, с помощью которой будут производиться все манипуляции с данными
        = new kendo.data.DataSource({
            transport: {
                read: {//Показываем как загружать данные
                    url: crudServiceBaseUrl,//Ссылка откуда загружать данные. Мы лишь обращаемся к контроллеру
                    //так как в типе запроса мы указали GET то контроллер сам поймет в какой метод передать запрос,
                     //поэтому явно указывать его не нужно,
                    //Да мы и не знаем как он называется на сервере, нам это не важно.
                    //В контроллере UserController будет вызыван метод GetUsers
                    dataType: "json",
                    type: "GET"
                },
                update: {
                    url: function (options) {
                        return crudServiceBaseUrl + "?" + obj_to_query(options.models[0]); //формируем запрос для обновления сущности,
                        //в options.models[0] находится сущность, которую редактирует пользователь
                        //options.models[0] это javascript объект,
                        //его мы предварительно преобразуем в параметры которые можно передать в строке URL
                        //Так же для этого нам нужно правильно настроить метод контроллера и маршруты
                    },
                    dataType: "json",
                    type: "PUT"
                },
                destroy: {
                    url: function (options) {
                        return crudServiceBaseUrl + "?" + obj_to_query(options.models[0]);//Формируем запрос для удаления
                    },
                    dataType: "json",
                    type: "DELETE"
                },
                create: {
                    url: crudServiceBaseUrl,//Запрос для создания новой сущности, но я не использую его в своем проекте
                    dataType: "json",
                    type: "POST",
                    processData: false
                },
                parameterMap: function (options, operation) {//Когда мы удаляем или редактируем некую сущность выполняется эта функция
                    if (operation !== "read" && options.models) {
                        //В options находится объект который мы изменили или хотим удалить
                        return options;
                    }
                }
            },
            batch: true,//Ниже уже дополнительные настройки
            pageSize: 20,
            schema: {
                model: {
                    id: "Id",
                    fields: {
                        Id: {
                            editable: false,
                            nullable: true
                        },
                        Name: {//Тут мы перечисляем какие поля присутствуют в объекте, который передаст сервер
                            type: "string"
                        },
                        SurName: {
                            type: "string"
                        },
                        Adress: {
                            type: "string"
                        },
                        Email: {
                            type: "string"
                        }
                    }
                }
            }
        });
 
    $("#grid").kendoGrid({
        dataSource: dataSource,
        pageable: true,
        groupable: true,
        sortable: true,
        //height: 550,
        //toolbar: ["create"], //Кнопка для создания сущностей
        columns: [//Производим настройку полей, например можем установить валидацию
            //"Id",
            {
                field: "Name",
                title: "Имя",
                width: "120px"
            }, {
                field: "SurName",
                title: "Фамлия",
                width: "120px"
            }, {
                field: "Adress",
                title: "Адрес",
                width: "120px"
            }, {
                field: "Email",
                title: "Почта",
                width: "120px"
            }, {
                command: ["edit", "destroy"],//Добавляем кнопки удаления и редактирования
                title: "&nbsp;",
                width: "250px"
            }
        ],
        editable: "inline"//режим редактирования
    });
});

csHTML страница


@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <title>Представьтесь</title>
    <meta charset="utf-8" />
 
    <!--Kendo UI start-->
    <style>
        html {
            font-size: 14px;
            font-family: Arial, Helvetica, sans-serif;
        }
    </style>
    <link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.3.1111/styles/kendo.common-bootstrap.min.css" />
    <link rel="stylesheet" href="//kendo.cdn.telerik.com/2015.3.1111/styles/kendo.bootstrap.min.css" />
    <script src="//kendo.cdn.telerik.com/2015.3.1111/js/kendo.all.min.js"></script>
    <!--Kendo UI end-->
 
   
</head>
<body style="background-color: #fff;">
        <div id="grid"></div>
       <script src="/Scripts/Custom/userGrid.js"></script>
</body>
</html>

Вернемся к нашему серверу (BackEnd)

Обратите внимание на метод

public async Task<IHttpActionResult> UpdateUser([FromUri]ApplicationUser applicationUser)
        { ... }

Перед параметром стоит атрибут [FromUri] он нужен чтобы связать параметры из запроса с объектом типа ApplicationUser, ведь свойства этого типа совпадают с параметрами в строке запроса. А это обеспеченно соответствующей настройкой маршрута. Перейдем в файл WebApiConfig.cs в вашем проекте. Нам нужно добавить маршрут который соответствует тем параметрам которые мы хотим передавать контроллеру, например при обновлении сущности

У меня маршрут выглядит так

config.Routes.MapHttpRoute(name: "userRoute",
                    routeTemplate: "api/{controller}/{Id}/{Name}/{SurName}/{Adress}/{Email}");

Заметьте, что мы указали api/{controller}, далее параметры. Соответствующие параметры должны быть в любом запросе, который хочет соответствовать этому маршруту и свойствам типа (в моем случае) ApplicationUser.

В итоге мы получаем вот такой вот результат:

Мне в Kendo UI нравится то, что мы просто указали метод API а он уже знает что мы обновили, что удалили, что добавляем и просто передает эту информацию на сервер, а сервер уже выполняет свои серверные дела.

Комментарии ()