更新:2007 年 11 月
您可以创建基于 Windows Communication Foundation (WCF) Exchange Server 邮件传输的应用程序,以便通过将运行 Microsoft Exchange Server 的计算机用作中介在指定的输入/输出信道中发送和接收邮件。基于 WCF Exchange Server 邮件传输的应用程序在台式机和设备上均受支持。
本演练介绍 WCF Exchange Server 邮件传输的功能,并阐释了下列任务:
- 设置计算机。 
- 为设备(客户端)生成应用程序。 
- 为台式机(服务器)生成应用程序。 
有关这些过程中所显示的完整代码清单,请参见本演练结尾处的“示例”一节。
| .gif) 说明: | 
|---|
| 请勿在成品代码中使用此示例。 | 
先决条件
此示例需要使用 .NET Compact Framework 3.5 版。
设置计算机
在此过程中,应确保正确设置开发环境,以运行给出的示例。
设置计算机以运行给出的示例
- 安装 Windows Mobile 5.0 版或 Windows Mobile 6 软件开发工具包 (SDK)。 - Windows Mobile 6 Professional SDK 包括 ActiveSync 始终最新 (AUTD) 功能,设备上的邮件传输使用此功能将“收件箱”保持为最新状态。有关更多信息,请参见 Windows Mobile Web site(Windows Mobile 网站)。 
- 确保可通过网络访问运行 Microsoft Exchange Server 2007 的电子邮件服务器。 - 如果没有 Exchange Server 2007,可以使用在虚拟 PC 上运行的试用版本。有关更多信息,请参见 Exchange Server Web site(Exchange Server 网站)。 
- 通过在计算机上运行 Outlook Web Access (OWA) 并连接至一个电子邮件帐户,验证计算机是否可以连接到新的 Exchange 电子邮件服务器。 
- 确保 Exchange 电子邮件服务器上启用了 Exchange Web 服务。 - 一种验证方法是使用下列 URL 之一访问电子邮件服务器上的 exchange.asmx 页:http://服务器地址/ews/exchange.asmx 或 https://服务器地址/ews/exchange.asmx。 
- 如果使用了仿真程序,请为其提供网络功能。 .gif) 说明: 说明:- 当 ActiveSync 提供网络连接时,将不会运行 ActiveSync AUTD 功能。您可以使用 Device Emulator 2.0(包括在 Windows Mobile 6 Professional SDK 中,也可以单独下载)并通过配置仿真程序属性将 NE2000 PCMCIA 卡绑定到宿主网络适配器上。 
- 在启动并运行仿真程序后,请配置 ActiveSync 以便与 Exchange 电子邮件服务器进行通信。有关更多信息,请参见位于 Microsoft TechNet 网站上的 Deploying Windows Mobile 6 Powered Devices with Microsoft Exchange Server 2007(将基于 Windows Mobile 6 的设备与 Microsoft Exchange Server 2007 部署在一起)中的“Step 5: Configure and Manage Mobile Device Access on the Exchange Server”(步骤 5:在 Exchange Server 上配置和管理移动设备访问)。 
为设备创建应用程序
在此过程中,将为表示客户端的设备生成应用程序,然后使用邮件传输创建邮件并将其发送到服务器。
为设备创建应用程序
- 在 Visual Studio 中创建一个新的智能设备项目。 
- 将下列引用添加到该项目中: - Microsoft.ServiceModel.Mail.dll 
- Microsoft.ServiceModel.Mail.WindowsMobile.dll 
- System.ServiceModel.dll 
- System.Runtime.Serialization.dll 
 
