public Message GetDataEmpty() { MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataEmptyResponse"); }
public Message GetDataObject() { User user = new User(); user.Name = "JACK"; user.Age = 20; user.ID = 1; user.Nationality = "CHINA"; MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataObjectResponse", user); }
示例代碼以下:安全
public Message GetDataXml() { string path = Environment.CurrentDirectory.Substring(0, Environment.CurrentDirectory.IndexOf("bin")) + "test.xml"; FileStream stream = new FileStream(path, FileMode.Open); XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataXmlResponse", xdr); }
public Message GetDataFault() { FaultException<FaultMessage> fe = new FaultException<FaultMessage> (new FaultMessage("錯誤時間:" + System.DateTime.Now.ToString(), "輸入的字符串大於10個字符")); MessageFault fault = fe.CreateMessageFault(); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, fault, "http://tempuri.org/IUserInfo/GetDataFaultResponse"); }
using System.ServiceModel; using System.Runtime.Serialization; using System.ServiceModel.Channels; namespace Service { [ServiceContract] public interface IUserInfo { [OperationContract] Message GetDataEmpty(); [OperationContract] Message GetDataObject(); [OperationContract] Message GetDataXml(); [OperationContract] Message GetDataFault(); } [MessageContract] public class User { [MessageBodyMember] public int ID { get; set; } [MessageBodyMember] public string Name { get; set; } [MessageBodyMember] public int Age { get; set; } [MessageBodyMember] public string Nationality { get; set; } } [DataContract] public class FaultMessage { private string _errorTime; private string _errorMessage; [DataMember] public string ErrorTime { get { return this._errorTime; } set { this._errorTime = value; } } [DataMember] public string ErrorMessage { get { return this._errorMessage; } set { this._errorMessage = value; } } public FaultMessage(string time, string message) { this._errorTime = time; this._errorMessage = message; } } }
UserInfo.cs的代碼以下:網絡
using System.ServiceModel.Channels; using System.ServiceModel; using System.IO; using System; using System.Xml; namespace Service { public class UserInfo:IUserInfo { public Message GetDataEmpty() { MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataEmptyResponse"); } public Message GetDataObject() { User user = new User(); user.Name = "JACK"; user.Age = 20; user.ID = 1; user.Nationality = "CHINA"; MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataObjectResponse", user); } public Message GetDataXml() { string path = Environment.CurrentDirectory.Substring(0, Environment.CurrentDirectory.IndexOf("bin")) + "test.xml"; FileStream stream = new FileStream(path, FileMode.Open); XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataXmlResponse", xdr); } public Message GetDataFault() { FaultException<FaultMessage> fe = new FaultException<FaultMessage> (new FaultMessage("錯誤時間:" + System.DateTime.Now.ToString(), "輸入的字符串大於10個字符")); MessageFault fault = fe.CreateMessageFault(); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, fault, "http://tempuri.org/IUserInfo/GetDataFaultResponse"); } } }
2. Host:控制檯應用程序,服務承載程序。添加對程序集Service的引用,完成如下代碼,寄宿服務。Program.cs代碼以下:架構
using System; using System.ServiceModel; using Service; namespace Host { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(UserInfo))) { host.Opened += delegate { Console.WriteLine("服務已經啓動,按任意鍵終止!"); }; host.Open(); Console.Read(); } } } }
因爲wsHttpBinding默認啓用安全機制,爲了簡便的觀察消息體結構,在本示例中設置wsHttpBinding的security mode="None",App.config的代碼以下:ide
<?xml version="1.0"?> <configuration> <system.serviceModel> <services> <service name="Service.UserInfo" behaviorConfiguration="mexBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:1234/UserInfo/"/> </baseAddresses> </host> <endpoint address="" binding="wsHttpBinding" contract="Service.IUserInfo" bindingConfiguration="bindConfig"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="mexBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="bindConfig"> <security mode="None" /> </binding> </wsHttpBinding> </bindings> </system.serviceModel> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
test.xml文件的內容以下:工具
<?xml version="1.0" encoding="utf-8" ?> <User> <ID>1</ID> <Name>20</Name> <Age>JACK</Age> <Nationality>CHINA</Nationality> </User>
運行Host.exe程序,成功寄宿服務後,咱們經過svcutil.exe工具生成客戶端代理類和客戶端的配置文件svcutil.exe是一個命令行工具,學習
位於路徑C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin下,咱們能夠經過命令行運行該工具生成客戶端代理類測試
3. Client:控制檯應用程序,客戶端調用程序。將生成的UserInfoClient.cs和App.config複製到Client的工程目錄下,完成客戶端調用代碼。Program.cs的代碼以下:this
using System; using System.ServiceModel.Channels; namespace Client { class Program { static void Main(string[] args) { UserInfoClient proxy = new UserInfoClient(); //顯示建立基本消息(空消息) //Message message = proxy.GetDataEmpty(); //Console.WriteLine(message.ToString()); //顯示從對象建立消息 //Message message = proxy.GetDataObject(); //Console.WriteLine(message.ToString()); //顯示從XML讀取器建立消息 //Message message = proxy.GetDataXml(); //Console.WriteLine(message.ToString()); //顯示建立錯誤消息 Message message = proxy.GetDataFault(); Console.WriteLine(message.ToString()); Console.Read(); } } }
從運行結果能夠看出一個基本的消息結構爲<s:Envelope></ s:Envelope >,其中包含消息頭<s:Header>< s:Header >和消息正文<s:Body></ s:Body >
從運行結果能夠看出類型爲User的MessageContract轉化爲了消息的正文部分
從運行結果能夠看出讀取文件test.xml的內容轉化爲了消息正文部分
從運行結果能夠看出類型爲FaultMessage的DataContract轉化爲了消息的正文部分,而且嵌套在了錯誤消息結構<s:Fault>下的<s:Detail>中。