使用 Windows Communication Foundation (WCF) Web 服务Consume a Windows Communication Foundation (WCF) Web Service

下载示例 下载示例Download Sample Download the sample

WCF 是 Microsoft 的统一的框架,用于构建面向服务的应用程序。它允许开发人员构建安全、 可靠、 事务处理,且可互操作分布式应用程序。本文演示如何使用 Xamarin.Forms 应用程序中的 WCF 简单对象访问协议 (SOAP) 服务。WCF is Microsoft's unified framework for building service-oriented applications. It enables developers to build secure, reliable, transacted, and interoperable distributed applications. This article demonstrates how to consume an WCF Simple Object Access Protocol (SOAP) service from a Xamarin.Forms application.

WCF 描述了具有各种不同协定的服务, 包括:WCF describes a service with a variety of different contracts including:

  • 数据协定– 定义构成对其中一条消息的内容的基础的数据结构。Data contracts – define the data structures that form the basis for the content within a message.
  • 消息协定搭配– 撰写邮件从现有数据协定。Message contracts – compose messages from existing data contracts.
  • 错误协定– 允许指定的自定义 SOAP 错误。Fault contracts – allow custom SOAP faults to be specified.
  • 服务协定– 指定服务支持的操作,这些消息所需的与每个操作进行交互。Service contracts – specify the operations that services support and the messages required for interacting with each operation. 它们还指定可以与每个服务上的操作相关联的任何自定义错误行为。They also specify any custom fault behavior that can be associated with operations on each service.

ASP.NET Web Services (.ASMX) 和 WCF 之间存在差异, 但 WCF 支持与通过 HTTP 提供的 SOAP 消息相同的功能。There are differences between ASP.NET Web Services (ASMX) and WCF, but WCF supports the same capabilities that ASMX provides – SOAP messages over HTTP. 有关使用 .ASMX 服务的详细信息, 请参阅使用 ASP.NET Web 服务 (.asmx)For more information about consuming an ASMX service, see Consume ASP.NET Web Services (ASMX).

重要

对 WCF 的 Xamarin 平台支持仅限于使用BasicHttpBinding类通过 HTTP/HTTPS 进行文本编码的 SOAP 消息。The Xamarin platform support for WCF is limited to text-encoded SOAP messages over HTTP/HTTPS using the BasicHttpBinding class.

WCF 支持需要使用仅在 Windows 环境中可用的工具来生成代理并托管 TodoWCFService。WCF support requires the use of tools only available in a Windows environment to generate the proxy and host the TodoWCFService. 生成和测试 iOS 应用需要在 Windows 计算机上部署 TodoWCFService, 或将其部署为 Azure web 服务。Building and testing the iOS app will require deploying the TodoWCFService on a Windows computer, or as an Azure web service.

Xamarin 窗体本机应用通常与 .NET Standard 类库共享代码。Xamarin Forms native apps typically share code with a .NET Standard Class Library. 但是, .NET Core 当前不支持 WCF, 因此共享项目必须是旧的可移植类库。However, .NET Core does not currently support WCF so the shared project must be a legacy Portable Class Library. 有关 .NET Core 中 WCF 支持的信息, 请参阅为服务器应用选择 .Net core 和 .NET FrameworkFor information about WCF support in .NET Core, see Choosing between .NET Core and .NET Framework for server apps.

示例应用程序解决方案包括一个可在本地运行的 WCF 服务, 如以下屏幕截图所示:The sample application solution includes a WCF service which can be run locally, and is shown in the following screenshot:

备注