- 添加 CFMessagingSerializer 类(如何:序列化 WCF 应用程序中的消息中进行了描述)。 - 在台式机上,可以使用自定义序列化程序或属性来创建序列化数据。但是,我们建议对设备和台式机使用同一个序列化程序。 
- 生成邮件。 - Dim str As String = "Hello"- String str = "Hello";
- 创建邮件并对它加以序列化。 - ' Create the message. Dim serializer As New CFMessagingSerializer(GetType(String)) Dim m As Message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer)- // Create the message. CFMessagingSerializer serializer = new CFMessagingSerializer(typeof(string)); Message m = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer);
- 创建表示信道名称、设备电子邮件地址以及服务器电子邮件地址的变量。 - Dim channelName As String = "StoreandFowardMessageHelloWorld" Dim serverAddress As String = "ServerMailAddress@fabrikam.com" Dim clientAddress As String = "DeviceMailAddress@fabrikam.com"- string channelName = "StoreandFowardMessageHelloWorld"; string serverAddress = "ServerMailAddress@fabrikam.com"; string clientAddress = "DeviceMailAddress@fabrikam.com";
- 生成输出信道。 - ' Build the output channel. Dim binding As New WindowsMobileMailBinding() Dim parameters As New BindingParameterCollection() Dim channelFactory As IChannelFactory(Of IOutputChannel) channelFactory = binding.BuildChannelFactory(Of IOutputChannel)(parameters) channelFactory.Open() Dim outChannel As IOutputChannel = channelFactory.CreateChannel(New EndpointAddress(MailUriHelper.Create(channelName, serverAddress))) outChannel.Open()- // Build the output channel. WindowsMobileMailBinding binding = new WindowsMobileMailBinding(); BindingParameterCollection parameters = new BindingParameterCollection(); IChannelFactory<IOutputChannel> channelFactory = binding.BuildChannelFactory<IOutputChannel>(parameters); channelFactory.Open(); IOutputChannel outChannel = channelFactory.CreateChannel(new EndpointAddress(MailUriHelper.Create(channelName,serverAddress))); outChannel.Open();
- 添加发送邮件的代码。 - ' Send the message. outChannel.Send(m)- // Send the message. outChannel.Send(m);
- 生成侦听器并添加侦听响应的代码。 - 侦听器会阻止代码执行。因此,在成品代码中,我们建议在单独的线程中运行侦听器。在此示例中,请将侦听器代码添加到发送方代码之后。 - ' Listen for the response. Dim listener As IChannelListener(Of IInputChannel) listener = binding.BuildChannelListener(Of IInputChannel)(MailUriHelper.CreateUri(channelName, clientAddress)) listener.Open() Dim inputChannel As IInputChannel = listener.AcceptChannel() inputChannel.Open() Dim reply As Message = inputChannel.Receive()- // Listen for the response. IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(MailUriHelper.CreateUri(channelName,clientAddress),parameters); listener.Open(); IInputChannel inputChannel = listener.AcceptChannel(); inputChannel.Open(); Message reply = inputChannel.Receive();
- 收到来自服务器的响应后,对响应进行反序列化并向用户显示结果。 - ' When you receive a response, deserialize the message. str = reply.GetBody(Of String)(serializer) MessageBox.Show(str, "Received message")- // When you receive a response, deserialize the message. str = reply.GetBody<string>(serializer); MessageBox.Show(str, "Received message");
- 进行清理。 - outChannel.Close() channelFactory.Close() listener.Close() inputChannel.Close() binding.Close()- outChannel.Close(); channelFactory.Close(); listener.Close(); inputChannel.Close(); binding.Close();
- 生成客户端应用程序,然后将其部署到配置为与 Exchange 电子邮件服务器进行同步的仿真程序或设备中。 
为台式机创建应用程序
在此过程中,将为台式计算机(在此示例中表示服务器)生成应用程序。服务器将处理来自客户端的邮件,并在追加邮件后将其发送回客户端。
为台式机创建应用程序
- 创建一个新的 Windows 控制台应用程序。 
- 将下列引用添加到该项目中: - Microsoft.ServiceModel.Mail.dll 
- Microsoft.ServiceModel.Channels.Mail.ExchangeWebService.dll 
- System.ServiceModel.dll 
- System.Runtime.Serialization.dll 
 
