A Preliminary Study on WCF-22: using Message class (on) in WCF, wcf-22

Source: Internet
Author: User
Tags xml reader

A Preliminary Study on WCF-22: using Message class (on) in WCF, wcf-22
Preface

 

  • Since learning about WCF, we have always stressed that it is a message-based communication mechanism. However, since WCF provides us with advanced encapsulation, we seldom know the internal mechanism of messages when using WCF. Due to the scalability of the WCF architecture, for some special cases, WCF provides a Message class for us to deeply customize the Message structure, so that we can expand the communication mechanism of WCF.
  • In the previous article, we described some common methods for passing data through WCF, such as data protocols and message protocols. The data they transmit will eventually be converted to the Message instance. For details, refer:

A Preliminary Study on WCF-16: Basic knowledge of WCF data protocols

A Preliminary Study on WCF-19: WCF Message Protocol

 

Message Class Overview

 

  • The Message class is the basic class of WCF. All the communication between the client and the service will eventually generate the Message instance to be sent and received. We usually do not directly interact with the Message class. Instead, we need to use the WCF Service Model (such as data protocols, message protocols, and operation protocols) to describe incoming and outgoing messages. However, in some advanced solutions, you can directly use the Message class for programming. The Message class provides a method for communication between the sender and receiver in the network to any information. It can be used to transmit information, suggest, or require a series of operations or request data.
  • The Message class is used as the abstract representation of messages, but its design is largely dependent on SOAP messages. Message contains the Message body, Message header, and Message attributes.

 

  • In short, Message is a common data container, but its design strictly follows the Message design method in the SOAP protocol. Like in SOAP, a message has both the message body and header. The message body contains actual load data, and the header contains other named Data containers. The rules for reading and writing the message body and the header are different. For example, the header is always buffered in the memory and can be accessed any time in any order, the body can only be read once and can be streamed. Generally, when SOAP is used, the message body is mapped to the SOAP body, and the message header is mapped to the SOAP header.

 

Message Use Cases and restrictions of Classes

 

  • The Message class may be used in the following situations:
  • The Message class can be used as the input parameter of the operation and/or the return value of the operation. As long as the Message is used anywhere in the operation, the following restrictions must be observed:

 

Use Message Class creation message

 

  • Create basic message
        public Message GetDataEmpty()        {            MessageVersion ver = OperationContext.Current.IncomingMessageVersion;            return Message.CreateMessage(ver, "http://tempuri.org/IUserInfo/GetDataEmptyResponse");        }
  • Create a message from an object
        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);        }
  • From XMLReader creates a message

  

The sample code is as follows:

        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);        }
  • Create error message
Public Message GetDataFault () {FaultException <FaultMessage> fe = new FaultException <FaultMessage> (new FaultMessage ("error time:" + System. dateTime. now. toString (), "the input string is greater than 10 characters"); MessageFault fault = fe. createMessageFault (); MessageVersion ver = OperationContext. current. incomingMessageVersion; return Message. createMessage (ver, fault, "http://tempuri.org/IUserInfo/GetDataFaultResponse ");}

 

WCF Used in Message Class Example

 

  • The solution is as follows:

  

 

  • The project structure is described as follows:
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;        }    }}

The code for UserInfo. cs is as follows:

Using System. serviceModel. channels; using System. serviceModel; using System. IO; 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 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 (" error time: "+ System. dateTime. now. toString (), "the input string is greater than 10 characters"); MessageFault fault = fe. createMessageFault (); MessageVersion ver = OperationContext. current. incomingMessageVersion; return Message. createMessage (ver, fault ," http://tempuri.org/IUserInfo/GetDataFaultResponse ");}}}

 

2. Host: console application and service bearer program. Add a reference to the Assembly Service. Complete the following code to host the Service. The Program. cs code is as follows:

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 ("the service has been started. Press any key to terminate! ") ;}; Host. Open (); Console. Read ();}}}}View Code

Because wsHttpBindingThe security mechanism is enabled by default. to easily observe the message body structure, set wsHttpBinding in this example.Security mode = "None", App. configThe Code is as follows:

<?xml version="1.0"?><configuration>    <system.serviceModel>                <services>            <service name="Service.UserInfo" behaviorConfiguration="mexBehavior">                

The content of the test. xml file is as follows:

<?xml version="1.0" encoding="utf-8" ?><User>  <ID>1</ID>  <Name>20</Name>  <Age>JACK</Age>  <Nationality>CHINA</Nationality></User>

Run the host.exeprogram. After successful boarding services, we use the svcutil.exetool to generate the client proxy class and the customer's configuration file svcutil.exe is a command line tool,

In the path C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin, we can run the command line to generate the client proxy class

  • Run cmd to open the command line and enter cd C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin
  • Input svcutil.exe/out: f: \ UserInfoClient. cs/config: f: \ App. config http: // localhost: 1234/UserInfo

 

3. Client: console application and Client calling program. Copy the generated UserInfoClient. cs and App. config to the Client project directory to complete the Client call code. The Code of Program. cs is as follows:

Using System; using System. serviceModel. channels; namespace Client {class Program {static void Main (string [] args) {UserInfoClient proxy = new UserInfoClient (); // display the creation basic message (empty message) // Message message = proxy. getDataEmpty (); // Console. writeLine (message. toString (); // display the Message created from the object // message Message = proxy. getDataObject (); // Console. writeLine (message. toString (); // display the Message created from the XML reader // message Message = proxy. getDataXml (); // Console. writeLine (message. toString (); // display creation error Message message = proxy. getDataFault (); Console. writeLine (message. toString (); Console. read ();}}}

 

  • Run the empty message code. The result is as follows:

  

The running result shows that the basic message structure is <s: Envelope> </s: Envelope>, which contains the message Header <s: Header> <s: header> and message Body <s: Body> </s: Body>

 

  • Run the message created from the object. The result is as follows:

  

The running result shows that MessageContract of the User type is converted to the body of the message.

 

  • Run the message created from the XML reader. The result is as follows:

  

The running result shows that the content of the test. xml file is converted to the message body part.

 

  • Run the created error message. The result is as follows:

  

The running result shows that the DataContract type of FaultMessage is converted to the body of the message, and is nested in <s: Detail> of the error message structure <s: Fault>.

 

Summary

 

  • Through the above example, we learned the basic structure of the Message, which is not to operate on the WCF test client, but to operate on the Message base class to describe the Message structure.
  • Although there are several ways to create a Message, we know that the Message is created and created through the overload of the CreateMessage method of the Message, and the Message version and Message Action must be specified. Action is generally the namespace of the service agreement + the name of the service agreement excuse + operation agreement + Response

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.