在 iOS 9 及更高版本中,应用传输安全 (ATS) 强制执行安全连接之间 (例如应用程序的后端服务器) 的 internet 资源和应用程序中,从而防止意外泄露敏感信息。In iOS 9 and greater, App Transport Security (ATS) enforces secure connections between internet resources (such as the app's back-end server) and the app, thereby preventing accidental disclosure of sensitive information. 由于默认情况下构建适用于 iOS 9 应用程序中启用了 ATS,所有连接都将遵循 ATS 安全要求。Since ATS is enabled by default in apps built for iOS 9, all connections will be subject to ATS security requirements. 如果连接不能满足这些要求,它们将失败并出现异常。If connections do not meet these requirements, they will fail with an exception.

如果不能使用 ATS 可以选择退出的HTTPS协议并确保对 internet 资源的通信安全。ATS can be opted out of if it is not possible to use the HTTPS protocol and secure communication for internet resources. 这可以通过更新应用程序的实现Info.plist文件。This can be achieved by updating the app's Info.plist file. 有关详细信息请参阅应用程序传输安全For more information see App Transport Security.

使用 web 服务Consume the web service

WCF 服务提供了以下操作:The WCF service provides the following operations:

操作Operation 描述Description 参数Parameters
GetTodoItemsGetTodoItems 获取待办事项的列表Get a list of to-do items
CreateTodoItemCreateTodoItem 创建新的待办事项Create a new to-do item XML 序列化 TodoItemAn XML serialized TodoItem
EditTodoItemEditTodoItem 更新待办事项Update a to-do item XML 序列化 TodoItemAn XML serialized TodoItem
DeleteTodoItemDeleteTodoItem 删除待办事项Delete a to-do item XML 序列化 TodoItemAn XML serialized TodoItem

有关在应用程序中使用的数据模型的详细信息,请参阅为数据建模For more information about the data model used in the application, see Modeling the data.

一个代理必须生成以使用 WCF 服务,允许应用程序连接到服务。A proxy must be generated to consume a WCF service, which allows the application to connect to the service. 代理是通过使用以定义的方法和关联的服务配置的服务元数据构造的。The proxy is constructed by consuming service metadata that define the methods and associated service configuration. 此元数据中生成的 web 服务的 Web 服务描述语言 (WSDL) 文档的形式公开。This metadata is exposed in the form of a Web Services Description Language (WSDL) document that is generated by the web service. 在 Visual Studio 2017 中使用 Microsoft WCF Web Service Reference Provider,若要将 web 服务的服务引用添加到.NET Standard 库,可以生成代理。The proxy can be built by using the Microsoft WCF Web Service Reference Provider in Visual Studio 2017 to add a service reference for the web service to a .NET Standard library. 创建的代理帐户在 Visual Studio 2017 中使用 Microsoft WCF Web Service Reference Provider 的替代方法是使用 ServiceModel Metadata Utility Tool (svcutil.exe)。An alternative to creating the proxy using the Microsoft WCF Web Service Reference Provider in Visual Studio 2017 is to use the ServiceModel Metadata Utility Tool (svcutil.exe). 有关详细信息,请参阅ServiceModel Metadata Utility Tool (Svcutil.exe)For more information, see ServiceModel Metadata Utility Tool (Svcutil.exe).

生成的代理类提供用于使用 web 服务使用异步编程模型 (APM) 设计模式的方法。The generated proxy classes provide methods for consuming the web services that use the Asynchronous Programming Model (APM) design pattern. 在此模式下,异步操作实现这两个方法名为BeginOperationNameEndOperationName,其中开始和结束异步操作。In this pattern, an asynchronous operation is implemented as two methods named BeginOperationName and EndOperationName, which begin and end the asynchronous operation.

BeginOperationName方法开始异步操作并返回一个对象,实现IAsyncResult接口。The BeginOperationName method begins the asynchronous operation and returns an object that implements the IAsyncResult interface. 在调用BeginOperationName,应用程序可以继续在调用线程上执行指令,同时异步操作在线程池线程。After calling BeginOperationName, an application can continue executing instructions on the calling thread, while the asynchronous operation takes place on a thread pool thread.

每次调用BeginOperationName,应用程序还应调用EndOperationName来获取该操作的结果。For each call to BeginOperationName, the application should also call EndOperationName to get the results of the operation. 返回值EndOperationName同步 web 服务方法返回的类型相同。The return value of EndOperationName is the same type returned by the synchronous web service method. 例如,EndGetTodoItems方法返回的集合TodoItem实例。For example, the EndGetTodoItems method returns a collection of TodoItem instances. EndOperationName方法还包括IAsyncResult应设置为的对应调用返回的实例的参数BeginOperationName方法。The EndOperationName method also includes an IAsyncResult parameter that should be set to the instance returned by the corresponding call to the BeginOperationName method.

任务并行库 (TPL) 可以简化使用 APM begin/end 方法对通过封装中相同的异步操作的过程Task对象。The Task Parallel Library (TPL) can simplify the process of consuming an APM begin/end method pair by encapsulating the asynchronous operations in the same Task object. 这种封装提供的多个重载TaskFactory.FromAsync方法。This encapsulation is provided by multiple overloads of the TaskFactory.FromAsync method.

有关 APM 的详细信息请参阅异步编程模型TPL 和传统.NET Framework 异步编程MSDN 上。For more information about APM see Asynchronous Programming Model and TPL and Traditional .NET Framework Asynchronous Programming on MSDN.

创建 TodoServiceClient 对象Create the TodoServiceClient object

生成的代理类提供了TodoServiceClient类,该类用于通过 HTTP 与 WCF 服务进行通信。The generated proxy class provides the TodoServiceClient class, which is used to communicate with the WCF service over HTTP. 它提供用于调用 web 服务方法从 URI 的异步操作来标识服务实例的功能。It provides functionality for invoking web service methods as asynchronous operations from a URI identified service instance. 有关异步操作的详细信息,请参阅异步支持概述For more information about asynchronous operations, see Async Support Overview.

TodoServiceClient实例在类级别声明的以便在对象存在的只要该应用程序需要使用 WCF 服务,如下面的代码示例中所示:The TodoServiceClient instance is declared at the class-level so that the object lives for as long as the application needs to consume the WCF service, as shown in the following code example:

public class SoapService : ISoapService
{
  ITodoService todoService;
  ...

  public SoapService ()
  {
    todoService = new TodoServiceClient (
      new BasicHttpBinding (),
      new EndpointAddress (Constants.SoapUrl));
  }
  ...
}

TodoServiceClient实例配置有绑定的绑定信息以及终结点地址。The TodoServiceClient instance is configured with binding information and an endpoint address. 使用绑定指定传输、 编码和协议详细信息所需的应用程序和服务彼此通信。A binding is used to specify the transport, encoding, and protocol details required for applications and services to communicate with each other. BasicHttpBinding指定将通过 HTTP 传输协议发送文本编码的 SOAP 消息。The BasicHttpBinding specifies that text-encoded SOAP messages will be sent over the HTTP transport protocol. 指定终结点地址可以连接到 WCF 服务的不同实例应用程序,前提是有多个已发布的实例。Specifying an endpoint address enables the application to connect to different instances of the WCF service, provided that there are multiple published instances.

有关配置服务引用的详细信息,请参阅配置服务引用For more information about configuring the service reference, see Configuring the Service Reference.

创建数据传输对象Create data transfer objects

示例应用程序使用TodoItem模型数据的类。The sample application uses the TodoItem class to model data. 用于存储TodoItem中 web 服务必须首先将转换为生成的代理项TodoItem类型。To store a TodoItem item in the web service it must first be converted to the proxy generated TodoItem type. 这通过实现ToWCFServiceTodoItem方法,如下面的代码示例中所示:This is accomplished by the ToWCFServiceTodoItem method, as shown in the following code example:

TodoWCFService.TodoItem ToWCFServiceTodoItem (TodoItem item)
{
  return new TodoWCFService.TodoItem
  {
    ID = item.ID,
    Name = item.Name,
    Notes = item.Notes,
    Done = item.Done
  };
}

此方法只需创建一个新TodoWCFService.TodoItem实例,并将每个属性设置为相同的属性从TodoItem实例。This method simply creates a new TodoWCFService.TodoItem instance, and sets each property to the identical property from the TodoItem instance.

同样,当从 web 服务检索数据时,必须将它从转换生成的代理TodoItem键入到TodoItem实例。Similarly, when data is retrieved from the web service, it must be converted from the proxy generated TodoItem type to a TodoItem instance. 这通过实现FromWCFServiceTodoItem方法,如下面的代码示例中所示:This is accomplished with the FromWCFServiceTodoItem method, as shown in the following code example:

static TodoItem FromWCFServiceTodoItem (TodoWCFService.TodoItem item)
{
  return new TodoItem
  {
    ID = item.ID,
    Name = item.Name,
    Notes = item.Notes,
    Done = item.Done
  };
}

此方法只需从生成的代理中检索数据TodoItem类型并将其设置在新创建TodoItem实例。This method simply retrieves the data from the proxy generated TodoItem type and sets it in the newly created TodoItem instance.

检索数据Retrieve data

TodoServiceClient.BeginGetTodoItemsTodoServiceClient.EndGetTodoItems方法用于调用GetTodoItemsweb 服务所提供的操作。The TodoServiceClient.BeginGetTodoItems and TodoServiceClient.EndGetTodoItems methods are used to call the GetTodoItems operation provided by the web service. 这些异步方法封装在Task对象,如下面的代码示例中所示:These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

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委托。The Task.Factory.FromAsync method creates a Task that executes the TodoServiceClient.EndGetTodoItems method once the TodoServiceClient.BeginGetTodoItems method completes, with the null parameter indicating that no data is being passed into the BeginGetTodoItems delegate. 最后的值TaskCreationOptions枚举指定应使用的创建和执行任务的默认行为。Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

TodoServiceClient.EndGetTodoItems方法将返回ObservableCollectionTodoWCFService.TodoItem实例,然后将转换为ListTodoItem显示的实例。The TodoServiceClient.EndGetTodoItems method returns an ObservableCollection of TodoWCFService.TodoItem instances, which is then converted to a List of TodoItem instances for display.

创建数据Create data

TodoServiceClient.BeginCreateTodoItemTodoServiceClient.EndCreateTodoItem方法用于调用CreateTodoItemweb 服务所提供的操作。The TodoServiceClient.BeginCreateTodoItem and TodoServiceClient.EndCreateTodoItem methods are used to call the CreateTodoItem operation provided by the web service. 这些异步方法封装在Task对象,如下面的代码示例中所示:These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

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若要创建的 web 服务。The Task.Factory.FromAsync method creates a Task that executes the TodoServiceClient.EndCreateTodoItem method once the TodoServiceClient.BeginCreateTodoItem method completes, with the todoItem parameter being the data that's passed into the BeginCreateTodoItem delegate to specify the TodoItem to be created by the web service. 最后的值TaskCreationOptions枚举指定应使用的创建和执行任务的默认行为。Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

Web 服务将引发FaultException未能创建TodoItem,这由应用程序处理。The web service throws a FaultException if it fails to create the TodoItem, which is handled by the application.

更新数据Update data

TodoServiceClient.BeginEditTodoItemTodoServiceClient.EndEditTodoItem方法用于调用EditTodoItemweb 服务所提供的操作。The TodoServiceClient.BeginEditTodoItem and TodoServiceClient.EndEditTodoItem methods are used to call the EditTodoItem operation provided by the web service. 这些异步方法封装在Task对象,如下面的代码示例中所示:These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

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若要通过 web 服务进行更新。The Task.Factory.FromAsync method creates a Task that executes the TodoServiceClient.EndEditTodoItem method once the TodoServiceClient.BeginCreateTodoItem method completes, with the todoItem parameter being the data that's passed into the BeginEditTodoItem delegate to specify the TodoItem to be updated by the web service. 最后的值TaskCreationOptions枚举指定应使用的创建和执行任务的默认行为。Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

Web 服务将引发FaultException如果无法找到或更新TodoItem,这由应用程序处理。The web service throws a FaultException if it fails to locate or update the TodoItem, which is handled by the application.

删除数据Delete data

TodoServiceClient.BeginDeleteTodoItemTodoServiceClient.EndDeleteTodoItem方法用于调用DeleteTodoItemweb 服务所提供的操作。The TodoServiceClient.BeginDeleteTodoItem and TodoServiceClient.EndDeleteTodoItem methods are used to call the DeleteTodoItem operation provided by the web service. 这些异步方法封装在Task对象,如下面的代码示例中所示:These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

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要删除 web 服务。The Task.Factory.FromAsync method creates a Task that executes the TodoServiceClient.EndDeleteTodoItem method once the TodoServiceClient.BeginDeleteTodoItem method completes, with the id parameter being the data that's passed into the BeginDeleteTodoItem delegate to specify the TodoItem to be deleted by the web service. 最后的值TaskCreationOptions枚举指定应使用的创建和执行任务的默认行为。Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

Web 服务将引发FaultException如果无法找到或删除TodoItem,这由应用程序处理。The web service throws a FaultException if it fails to locate or delete the TodoItem, which is handled by the application.

配置对 IIS Express 的远程访问Configure remote access to IIS Express

在 Visual Studio 2017 或 Visual Studio 2019 中, 你应该能够在没有其他配置的情况下在电脑上测试 UWP 应用程序。In Visual Studio 2017 or Visual Studio 2019, you should be able to test the UWP application on a PC with no additional configuration. 测试 Android 和 iOS 客户端可能需要此部分中的其他步骤。Testing Android and iOS clients may require the additional steps in this section. 有关详细信息, 请参阅从 IOS 模拟器和 Android 模拟器连接到本地 Web 服务See Connect to Local Web Services from iOS Simulators and Android Emulators for more information.

默认情况下, IIS Express 仅响应对localhost的请求。By default, IIS Express will only respond to requests to localhost. 远程设备 (如 Android 设备, iPhone 甚至是模拟器) 将无法访问本地 WCF 服务。Remote devices (such as an Android device, an iPhone or even a simulator) will not have access to your local WCF service. 需要在本地网络上了解 Windows 10 工作站的 IP 地址。You will need to know your Windows 10 workstation IP address on the local network. 出于本示例的目的, 假设工作站有 IP 地址192.168.1.143For the purpose of this example, assume that your workstation has the IP address 192.168.1.143. 以下步骤说明如何配置 Windows 10 和 IIS Express 以接受远程连接并从物理或虚拟设备连接到服务:The following steps explain how to configure Windows 10 and IIS Express to accept remote connections and connect to the service from a physical or virtual device:

  1. 向 Windows 防火墙添加例外Add an exception to Windows Firewall. 必须通过 Windows 防火墙打开端口, 子网中的应用程序才能使用这些应用程序与 WCF 服务进行通信。You must open a port through Windows Firewall that applications on your subnet can use to communicate with the WCF service. 在防火墙中创建入站规则打开端口49393。Create an inbound rule opening port 49393 in the firewall. 在管理命令提示符下, 运行以下命令:From an administrative command prompt, run this command:

    netsh advfirewall firewall add rule name="TodoWCFService" dir=in protocol=tcp localport=49393 profile=private remoteip=localsubnet action=allow
    
  2. 将 IIS Express 配置为接受远程连接Configure IIS Express to Accept Remote connections. 您可以通过在 [解决方案目录.] vs\config\applicationhost.config中编辑 IIS Express 的配置文件来配置 IIS Express。查找名称site TodoWCFService为的元素。You can configure IIS Express by editing the configuration file for IIS Express at [solution directory].vs\config\applicationhost.config. Find the site element with the name TodoWCFService. 它应类似于以下 XML:It should look similar to the following XML:

    <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 模拟器。You will need to add two binding elements to open up port 49393 to outside traffic and the Android emulator. 绑定使用一[IP address]:[port]:[hostname]种格式, 该格式指定 IIS Express 响应请求的方式。The binding uses a [IP address]:[port]:[hostname] format that specifies how IIS Express will respond to requests. 外部请求的主机名必须指定为bindingExternal requests will have hostnames that must be specified as a binding. 将以下 XML 添加到bindings元素, 并将 ip 地址替换为你自己的 ip 地址:Add the following XML to the bindings element, replacing the IP address with your own IP address:

    <binding protocol="http" bindingInformation="*:49393:192.168.1.143" />
    <binding protocol="http" bindingInformation="*:49393:127.0.0.1" />
    

    更改后, bindings元素应如下所示:After your changes the bindings element should look like the following:

    <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 将不接受来自外部源的连接。By default, IIS Express will not accept connections from external sources for security reasons. 若要启用远程设备的连接, 必须使用管理权限运行 IIS Express。To enable connections from remote devices you must run IIS Express with Administrative permissions. 执行此操作的最简单方法是运行具有管理权限的 Visual Studio 2017。The easiest way to do this is to run Visual Studio 2017 with Administrative permissions. 这会在运行 TodoWCFService 时, 通过管理权限启动 IIS Express。This will launch IIS Express with Administrative permissions when running the TodoWCFService.

    完成这些步骤后, 你应该能够运行 TodoWCFService 并从子网中的其他设备进行连接。With these steps complete, you should be able to run the TodoWCFService and connect from other devices on your subnet. 可以通过运行应用程序并访问http://localhost:49393/TodoService.svc来对此进行测试。You can test this by running your application and visiting http://localhost:49393/TodoService.svc. 如果在访问该 URL 时收到错误请求错误, bindings则 IIS Express 配置中可能不正确 (请求 IIS Express, 但被拒绝)。If you get a Bad Request error when visiting that URL, your bindings may be incorrect in the IIS Express configuration (the request is reaching IIS Express but is being rejected). 如果遇到其他错误, 可能是因为应用程序未运行或防火墙配置不正确。If you get a different error it may be that your application is not running or your firewall is incorrectly configured.

    若要允许 IIS Express 继续运行和服务, 请关闭 "项目属性" 中的 "编辑并继续" 选项 > Web > 调试器To allow IIS Express to keep running and serving the service, turn off the Edit and Continue option in Project Properties > Web > Debuggers.

  3. 自定义终结点设备用于访问服务的终结点Customize the endpoint devices use to access the service. 此步骤包括配置在物理或模拟设备上运行的客户端应用程序, 以访问 WCF 服务。This step involves configuring the client application, running on a physical or emulated device, to access the WCF service.

    Android 模拟器使用内部代理, 阻止模拟器直接访问主机的localhost地址。The Android emulator utilizes an internal proxy that prevents the emulator from directly accessing the host machine's localhost address. 相反, 模拟器上10.0.2.2的地址通过内部代理路由localhost到主机上的。Instead, the address 10.0.2.2 on the emulator is routed to localhost on the host machine through an internal proxy. 这些代理的请求将127.0.0.1作为请求标头中的主机名, 因此, 在上述步骤中为此主机名创建 IIS Express 绑定的原因。These proxied requests will have 127.0.0.1 as the hostname in the request header, which is why you created the IIS Express binding for this hostname in the steps above.

    IOS 模拟器在 Mac 生成主机上运行, 即使使用的是适用于 Windows 的远程 IOS 模拟器也是如此。The iOS Simulator runs on a Mac build host, even if you are using the Remoted iOS Simulator for Windows. 来自模拟器的网络请求将本地网络上的工作站 IP 作为主机名 (在本示例中, 实际的192.168.1.143IP 地址可能不同)。Network requests from the simulator will have your workstation IP on the local network as the hostname (in this example it's 192.168.1.143, but your actual IP address will likely be different). 这就是在上述步骤中为此主机名创建 IIS Express 绑定的原因。This is why you created the IIS Express binding for this hostname in the steps above.

    确保 TodoWCF SoapUrl (可移植) 项目中的Constants.cs文件中的属性的值对于你的网络是正确的:Ensure the SoapUrl property in the Constants.cs file in the TodoWCF (Portable) project have values that are correct for your network:

    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后, 应能够从物理或虚拟设备连接到 Windows 10 工作站上运行的 TodoWCFService。Once you have configured the Constants.cs with the appropriate endpoints, you should be able to connect to the TodoWCFService running on your Windows 10 workstation from physical or virtual devices.