- 添加 CFMessagingSerializer 类(如何:序列化 WCF 应用程序中的消息中进行了描述)。 
- 创建一些变量,其中某些变量必须对应于设备项目中的值。 - ' Set some global variables. Dim channelName As String = "StoreandFowardMessageHelloWorld" Dim serverAddress As String = "ServerMailAddress@fabrikam.com" Dim serverPWD As String = "MyPassword" Dim clientAddress As String = "DeviceMailAddress@fabrikam.com" Dim exchangeServerLocation As String = "http://fabrikam"- // Set some global variables. string channelName = "StoreandFowardMessageHelloWorld"; string serverAddress = "ServerMailAddress@fabrikam.com"; string serverPWD = "MyPassword"; string clientAddress = "DeviceMailAddress@fabrikam.com"; string exchangeServerLocation = "http://fabrikam";
- 创建侦听器。 - 如果使用了 Windows 凭据,请将 null 值作为第二个参数传递给 ExchangeWebServiceMailBinding 对象。与在设备上的情况相同,输入信道也会阻止代码执行。因此,我们建议在成品代码中为每个侦听器创建一个新线程。 - ' Create the listener. If you are using Windows credentials, ' pass a null value as the second argument to the ExchangeWebServiceMailBinding. Dim binding As MailBindingBase binding = New ExchangeWebServiceMailBinding(New Uri(exchangeServerLocation), New System.Net.NetworkCredential(serverAddress, serverPWD)) Dim parameters As New BindingParameterCollection() Dim listener As IChannelListener(Of IInputChannel) listener = binding.BuildChannelListener(Of IInputChannel)(MailUriHelper.CreateUri(channelName, serverAddress)) listener.Open() Dim inputChannel As IInputChannel = listener.AcceptChannel() inputChannel.Open() Dim reply As Message = inputChannel.Receive() Dim serializer As New CFMessagingSerializer(GetType(String)) Dim str As String = "" str = reply.GetBody(Of String)(serializer)- // Create the listener. If you are using Windows credentials, // pass a null value as the second argument to the ExchangeWebServiceMailBinding. MailBindingBase binding = new ExchangeWebServiceMailBinding(new Uri(exchangeServerLocation), new System.Net.NetworkCredential(serverAddress, serverPWD)); BindingParameterCollection parameters = new BindingParameterCollection(); IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel> (MailUriHelper.CreateUri(channelName, serverAddress), parameters); listener.Open(); IInputChannel inputChannel = listener.AcceptChannel(); inputChannel.Open(); Message reply = inputChannel.Receive(); CFMessagingSerializer serializer = new CFMessagingSerializer(typeof(string)); string str = ""; str = reply.GetBody<string>(serializer);
- 添加处理邮件的代码。 - ' Process the message. str += ", World!"- // Process the message. str += ", World!";
- 添加通过输出信道发送响应的代码。 - ' Send the response through an output channel. Dim m As Message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer) Dim channelFactory As IChannelFactory(Of IOutputChannel) channelFactory = binding.BuildChannelFactory(Of IOutputChannel)(parameters) channelFactory.Open() Dim outChannel As IOutputChannel = channelFactory.CreateChannel(New EndpointAddress(MailUriHelper.CreateUri(channelName, clientAddress))) outChannel.Open() outChannel.Send(m)- // Send the response through an output channel. Message m = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer); IChannelFactory<IOutputChannel> channelFactory = binding.BuildChannelFactory<IOutputChannel>(parameters); channelFactory.Open(); IOutputChannel outChannel = channelFactory.CreateChannel(new EndpointAddress( MailUriHelper.CreateUri(channelName, clientAddress))); outChannel.Open(); outChannel.Send(m);
- 进行清理。 - ' Clean up. outChannel.Close() channelFactory.Close() listener.Close() inputChannel.Close() binding.Close()- // Clean up. outChannel.Close(); channelFactory.Close(); listener.Close(); inputChannel.Close(); binding.Close();
- 生成项目并启动服务器应用程序。 
- 启动仿真程序或设备上的客户端应用程序。 
示例
说明
下面的完整示例演示如何使用 WCF Exchange Server 邮件传输发送和接收邮件。
针对设备(客户端)的完整代码清单
        Dim str As String = "Hello"
        ' Create the message.
        Dim serializer As New CFMessagingSerializer(GetType(String))
        Dim m As Message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer)
        Dim channelName As String = "StoreandFowardMessageHelloWorld"
        Dim serverAddress As String = "ServerMailAddress@fabrikam.com"
        Dim clientAddress As String = "DeviceMailAddress@fabrikam.com"
        ' Build the output channel.
        Dim binding As New WindowsMobileMailBinding()
        Dim parameters As New BindingParameterCollection()
        Dim channelFactory As IChannelFactory(Of IOutputChannel)
        channelFactory = binding.BuildChannelFactory(Of IOutputChannel)(parameters)
        channelFactory.Open()
        Dim outChannel As IOutputChannel = channelFactory.CreateChannel(New EndpointAddress(MailUriHelper.Create(channelName, serverAddress)))
        outChannel.Open()
        ' Send the message.
        outChannel.Send(m)
        ' Listen for the response.         
        Dim listener As IChannelListener(Of IInputChannel)
        listener = binding.BuildChannelListener(Of IInputChannel)(MailUriHelper.CreateUri(channelName, clientAddress))
        listener.Open()
        Dim inputChannel As IInputChannel = listener.AcceptChannel()
        inputChannel.Open()
        Dim reply As Message = inputChannel.Receive()
        ' When you receive a response, deserialize the message.
        str = reply.GetBody(Of String)(serializer)
        MessageBox.Show(str, "Received message")
        outChannel.Close()
        channelFactory.Close()
        listener.Close()
        inputChannel.Close()
        binding.Close()
    End Sub
