Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
WCF — это единая платформа Майкрософт для создания приложений, ориентированных на обслуживание. Это позволяет разработчикам создавать безопасные, надежные, трансактированные и совместимые распределенные приложения. В этой статье показано, как использовать службу Xamarin.Forms протокола SOAP (SOAP) WCF.
WCF описывает службу с различными контрактами, включая:
- Контракты данных — определяют структуры данных, которые формируют основу для содержимого в сообщении.
- Контракты сообщений — создание сообщений из существующих контрактов данных.
- Контракты сбоя — позволяют указывать пользовательские ошибки SOAP.
- Контракты служб — укажите операции, которые поддерживают службы и сообщения, необходимые для взаимодействия с каждой операцией. Они также указывают любое пользовательское поведение сбоя, которое может быть связано с операциями в каждой службе.
Существуют различия между ASP.NET веб-службами (ASMX) и WCF, но WCF поддерживает те же возможности, что и ASMX— сообщения SOAP по протоколу HTTP. Дополнительные сведения об использовании службы ASMX см. в разделе "Использование ASP.NET веб-служб (ASMX)".
Внимание
Поддержка платформы Xamarin для WCF ограничена текстовыми сообщениями SOAP по протоколу HTTP/HTTPS с помощью BasicHttpBinding класса.
Поддержка WCF требует использования средств, доступных только в среде Windows, для создания прокси-сервера и размещения TodoWCFService. Для создания и тестирования приложения iOS потребуется развернуть TodoWCFService на компьютере Windows или в качестве веб-службы Azure.
Собственные приложения Xamarin Forms обычно совместно используют код с библиотекой классов .NET Standard. Однако .NET Core в настоящее время не поддерживает WCF, поэтому общий проект должен быть устаревшей переносимой библиотекой классов. Сведения о поддержке WCF в .NET Core см. в разделе Выбор между .NET Core и платформа .NET Framework для серверных приложений.
Пример решения приложения включает службу WCF, которая может выполняться локально и показана на следующем снимке экрана:

Примечание.
В iOS 9 и более поздней версии безопасность транспорта приложений (ATS) обеспечивает безопасные подключения между интернет-ресурсами (например, сервером приложения) и приложением, тем самым предотвращая случайное раскрытие конфиденциальной информации. Так как ATS включен по умолчанию в приложениях, созданных для iOS 9, все подключения будут соответствовать требованиям безопасности ATS. Если подключения не соответствуют этим требованиям, они завершаются сбоем с исключением.
ATS можно отказаться от использования протокола и безопасного HTTPS обмена данными для интернет-ресурсов. Это можно сделать, обновив файл Info.plist приложения. Дополнительные сведения см. в разделе "Безопасность транспорта приложений".
Использование веб-службы
Служба WCF предоставляет следующие операции:
| Операция | Description | Параметры |
|---|---|---|
| GetTodoItems | Получение списка элементов задач | |
| CreateTodoItem | Создание нового элемента для выполнения | Сериализованный XML TodoItem |
| EditTodoItem | Обновление элемента задачи | Сериализованный XML TodoItem |
| DeleteTodoItem | Удаление элемента задачи | Сериализованный XML TodoItem |
Дополнительные сведения о модели данных, используемой в приложении, см. в разделе "Моделирование данных".
Прокси-сервер должен быть создан для использования службы WCF, которая позволяет приложению подключаться к службе. Прокси-сервер создается путем использования метаданных службы, определяющих методы и связанную конфигурацию службы. Эти метаданные предоставляются в виде документа языка описания веб-служб (WSDL), созданного веб-службой. Прокси-сервер можно создать с помощью поставщика ссылок веб-службы WCF в Visual Studio 2017, чтобы добавить ссылку на службу для веб-службы в библиотеку .NET Standard. Альтернативой созданию прокси-сервера с помощью поставщика ссылок на веб-службы WCF в Visual Studio 2017 является использование средства служебной программы метаданных ServiceModel (svcutil.exe). Дополнительные сведения см. в статье ServiceModel Metadata Utility Tool (Svcutil.exe).
Созданные прокси-классы предоставляют методы для использования веб-служб, использующих шаблон конструктора асинхронной модели программирования (APM). В этом шаблоне асинхронная операция реализуется в виде двух методов с именем BeginOperationName и EndOperationName, которые начинаются и заканчиваются асинхронной операцией.
Метод BeginOperationName начинает асинхронную операцию и возвращает объект, реализующий IAsyncResult интерфейс. После вызова BeginOperationName приложение может продолжить выполнение инструкций в вызывающем потоке, а асинхронная операция выполняется в потоке пула потоков.
Для каждого вызова BeginOperationName приложение также должно вызвать EndOperationName, чтобы получить результаты операции. Возвращаемое значение EndOperationName совпадает с типом, возвращаемым методом синхронной веб-службы. Например, EndGetTodoItems метод возвращает коллекцию TodoItem экземпляров. Метод EndOperationName также включает IAsyncResult параметр, который следует задать экземпляру, возвращаемого соответствующим вызовом метода BeginOperationName .
Библиотека параллельных задач (TPL) может упростить процесс использования пары методов APM begin/end, инкапсулируя асинхронные операции в одном Task объекте. Эта инкапсуляция обеспечивается несколькими перегрузками TaskFactory.FromAsync метода.
Дополнительные сведения об APM см. в статье "Асинхронное программирование модели" и TPL и традиционных платформа .NET Framework асинхронного программирования на сайте MSDN.
Создание объекта TodoServiceClient
Созданный прокси-класс предоставляет TodoServiceClient класс, который используется для взаимодействия со службой WCF по протоколу HTTP. Он предоставляет функциональные возможности для вызова методов веб-службы в качестве асинхронных операций из определяемого экземпляра службы URI. Дополнительные сведения об асинхронных операциях см. в обзоре поддержки Async.
TodoServiceClient Экземпляр объявляется на уровне класса, чтобы объект работал до тех пор, пока приложение должно использовать службу WCF, как показано в следующем примере кода:
public class SoapService : ISoapService
{
ITodoService todoService;
...
public SoapService ()
{
todoService = new TodoServiceClient (
new BasicHttpBinding (),
new EndpointAddress (Constants.SoapUrl));
}
...
}
Экземпляр TodoServiceClient настраивается с информацией о привязке и адресом конечной точки. Привязка используется для указания сведений о транспорте, кодировке и протоколе, необходимых для взаимодействия между приложениями и службами. Указывает BasicHttpBinding , что текстовые сообщения SOAP будут отправляться по протоколу транспорта HTTP. Указание адреса конечной точки позволяет приложению подключаться к разным экземплярам службы WCF, при условии, что существует несколько опубликованных экземпляров.
Дополнительные сведения о настройке ссылки на службу см. в разделе "Настройка ссылки на службу".
Создание объектов передачи данных
Пример приложения использует TodoItem класс для моделирования данных. Чтобы сохранить TodoItem элемент в веб-службе, сначала его необходимо преобразовать в созданный TodoItem прокси-сервер. Это достигается методом ToWCFServiceTodoItem , как показано в следующем примере кода:
TodoWCFService.TodoItem ToWCFServiceTodoItem (TodoItem item)
{
return new TodoWCFService.TodoItem
{
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Этот метод просто создает новый TodoWCFService.TodoItem экземпляр и задает каждому свойству идентичное свойство из экземпляра TodoItem .
Аналогичным образом, когда данные извлекаются из веб-службы, его необходимо преобразовать из созданного TodoItem прокси-сервера в TodoItem экземпляр. Это достигается с FromWCFServiceTodoItem помощью метода, как показано в следующем примере кода:
static TodoItem FromWCFServiceTodoItem (TodoWCFService.TodoItem item)
{
return new TodoItem
{
ID = item.ID,
Name = item.Name,
Notes = item.Notes,
Done = item.Done
};
}
Этот метод просто извлекает данные из созданного TodoItem прокси-сервера типа и задает его в только что созданном TodoItem экземпляре.
Извлечение данных
TodoServiceClient.EndGetTodoItems Методы TodoServiceClient.BeginGetTodoItems используются для вызова GetTodoItems операции, предоставляемой веб-службой. Эти асинхронные методы инкапсулируются в Task объекте, как показано в следующем примере кода:
public async Task<List<TodoItem>> RefreshDataAsync ()
{
...
var todoItems = await Task.Factory.FromAsync <ObservableCollection<TodoWCFService.TodoItem>> (
todoService.BeginGetTodoItems,
todoService.EndGetTodoItems,
null,
TaskCreationOptions.None);
foreach (var item in todoItems)
{
Items.Add (FromWCFServiceTodoItem (item));
}
...
}
Метод Task.Factory.FromAsync создает Task метод, который выполняет TodoServiceClient.EndGetTodoItems метод после TodoServiceClient.BeginGetTodoItems завершения метода, с null параметром, указывающим, что данные не передаются делегату BeginGetTodoItems . Наконец, значение перечисления TaskCreationOptions указывает, что поведение по умолчанию для создания и выполнения задач должно использоваться.
Метод TodoServiceClient.EndGetTodoItems возвращает ObservableCollectionTodoWCFService.TodoItem экземпляры, которые затем преобразуются в ListTodoItem экземпляры для отображения.
Создание данных
TodoServiceClient.EndCreateTodoItem Методы TodoServiceClient.BeginCreateTodoItem используются для вызова CreateTodoItem операции, предоставляемой веб-службой. Эти асинхронные методы инкапсулируются в Task объекте, как показано в следующем примере кода:
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
var todoItem = ToWCFServiceTodoItem (item);
...
await Task.Factory.FromAsync (
todoService.BeginCreateTodoItem,
todoService.EndCreateTodoItem,
todoItem,
TaskCreationOptions.None);
...
}
Метод Task.Factory.FromAsync создает Task метод, который выполняет TodoServiceClient.EndCreateTodoItem метод после TodoServiceClient.BeginCreateTodoItem завершения метода, с todoItem параметром, передаваемым в BeginCreateTodoItem делегат, чтобы указать TodoItem созданный веб-службой параметр. Наконец, значение перечисления TaskCreationOptions указывает, что поведение по умолчанию для создания и выполнения задач должно использоваться.
Веб-служба выдает исключение FaultException , если не удается создать TodoItemобъект, который обрабатывается приложением.
Обновление данных
TodoServiceClient.EndEditTodoItem Методы TodoServiceClient.BeginEditTodoItem используются для вызова EditTodoItem операции, предоставляемой веб-службой. Эти асинхронные методы инкапсулируются в Task объекте, как показано в следующем примере кода:
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
var todoItem = ToWCFServiceTodoItem (item);
...
await Task.Factory.FromAsync (
todoService.BeginEditTodoItem,
todoService.EndEditTodoItem,
todoItem,
TaskCreationOptions.None);
...
}
Метод Task.Factory.FromAsync создает Task метод, который выполняет TodoServiceClient.EndEditTodoItem метод после TodoServiceClient.BeginCreateTodoItem завершения метода, с todoItem параметром, передаваемым в BeginEditTodoItem делегат, чтобы указать TodoItem , который будет обновляться веб-службой. Наконец, значение перечисления TaskCreationOptions указывает, что поведение по умолчанию для создания и выполнения задач должно использоваться.
Веб-служба создает исключение FaultException , если не удается найти или обновить TodoItemобъект, который обрабатывается приложением.
Удаление данных
TodoServiceClient.EndDeleteTodoItem Методы TodoServiceClient.BeginDeleteTodoItem используются для вызова DeleteTodoItem операции, предоставляемой веб-службой. Эти асинхронные методы инкапсулируются в Task объекте, как показано в следующем примере кода:
public async Task DeleteTodoItemAsync (string id)
{
...
await Task.Factory.FromAsync (
todoService.BeginDeleteTodoItem,
todoService.EndDeleteTodoItem,
id,
TaskCreationOptions.None);
...
}
Метод Task.Factory.FromAsync создает Task метод, который выполняет TodoServiceClient.EndDeleteTodoItem метод после TodoServiceClient.BeginDeleteTodoItem завершения метода, с id параметром, передаваемым в BeginDeleteTodoItem делегат, чтобы указать TodoItem удаление веб-службой. Наконец, значение перечисления TaskCreationOptions указывает, что поведение по умолчанию для создания и выполнения задач должно использоваться.
Веб-служба создает исключение FaultException , если не удается найти или удалить TodoItemобъект, который обрабатывается приложением.
Настройка удаленного доступа к IIS Express
В Visual Studio 2017 или Visual Studio 2019 вы сможете протестировать приложение UWP на компьютере без дополнительной настройки. Для тестирования клиентов Android и iOS могут потребоваться дополнительные действия, описанные в этом разделе. Дополнительные сведения см. в разделе Подключение локальных веб-служб из симуляторов iOS и эмуляторов Android.
По умолчанию СЛУЖБА IIS Express будет отвечать только на запросы localhost. Удаленные устройства (например, устройство Android, i Телефон или даже симулятор) не будут иметь доступа к локальной службе WCF. Вам потребуется знать IP-адрес рабочей станции Windows 10 в локальной сети. В этом примере предположим, что у рабочей станции есть IP-адрес 192.168.1.143. Ниже описано, как настроить Windows 10 и IIS Express для приема удаленных подключений и подключения к службе с физического или виртуального устройства:
Добавьте исключение в брандмауэр Windows. Необходимо открыть порт через брандмауэр Windows, который приложения в подсети могут использовать для взаимодействия со службой WCF. Создайте правило для входящего трафика, открывающее порт 49393 в брандмауэре. В командной строке администрирования выполните следующую команду:
netsh advfirewall firewall add rule name="TodoWCFService" dir=in protocol=tcp localport=49393 profile=private remoteip=localsubnet action=allowНастройка IIS Express для принятия удаленных подключений. Вы можете настроить IIS Express, изменив файл конфигурации для IIS Express в [каталоге решения].vs\config\applicationhost.config.
siteНайдите элемент с именемTodoWCFService. Он должен выглядеть примерно так:<site name="TodoWCFService" id="2"> <application path="/" applicationPool="Clr4IntegratedAppPool"> <virtualDirectory path="/" physicalPath="C:\Users\tom\TodoWCF\TodoWCFService\TodoWCFService" /> </application> <bindings> <binding protocol="http" bindingInformation="*:49393:localhost" /> </bindings> </site>Необходимо добавить два
bindingэлемента, чтобы открыть порт 49393 для внешнего трафика и эмулятора Android. Привязка использует формат, определяющий[IP address]:[port]:[hostname]способ реагирования IIS Express на запросы. Внешние запросы будут иметь имена узлов, которые должны быть указаны в качествеbindingимени. Добавьте следующий XML-код вbindingsэлемент, заменив IP-адрес собственным IP-адресом:<binding protocol="http" bindingInformation="*:49393:192.168.1.143" /> <binding protocol="http" bindingInformation="*:49393:127.0.0.1" />После внесения изменений
bindingsэлемент должен выглядеть следующим образом:<site name="TodoWCFService" id="2"> <application path="/" applicationPool="Clr4IntegratedAppPool"> <virtualDirectory path="/" physicalPath="C:\Users\tom\TodoWCF\TodoWCFService\TodoWCFService" /> </application> <bindings> <binding protocol="http" bindingInformation="*:49393:localhost" /> <binding protocol="http" bindingInformation="*:49393:192.168.1.143" /> <binding protocol="http" bindingInformation="*:49393:127.0.0.1" /> </bindings> </site>Внимание
По умолчанию СЛУЖБА IIS Express не будет принимать подключения из внешних источников по соображениям безопасности. Чтобы включить подключения с удаленных устройств, необходимо запустить IIS Express с разрешениями Администратор istrative. Самый простой способ сделать это — запустить Visual Studio 2017 с разрешениями Администратор istrative. При запуске TodoWCFService будет запускаться СЛУЖБА IIS Express с Администратор istrative разрешения.
После выполнения этих действий вы сможете запустить TodoWCFService и подключиться с других устройств в подсети. Это можно проверить, запустив приложение и посещая
http://localhost:49393/TodoService.svcего. Если при посещении этого URL-адреса возникает ошибка с неправильным запросом, возможно,bindingsв конфигурации IIS Express (запрос достигает IIS Express, но отклоняется). Если возникает другая ошибка, возможно, приложение не запущено или брандмауэр настроен неправильно.Чтобы разрешить службам IIS Express работать и обслуживать службу, отключите параметр "Изменить и продолжить" в веб-отладчиках> свойств > проекта.
Настройте устройства конечной точки, используемые для доступа к службе. Этот шаг включает настройку клиентского приложения, работающего на физическом или эмулированном устройстве, для доступа к службе WCF.
Эмулятор Android использует внутренний прокси-сервер, который запрещает эмулятору напрямую получать доступ к адресу хост-компьютера
localhost. Вместо этого адрес10.0.2.2эмулятораlocalhostнаправляется на главный компьютер через внутренний прокси-сервер. Эти прокси-запросы будут иметь127.0.0.1имя узла в заголовке запроса, поэтому вы создали привязку IIS Express для этого имени узла в описанных выше шагах.Симулятор iOS запускается на узле сборки Mac, даже если вы используете удаленный симулятор iOS для Windows. Сетевые запросы от симулятора будут иметь IP-адрес рабочей станции в локальной сети в качестве имени узла (в этом примере это
192.168.1.143так, но фактический IP-адрес, скорее всего, будет отличаться). Поэтому вы создали привязку IIS Express для этого имени узла, выполнив описанные выше действия.Убедитесь,
SoapUrlчто свойство в файле Constants.cs в проекте TodoWCF (переносимое) имеет значения, правильные для вашей сети:public static string SoapUrl { get { var defaultUrl = "http://localhost:49393/TodoService.svc"; if (Device.RuntimePlatform == Device.Android) { defaultUrl = "http://10.0.2.2:49393/TodoService.svc"; } else if (Device.RuntimePlatform == Device.iOS) { defaultUrl = "http://192.168.1.143:49393/TodoService.svc"; } return defaultUrl; } }После настройки Constants.cs с соответствующими конечными точками вы сможете подключиться к TodoWCFService, работающей на рабочей станции Windows 10 с физических или виртуальных устройств.