Использование веб-службы ASP.NET (ASMX)
ASMX предоставляет возможность создавать веб-службы, отправляющие сообщения с помощью протокола SOAP. SOAP — это независимый от платформы и независимый от языка протокол для создания и доступа к веб-службам. Потребители службы ASMX не должны знать ничего о платформе, объектной модели или языке программирования, используемом для реализации службы. Им нужно только понять, как отправлять и получать сообщения SOAP. В этой статье показано, как использовать службу SOAP ASMX из Xamarin.Forms приложения.
Сообщение SOAP — это XML-документ, содержащий следующие элементы:
- Корневой элемент с именем Envelope , который идентифицирует XML-документ как сообщение SOAP.
- Необязательный элемент Заголовка , содержащий сведения, относящиеся к приложению, такие как данные проверки подлинности. Если элемент Header присутствует, он должен быть первым дочерним элементом элемента Envelope.
- Обязательный элемент Body , содержащий сообщение SOAP, предназначенное для получателя.
- Необязательный элемент fault , используемый для указания сообщений об ошибках. Если элемент Fault присутствует, он должен быть дочерним элементом элемента Body.
SOAP может работать над множеством транспортных протоколов, включая ПРОТОКОЛ HTTP, SMTP, TCP и UDP. Однако служба ASMX может работать только по протоколу HTTP. Платформа Xamarin поддерживает стандартные реализации SOAP 1.1 по протоколу HTTP, и это включает поддержку многих стандартных конфигураций служб ASMX.
Этот пример включает мобильные приложения, которые выполняются на физических или эмулированных устройствах, а также службу ASMX, которая предоставляет методы для получения, добавления, редактирования и удаления данных. При запуске мобильных приложений они подключаются к локально размещенной службе ASMX, как показано на следующем снимке экрана:
Примечание.
В iOS 9 и более поздней версии безопасность транспорта приложений (ATS) обеспечивает безопасные подключения между интернет-ресурсами (например, сервером приложения) и приложением, тем самым предотвращая случайное раскрытие конфиденциальной информации. Так как ATS включен по умолчанию в приложениях, созданных для iOS 9, все подключения будут соответствовать требованиям безопасности ATS. Если подключения не соответствуют этим требованиям, они завершаются сбоем с исключением.
ATS можно отказаться от использования протокола и безопасного HTTPS
обмена данными для интернет-ресурсов. Это можно сделать, обновив файл Info.plist приложения. Дополнительные сведения см. в разделе "Безопасность транспорта приложений".
Использование веб-службы
Служба ASMX предоставляет следующие операции:
Операция | Description | Параметры |
---|---|---|
GetTodoItems | Получение списка элементов задач | |
CreateTodoItem | Создание нового элемента для выполнения | Сериализованный XML TodoItem |
EditTodoItem | Обновление элемента задачи | Сериализованный XML TodoItem |
DeleteTodoItem | Удаление элемента задачи | Сериализованный XML TodoItem |
Дополнительные сведения о модели данных, используемой в приложении, см. в разделе "Моделирование данных".
Создание прокси-сервера TodoService
Класс прокси-сервера, называемый TodoService
, расширяет SoapHttpClientProtocol
и предоставляет методы для взаимодействия со службой ASMX по протоколу HTTP. Прокси-сервер создается путем добавления веб-ссылки на каждый проект для конкретной платформы в Visual Studio 2019 или Visual Studio 2017. Веб-ссылка создает методы и события для каждого действия, определенного в документе языка описания веб-служб (WSDL).
Например, GetTodoItems
действие службы приводит к GetTodoItemsAsync
методу и GetTodoItemsCompleted
событию в прокси-сервере. Созданный метод имеет тип возвращаемого значения void и вызывает GetTodoItems
действие родительского SoapHttpClientProtocol
класса. Когда вызываемый метод получает ответ от службы, он запускает GetTodoItemsCompleted
событие и предоставляет данные ответа в свойстве события Result
.
Создание реализации ISoapService
Чтобы включить общий кроссплатформенный проект для работы со службой, пример определяет ISoapService
интерфейс, который следует асинхронной модели программирования задач в C#. Каждая платформа реализует ISoapService
доступ к прокси-серверу для конкретной платформы. В примере используются TaskCompletionSource
объекты для предоставления прокси-сервера в качестве асинхронного интерфейса задачи. Сведения об использовании TaskCompletionSource
приведены в реализации каждого типа действия в разделах ниже.
SoapService
Пример:
TodoService
Создает экземпляр в качестве экземпляра уровня класса- Создает коллекцию, вызываемую
Items
для храненияTodoItem
объектов - Указывает пользовательскую конечную точку для необязательного
Url
свойства вTodoService
public class SoapService : ISoapService
{
ASMXService.TodoService todoService;
public List<TodoItem> Items { get; private set; } = new List<TodoItem>();
public SoapService ()
{
todoService = new ASMXService.TodoService ();
todoService.Url = Constants.SoapUrl;
...
}
}
Создание объектов передачи данных
Пример приложения использует TodoItem
класс для моделирования данных. Чтобы сохранить TodoItem
элемент в веб-службе, сначала его необходимо преобразовать в созданный TodoItem
прокси-сервер. Это достигается методом ToASMXServiceTodoItem
, как показано в следующем примере кода:
ASMXService.TodoItem ToASMXServiceTodoItem (TodoItem item)
{
return new ASMXService.TodoItem {
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Этот метод создает новый ASMService.TodoItem
экземпляр и задает каждому свойству идентичное свойство из экземпляра TodoItem
.
Аналогичным образом, когда данные извлекаются из веб-службы, его необходимо преобразовать из созданного TodoItem
прокси-сервера в TodoItem
экземпляр. Это достигается с FromASMXServiceTodoItem
помощью метода, как показано в следующем примере кода:
static TodoItem FromASMXServiceTodoItem (ASMXService.TodoItem item)
{
return new TodoItem {
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Этот метод извлекает данные из созданного TodoItem
прокси-сервера типа и задает его в только что созданном TodoItem
экземпляре.
Извлечение данных
Интерфейс ISoapService
ожидает, RefreshDataAsync
что метод возвращает коллекцию Task
элементов. TodoService.GetTodoItemsAsync
Однако метод возвращает void. Чтобы удовлетворить шаблон интерфейса, необходимо вызвать GetTodoItemsAsync
, подождите, пока GetTodoItemsCompleted
событие будет срабатывает, и заполните коллекцию. Это позволяет возвращать допустимую коллекцию в пользовательский интерфейс.
В приведенном ниже примере создается новый TaskCompletionSource
асинхронный вызов метода RefreshDataAsync
и ожидается Task
предоставленный методом TaskCompletionSource
. При вызове обработчика TodoService_GetTodoItemsCompleted
событий он заполняет коллекцию Items
и обновляет TaskCompletionSource
:
public class SoapService : ISoapService
{
TaskCompletionSource<bool> getRequestComplete = null;
...
public SoapService()
{
...
todoService.GetTodoItemsCompleted += TodoService_GetTodoItemsCompleted;
}
public async Task<List<TodoItem>> RefreshDataAsync()
{
getRequestComplete = new TaskCompletionSource<bool>();
todoService.GetTodoItemsAsync();
await getRequestComplete.Task;
return Items;
}
private void TodoService_GetTodoItemsCompleted(object sender, ASMXService.GetTodoItemsCompletedEventArgs e)
{
try
{
getRequestComplete = getRequestComplete ?? new TaskCompletionSource<bool>();
Items = new List<TodoItem>();
foreach (var item in e.Result)
{
Items.Add(FromASMXServiceTodoItem(item));
}
getRequestComplete?.TrySetResult(true);
}
catch (Exception ex)
{
Debug.WriteLine(@"\t\tERROR {0}", ex.Message);
}
}
...
}
Дополнительные сведения см. в статье "Асинхронная модель программирования" и TPL и традиционное платформа .NET Framework асинхронное программирование.
Создание или изменение данных
При создании или изменении данных необходимо реализовать ISoapService.SaveTodoItemAsync
метод. Этот метод определяет, является ли TodoItem
новый или обновленный элемент и вызывает ли соответствующий метод в объекте todoService
. CreateTodoItemCompleted
EditTodoItemCompleted
Обработчики событий также должны быть реализованы, чтобы узнать, когда todoService
получен ответ от службы ASMX (их можно объединить в один обработчик, так как они выполняют ту же операцию). В следующем примере показаны реализации интерфейса и обработчика событий, а также TaskCompletionSource
объект, используемый для асинхронной работы:
public class SoapService : ISoapService
{
TaskCompletionSource<bool> saveRequestComplete = null;
...
public SoapService()
{
...
todoService.CreateTodoItemCompleted += TodoService_SaveTodoItemCompleted;
todoService.EditTodoItemCompleted += TodoService_SaveTodoItemCompleted;
}
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
try
{
var todoItem = ToASMXServiceTodoItem(item);
saveRequestComplete = new TaskCompletionSource<bool>();
if (isNewItem)
{
todoService.CreateTodoItemAsync(todoItem);
}
else
{
todoService.EditTodoItemAsync(todoItem);
}
await saveRequestComplete.Task;
}
catch (SoapException se)
{
Debug.WriteLine("\t\t{0}", se.Message);
}
catch (Exception ex)
{
Debug.WriteLine("\t\tERROR {0}", ex.Message);
}
}
private void TodoService_SaveTodoItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
saveRequestComplete?.TrySetResult(true);
}
...
}
Удаление данных
Для удаления данных требуется аналогичная реализация. Определите TaskCompletionSource
, реализуйте обработчик событий и ISoapService.DeleteTodoItemAsync
метод:
public class SoapService : ISoapService
{
TaskCompletionSource<bool> deleteRequestComplete = null;
...
public SoapService()
{
...
todoService.DeleteTodoItemCompleted += TodoService_DeleteTodoItemCompleted;
}
public async Task DeleteTodoItemAsync (string id)
{
try
{
deleteRequestComplete = new TaskCompletionSource<bool>();
todoService.DeleteTodoItemAsync(id);
await deleteRequestComplete.Task;
}
catch (SoapException se)
{
Debug.WriteLine("\t\t{0}", se.Message);
}
catch (Exception ex)
{
Debug.WriteLine("\t\tERROR {0}", ex.Message);
}
}
private void TodoService_DeleteTodoItemCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
deleteRequestComplete?.TrySetResult(true);
}
...
}
Тестирование веб-службы
Для тестирования физических или эмулированных устройств с локально размещенной службой требуется настраиваемая конфигурация IIS, адреса конечных точек и правила брандмауэра. Дополнительные сведения о настройке среды для тестирования см. в разделе "Настройка удаленного доступа к IIS Express". Единственное различие между тестированием WCF и ASMX — номер порта TodoService.