End Class
static void Main()
{
    String str = "Hello";
    // Create the message.
    CFMessagingSerializer serializer = new CFMessagingSerializer(typeof(string));
    Message m = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer);
    string channelName = "StoreandFowardMessageHelloWorld";
    string serverAddress = "ServerMailAddress@fabrikam.com";
    string clientAddress = "DeviceMailAddress@fabrikam.com";
    // Build the output channel.
    WindowsMobileMailBinding binding = new WindowsMobileMailBinding();
    BindingParameterCollection parameters = new BindingParameterCollection();
    IChannelFactory<IOutputChannel> channelFactory = binding.BuildChannelFactory<IOutputChannel>(parameters);
    channelFactory.Open();
    IOutputChannel outChannel = channelFactory.CreateChannel(new EndpointAddress(MailUriHelper.Create(channelName,serverAddress)));
    outChannel.Open();
    // Send the message.
    outChannel.Send(m);
    // Listen for the response.         
    IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(MailUriHelper.CreateUri(channelName,clientAddress),parameters);
    listener.Open();
    IInputChannel inputChannel = listener.AcceptChannel();
    inputChannel.Open();
    Message reply = inputChannel.Receive();
    // When you receive a response, deserialize the message.
    str = reply.GetBody<string>(serializer);
    MessageBox.Show(str, "Received message");
    outChannel.Close();
    channelFactory.Close();
    listener.Close();
    inputChannel.Close();
    binding.Close();
}
针对台式机(服务器)的完整代码清单
        ' Set some global variables. 
        Dim channelName As String = "StoreandFowardMessageHelloWorld"
        Dim serverAddress As String = "ServerMailAddress@fabrikam.com"
        Dim serverPWD As String = "MyPassword"
        Dim clientAddress As String = "DeviceMailAddress@fabrikam.com"
        Dim exchangeServerLocation As String = "http://fabrikam"
        ' Create the listener. If you are using Windows credentials,
        ' pass a null value as the second argument to the ExchangeWebServiceMailBinding.
        Dim binding As MailBindingBase
        binding = New ExchangeWebServiceMailBinding(New Uri(exchangeServerLocation), New System.Net.NetworkCredential(serverAddress, serverPWD))
        Dim parameters As New BindingParameterCollection()
        Dim listener As IChannelListener(Of IInputChannel)
        listener = binding.BuildChannelListener(Of IInputChannel)(MailUriHelper.CreateUri(channelName, serverAddress))
        listener.Open()
        Dim inputChannel As IInputChannel = listener.AcceptChannel()
        inputChannel.Open()
        Dim reply As Message = inputChannel.Receive()
        Dim serializer As New CFMessagingSerializer(GetType(String))
        Dim str As String = ""
        str = reply.GetBody(Of String)(serializer)
        ' Process the message.
        str += ", World!"
        ' Send the response through an output channel.
        Dim m As Message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer)
        Dim channelFactory As IChannelFactory(Of IOutputChannel)
        channelFactory = binding.BuildChannelFactory(Of IOutputChannel)(parameters)
        channelFactory.Open()
        Dim outChannel As IOutputChannel = channelFactory.CreateChannel(New EndpointAddress(MailUriHelper.CreateUri(channelName, clientAddress)))
        outChannel.Open()
        outChannel.Send(m)
        ' Clean up.
        outChannel.Close()
        channelFactory.Close()
        listener.Close()
        inputChannel.Close()
        binding.Close()
    End Sub
End Class
static void Main()
{
    // Set some global variables. 
    string channelName = "StoreandFowardMessageHelloWorld";
    string serverAddress = "ServerMailAddress@fabrikam.com";
    string serverPWD = "MyPassword";
    string clientAddress = "DeviceMailAddress@fabrikam.com";
    string exchangeServerLocation = "http://fabrikam";
    // Create the listener. If you are using Windows credentials,
    // pass a null value as the second argument to the ExchangeWebServiceMailBinding.
    MailBindingBase binding = new ExchangeWebServiceMailBinding(new Uri(exchangeServerLocation),
        new System.Net.NetworkCredential(serverAddress, serverPWD));
    BindingParameterCollection parameters = new BindingParameterCollection();
    IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>
        (MailUriHelper.CreateUri(channelName, serverAddress), parameters);
    listener.Open();
    IInputChannel inputChannel = listener.AcceptChannel();
    inputChannel.Open();
    Message reply = inputChannel.Receive();
    CFMessagingSerializer serializer = new CFMessagingSerializer(typeof(string));
    string str = "";
    str = reply.GetBody<string>(serializer);
    // Process the message.
    str += ", World!";
    // Send the response through an output channel.
    Message m = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "urn:test", str, serializer);
    IChannelFactory<IOutputChannel> channelFactory = binding.BuildChannelFactory<IOutputChannel>(parameters);
    channelFactory.Open();
    IOutputChannel outChannel = channelFactory.CreateChannel(new EndpointAddress(
        MailUriHelper.CreateUri(channelName, clientAddress)));
    outChannel.Open();
    outChannel.Send(m);
    // Clean up.
    outChannel.Close();
    channelFactory.Close();
    listener.Close();
    inputChannel.Close();
    binding.Close();
}
编译代码
在设备上运行的示例需要引用下列命名空间:
在台式机上运行的示例需要引用下列命名空间:
安全性
此示例中未启用邮件传输安全性。有关更多信息,请参见 WCF Exchange Server 邮件传输。
请参见
任务
如何:在 WCF Exchange Server 邮件传输中使用消息安全性
其他资源
Windows Communication Foundation (WCF) 开发与 .NET Compact Framework