HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Как известно, веб-сервисы можно создавать на разных языках. Давайте напишем REST-приложение, используя<strong>.NET</strong>и<strong>Visual Studio</strong>. Результат - веб-сервис, работающий со следующим набором данных "туториалов":</p>
1 <p>Как известно, веб-сервисы можно создавать на разных языках. Давайте напишем REST-приложение, используя<strong>.NET</strong>и<strong>Visual Studio</strong>. Результат - веб-сервис, работающий со следующим набором данных "туториалов":</p>
2 <p>Будут реализованы следующие RESTful-методы: •<strong>GET Tutorial</strong>(при вызове клиент получит все доступные TutorialName); •<strong>GET Tutorial/TutorialId</strong>(при вызове клиент получит TutorialName, соответствующий переданному TutorialId); •<strong>POST Tutorial/TutorialName</strong>(при вызове клиент отправит запрос на добавление туториала с переданным TutorialName); •<strong>DELETE Tutorial/TutorialId</strong>(при вызове клиент отправит запрос на удаление туториала с TutorialName, которое соответствует переданному TutorialId).</p>
2 <p>Будут реализованы следующие RESTful-методы: •<strong>GET Tutorial</strong>(при вызове клиент получит все доступные TutorialName); •<strong>GET Tutorial/TutorialId</strong>(при вызове клиент получит TutorialName, соответствующий переданному TutorialId); •<strong>POST Tutorial/TutorialName</strong>(при вызове клиент отправит запрос на добавление туториала с переданным TutorialName); •<strong>DELETE Tutorial/TutorialId</strong>(при вызове клиент отправит запрос на удаление туториала с TutorialName, которое соответствует переданному TutorialId).</p>
3 <p>Итак, перейдём к поэтапному созданию веб-сервиса.</p>
3 <p>Итак, перейдём к поэтапному созданию веб-сервиса.</p>
4 <h2>Этап № 1</h2>
4 <h2>Этап № 1</h2>
5 <p>В первую очередь, создаём пустое ASP.NET web-приложение. Для этого открываем Visual Studio и создаём новый проект:</p>
5 <p>В первую очередь, создаём пустое ASP.NET web-приложение. Для этого открываем Visual Studio и создаём новый проект:</p>
6 <p>Далее должно появиться новое диалоговое окно.</p>
6 <p>Далее должно появиться новое диалоговое окно.</p>
7 <h2>Этап № 2</h2>
7 <h2>Этап № 2</h2>
8 <p>В открывшемся окне переходим по вкладкам C# → Веб. И выбираем опцию "Веб-приложение ASP.NET (.NET Framework)", а потом вводим нужные данные вашего проекта (название, каталог):</p>
8 <p>В открывшемся окне переходим по вкладкам C# → Веб. И выбираем опцию "Веб-приложение ASP.NET (.NET Framework)", а потом вводим нужные данные вашего проекта (название, каталог):</p>
9 <p>В итоге должно открыться окно, где можно увидеть наш проект:</p>
9 <p>В итоге должно открыться окно, где можно увидеть наш проект:</p>
10 <h2>Этап № 3</h2>
10 <h2>Этап № 3</h2>
11 <p>Теперь нам надо создать файл будущего RESTful веб-сервиса. Для этого кликаем правой кнопкой по файлу проекта Webservice.REST (также можно нажать Ctrl+Shift+A) и выбираем опции Add-&gt;new item:</p>
11 <p>Теперь нам надо создать файл будущего RESTful веб-сервиса. Для этого кликаем правой кнопкой по файлу проекта Webservice.REST (также можно нажать Ctrl+Shift+A) и выбираем опции Add-&gt;new item:</p>
12 <p>Откроется окно, где находим опцию "WCF Service (с поддержкой технологии AJAX)" и даём ей имя TutorialSevice.svc. После выбора этой опции Visual Studio создаст код, который станет основой для реализации web-сервиса. В нашем случае WCF (Windows Communication Foundation) - это библиотека, используемая для налаживания взаимодействия между приложениями посредством разных протоколов типа TCP, HTTP и HTTPS. Что касается AJAX, то эта технология позволяет асинхронно обновлять web-страницы и обмениваться небольшими объёмами данных с сервером.</p>
12 <p>Откроется окно, где находим опцию "WCF Service (с поддержкой технологии AJAX)" и даём ей имя TutorialSevice.svc. После выбора этой опции Visual Studio создаст код, который станет основой для реализации web-сервиса. В нашем случае WCF (Windows Communication Foundation) - это библиотека, используемая для налаживания взаимодействия между приложениями посредством разных протоколов типа TCP, HTTP и HTTPS. Что касается AJAX, то эта технология позволяет асинхронно обновлять web-страницы и обмениваться небольшими объёмами данных с сервером.</p>
13 <h2>Этап № 4</h2>
13 <h2>Этап № 4</h2>
14 <p>Теперь надо внести изменения в<strong>Web.config</strong>. Это конфигурационный файл, который содержит настройки, нужные для правильной работы приложения. Таким образом, наше изменение позволит приложению отправлять и принимать данные как RESTful веб-сервис.</p>
14 <p>Теперь надо внести изменения в<strong>Web.config</strong>. Это конфигурационный файл, который содержит настройки, нужные для правильной работы приложения. Таким образом, наше изменение позволит приложению отправлять и принимать данные как RESTful веб-сервис.</p>
15 <p>Открываем конфигурационный файл:</p>
15 <p>Открываем конфигурационный файл:</p>
16 <p>В открывшемся файле находим строку &lt;enableWebScript /&gt;:</p>
16 <p>В открывшемся файле находим строку &lt;enableWebScript /&gt;:</p>
17 <p>и меняем её на &lt;webHttp /&gt;:</p>
17 <p>и меняем её на &lt;webHttp /&gt;:</p>
18 <h2>Этап № 5</h2>
18 <h2>Этап № 5</h2>
19 <p>Теперь можно браться за код. Открываем файл TutorialService.svc и сначала добавим код для отображения наших данных. Для этого создаём список со строками "Queues", "Arrays" и "Stacks". Эти строки будут отражать имена доступных туториалов:</p>
19 <p>Теперь можно браться за код. Открываем файл TutorialService.svc и сначала добавим код для отображения наших данных. Для этого создаём список со строками "Queues", "Arrays" и "Stacks". Эти строки будут отражать имена доступных туториалов:</p>
20 namespace Webservice.REST { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed public class TutorialService { private static List lst = new List (new String[] {"Arrays","Queues","Stacks"});<h2>Этап № 6</h2>
20 namespace Webservice.REST { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed public class TutorialService { private static List lst = new List (new String[] {"Arrays","Queues","Stacks"});<h2>Этап № 6</h2>
21 <p>Теперь давайте напишем код для метода GET в этом же файле. Данный метод станет запускаться при каждом вызове сервиса из веб-браузера. Он будет применяться для получения доступных туториалов:</p>
21 <p>Теперь давайте напишем код для метода GET в этом же файле. Данный метод станет запускаться при каждом вызове сервиса из веб-браузера. Он будет применяться для получения доступных туториалов:</p>
22 [WebGet(UriTemplate="/Tutorial")] public String GetAllTutorial() { int count = 1st.Count; String TutorialList = ""; for (int i = 0; i &lt; count; i++) TutorialList = TutorialList + lst[i] + ","; return TutorialList; }<p>Обратите внимание на строку [WebGet(UriTemplate="/Tutorial")] - она очень важна и необходима для определения, как мы будем вызывать данный метод по URL. К примеру, если наш сервис расположен по адресу http://localhost:52645/TutorialService.svc, а в его конец мы добавим "/Tutorial" и получим http://localhost:52645/TutorialService.svc/Tutorial, то будет вызван вышенаписанный код.</p>
22 [WebGet(UriTemplate="/Tutorial")] public String GetAllTutorial() { int count = 1st.Count; String TutorialList = ""; for (int i = 0; i &lt; count; i++) TutorialList = TutorialList + lst[i] + ","; return TutorialList; }<p>Обратите внимание на строку [WebGet(UriTemplate="/Tutorial")] - она очень важна и необходима для определения, как мы будем вызывать данный метод по URL. К примеру, если наш сервис расположен по адресу http://localhost:52645/TutorialService.svc, а в его конец мы добавим "/Tutorial" и получим http://localhost:52645/TutorialService.svc/Tutorial, то будет вызван вышенаписанный код.</p>
23 <p>Атрибут WebGet - это параметр, позволяющий GetAllTutorials() быть RESTful-методом, который можно вызвать GET-запросом.</p>
23 <p>Атрибут WebGet - это параметр, позволяющий GetAllTutorials() быть RESTful-методом, который можно вызвать GET-запросом.</p>
24 <p>Что касается самого метода GetAllTutorials(), то в нём есть код, собирающий все названия туториалов и возвращающий их в одной строке.</p>
24 <p>Что касается самого метода GetAllTutorials(), то в нём есть код, собирающий все названия туториалов и возвращающий их в одной строке.</p>
25 <h2>Этап № 7</h2>
25 <h2>Этап № 7</h2>
26 <p>Идём далее. Нижеуказанный код необходим, чтобы вернуть соответствующий TutorialName при получении GET-запроса с TutorialId:</p>
26 <p>Идём далее. Нижеуказанный код необходим, чтобы вернуть соответствующий TutorialName при получении GET-запроса с TutorialId:</p>
27 [WebGet (UriTemplate = "/Tutorial/{Tutorialid}")] public String GetTutorialbyID(String Tutorialid) { int pid; Int32.TryParse(Tutorialid, out pid); return lst[pid]; }<p>Как и в примере выше, первая строка - наиболее важна, ведь она определяет, как мы будем вызывать данный метод. Если мы сделаем запрос http://localhost:52645/TutorialService.svc/Tutorial/1, то web-сервис должен вернуть TutorialName, соответствующий TutorialId с индексом 1.</p>
27 [WebGet (UriTemplate = "/Tutorial/{Tutorialid}")] public String GetTutorialbyID(String Tutorialid) { int pid; Int32.TryParse(Tutorialid, out pid); return lst[pid]; }<p>Как и в примере выше, первая строка - наиболее важна, ведь она определяет, как мы будем вызывать данный метод. Если мы сделаем запрос http://localhost:52645/TutorialService.svc/Tutorial/1, то web-сервис должен вернуть TutorialName, соответствующий TutorialId с индексом 1.</p>
28 <p>Реализует описанную логику метод GetTutorialByID(). Учтите, что мы приводим TutorialId к типу Integer. Связано это с тем, что всё, что передаётся адресную строку веб-браузера является строкой. А так как индексом списка строка быть не может, мы добавляем код, нужный для преобразования в число.</p>
28 <p>Реализует описанную логику метод GetTutorialByID(). Учтите, что мы приводим TutorialId к типу Integer. Связано это с тем, что всё, что передаётся адресную строку веб-браузера является строкой. А так как индексом списка строка быть не может, мы добавляем код, нужный для преобразования в число.</p>
29 <h2>Этап № 8</h2>
29 <h2>Этап № 8</h2>
30 <p>Теперь пришла очередь кода для метода POST, который мы будем вызывать каждый раз, когда захотим добавить строку в наш список туториалов посредством POST-запроса:</p>
30 <p>Теперь пришла очередь кода для метода POST, который мы будем вызывать каждый раз, когда захотим добавить строку в наш список туториалов посредством POST-запроса:</p>
31 [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "/Tutorial", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void AddTutorial(string str) =&gt; lst.Add(str);<p>На первой строке - атрибут WebInvoke, прикреплённый к методу, - это позволяет вызывать его посредством POST-запроса. Что касается атрибутов RequestFormat и ResponseFormat, то мы указываем для них JSON, так как именно с этим форматом функционирует RESTful веб-сервис.</p>
31 [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "/Tutorial", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void AddTutorial(string str) =&gt; lst.Add(str);<p>На первой строке - атрибут WebInvoke, прикреплённый к методу, - это позволяет вызывать его посредством POST-запроса. Что касается атрибутов RequestFormat и ResponseFormat, то мы указываем для них JSON, так как именно с этим форматом функционирует RESTful веб-сервис.</p>
32 <h2>Этап № 9</h2>
32 <h2>Этап № 9</h2>
33 <p>Что же, теперь добавим метод для работы с DELETE-запросами. Этот метод станет вызываться каждый раз, когда мы будем пытаться удалить имеющееся значение из списка посредством DELETE-запроса:</p>
33 <p>Что же, теперь добавим метод для работы с DELETE-запросами. Этот метод станет вызываться каждый раз, когда мы будем пытаться удалить имеющееся значение из списка посредством DELETE-запроса:</p>
34 [WebInvoke(Method = "DELETE", RequestFormat = WebMessageFormat.Ison, UriTemplate = "/Tutorial/{Tutorialid}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void DeleteTutorial(String Tutorialid) { int pid; Int32.TryParse(Tutorialid, out pid); 1st.RemoveAt(pid); }<p>Первая-вторая строки не имеют ничего особенного и, по сути, не отличаются от предыдущих методов, сигнализируя о том, что нижеуказанный метод станет вызываться при каждом DELETE-запросе.</p>
34 [WebInvoke(Method = "DELETE", RequestFormat = WebMessageFormat.Ison, UriTemplate = "/Tutorial/{Tutorialid}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void DeleteTutorial(String Tutorialid) { int pid; Int32.TryParse(Tutorialid, out pid); 1st.RemoveAt(pid); }<p>Первая-вторая строки не имеют ничего особенного и, по сути, не отличаются от предыдущих методов, сигнализируя о том, что нижеуказанный метод станет вызываться при каждом DELETE-запросе.</p>
35 <p>Что касается метода DeleteTutorial(), то в нём мы приводим переданный TutorialId к типу Integer, удаляя из списка соответствующий элемент.</p>
35 <p>Что касается метода DeleteTutorial(), то в нём мы приводим переданный TutorialId к типу Integer, удаляя из списка соответствующий элемент.</p>
36 <p>В результате код должен выглядеть так (без учёта элементов, бывших там изначально):</p>
36 <p>В результате код должен выглядеть так (без учёта элементов, бывших там изначально):</p>
37 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Web; using System.Text; namespace Webservice.REST { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class TutorialService { private static List&lt;string&gt; lst = new List&lt;string&gt; { "Arrays", "Queues", "Stacks" }; [WebGet(UriTemplate = "/Tutorial")] public string GetAllTutorials() =&gt; String.Join(",", lst); [WebGet(UriTemplate = "/Tutorial/{TutorialId}")] public string GetTutorialByID(string TutorialId) { int pid; if (!TryParse(TutorialId, out pid)) { throw new HttpResponseException("TutorialId must be an integer", HttpStatusCode.BadRequest); } return lst[pid]; } [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "/Tutorial", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void AddTutorial(string str) =&gt; lst.Add(str); [WebInvoke(Method = "DELETE", RequestFormat = WebMessageFormat.Json, UriTemplate = "/Tutorial/{TutorialId}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void DeleteTutorial(string TutorialId) { int pid; if (!TryParse(TutorialId, out pid)) { throw new HttpResponseException("TutorialId must be an integer", HttpStatusCode.BadRequest); } lst.RemoveAt(pid); } } }<p>Вот и всё, RESTful веб-сервис на ASP.NET создан! Теперь нужно его запустить и протестировать. Но об этом поговорим в следующий раз.</p>
37 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Web; using System.Text; namespace Webservice.REST { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class TutorialService { private static List&lt;string&gt; lst = new List&lt;string&gt; { "Arrays", "Queues", "Stacks" }; [WebGet(UriTemplate = "/Tutorial")] public string GetAllTutorials() =&gt; String.Join(",", lst); [WebGet(UriTemplate = "/Tutorial/{TutorialId}")] public string GetTutorialByID(string TutorialId) { int pid; if (!TryParse(TutorialId, out pid)) { throw new HttpResponseException("TutorialId must be an integer", HttpStatusCode.BadRequest); } return lst[pid]; } [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "/Tutorial", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void AddTutorial(string str) =&gt; lst.Add(str); [WebInvoke(Method = "DELETE", RequestFormat = WebMessageFormat.Json, UriTemplate = "/Tutorial/{TutorialId}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] public void DeleteTutorial(string TutorialId) { int pid; if (!TryParse(TutorialId, out pid)) { throw new HttpResponseException("TutorialId must be an integer", HttpStatusCode.BadRequest); } lst.RemoveAt(pid); } } }<p>Вот и всё, RESTful веб-сервис на ASP.NET создан! Теперь нужно его запустить и протестировать. Но об этом поговорим в следующий раз.</p>
38 <p><em>Источник: "<a>RESTful Web Services Tutorial with Example</a>".</em></p>
38 <p><em>Источник: "<a>RESTful Web Services Tutorial with Example</a>".</em></p>
39  
39