Section 1
- Part 3
- Topic 5
Implement WSE SOAP messaging.
- Select a protocol.
- Implement one-way SOAP messaging.
- Implement bidirectional SOAP messaging.
- Send the attachments from a Web service application.
- Receive attachments in a client application.
Summary
WSE allows you to send and receive messages using the TCP protocol with or without using a http server.
WSE provides the SoapSender and SoapReceiver classes to enable one way communication while the SoapClient and SoapService classes support bidirectional messaging.
To use the SoapSender class to send a message to a Soap Receiver you must create an end point reference pointing to where you want to send the message. An example from msdn for creating an end point reference is below:
Uri destinationUri = new Uri("soap.tcp://SomeHostName/SomePath");
//or
//Uri destinationUri = new Uri("http://SomeHostName/SomePath");
EndpointReference destination = new EndpointReference(destinationUri);
SoapSender sender = new SoapSender(destination);
Once you have the endpoint, you need to create an Envelope Message that holds the actual Message you want to send. Once you have configured the message you need to call the send method of the SoapSender instance to send the message to the end point. An example from msdn for doing this is below:
SoapEnvelope envelope = new SoapEnvelope();
envelope.Context.Addressing.Action = new Action("soap.tcp://SomeNamespaceURI/myReceiver");
envelope.SetBodyObject("Some message goes here"); sender.Send(envelope);
To receive the message on the other side you must create a class that inherits from SoapReceiver class. In the class override the Receive method to get the message from the sender. An example from msdn is below:
class MyReceiver : SoapReceiver
{
protected override void Receive( SoapEnvelope message )
{
// Do something with the message,
// such as display its contents.
}
}
To actually get this to work though, you must register an instance of the receiver. This is done differently depending on if you are using tcp with a console application/windows service or hosting it in IIS using http. To register the receiver using tcp, you must create an endpoint for the receiver and register the endpoint with the instance of your custom receiver class. An example of this is below:
MyReceiver myReceiver = new MyReceiver();
Uri to = new Uri(
"soap.tcp://" + System.Net.Dns.GetHostName() + "/MyReceiver" );
EndpointReference EPR = new EndpointReference(to);
SoapReceivers.Add(EPR, myReceiver);
To configure the receiver with http, you must make sure the web config has a reference to WSE 3.0 in the config sections and then add an http handler of the type of you receiver in the web config. An example of this section from msdn is below:
<httpHandlers>
<add verb="*" path="MyReceiver.ashx" type="MyNamespace.MyReceiver, MyAssemblyName"/>
</httpHandlers>
For bidirectional communication you will need to create a class that inherits from SoapClient to server as the client. The constructor of this class should accept an endpoint reference as a parameter, passing it to the base constructor. Then in the class you must define methods to correspond to methods defined in a SoapService class (described later). The methods should be decorated with a SoapMethod Attribute. Each method should accept a SoapEnvelope and pass the envelope with the method name to the base SendRequestResponse method. An example of an implementation from msdn is below:
[SoapMethod("RequestResponseMethod")]
public SoapEnvelope RequestResponseMethod(SoapEnvelope envelope)
{
return base.SendRequestResponse("RequestResponseMethod",envelope);
}
Then in the code that will be send the request you need to create an instance of your SoapClient passing in the end point reference. Then you can call the methods that you exposed passing in an envelope to be passed to the end point. An example from msdn is below:
// The destination variable is the EndpointReference
// for the Web service.
CustomSoapClient client = new TcpClient(destination); SoapEnvelope envelope = new SoapEnvelope();
envelope.Context.Addressing.Action = new Action("soap.tcp://SomeNamespaceURI/myReceiver");
envelope.SetBodyObject("Some message goes here"); // The envelope that is returned is the response data.
SoapEnvelope returnEnvelope = client.RequestResponseMethod(envelope);
To receive the messages on the other side you must create a class that inherits from SoapService class. In the class you must define the methods that the client can invoke and decorate them with a SoapMethod Attribute. An example from msdn is below:
class TcpService : SoapService
{
[SoapMethod("RequestResponseMethod")]
public SoapEnvelope RequestResponseMethod(SoapEnvelope envelope)
{
SoapEnvelope response = new SoapEnvelope();
// Whatever data the client will require from a response
// is placed in the SOAP envelope.
response.SetBodyObject("<Response>Some message goes here</Response>");
return response;
}
}
To actually get this to work though, you must register an instance of the service. This is done differently depending on if you are using tcp with a console application/windows service or hosting it in IIS using http. To register the receiver using tcp, you must create an endpoint for the service and register the endpoint with the instance of your custom service class. An example of this is below:
TcpService tcpService = new TcpService();
Uri to = new Uri( "soap.tcp://" + System.Net.Dns.GetHostName() + "/MyReceiver" );
EndpointReference EPR = new EndpointReference(to);
SoapReceivers.Add(EPR, tcpService);
To configure the receiver with http, you must make sure the web config has a reference to WSE 3.0 in the config sections and then add an http handler of the type of you receiver in the web config. An example of this section from msdn is below:
<httpHandlers>
<add verb="*" path="MyReceiver.ashx" type="MyNamespace.TcpService, MyAssemblyName"/>
</httpHandlers>
WSE 2.0 used DIME Attachments for attaching large pieces of data to a Soap Message. WSE 3.0 uses Message Transmission Optimization Mechanism or MTOM to attach large pieces of data to a Soap Message.
To use MTOM you must add a MTOM element to the web config either manually or through the WSE Settings Wizard on the messaging tab. You must configure the client mode to on, and the server mode to optional or always depending on your requirements.
Once your application is configured to use MTOM, you can simply configure your web service methods to either return a byte array or accept a byte array as a parameter. Here is an example from msdn that returns a file to the client:
[WebMethod]
public byte[] GetFile(string fileName)
{
byte[] response;
String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;
response = File.ReadAllBytes(filePath);
return response;
}
You can configure the max size of an attachment and maximum timeout for a request through the httpruntime node of the web config of the service. An example of setting these values from msdn is below:
<configuration>
<system.web>
<httpRuntime maxMessageLength="409600"
executionTimeoutInSeconds="300"/>
</system.web>
</configuration>
To send and receive from the client side you must add a MTOM element to the web config either manually or through the WSE Settings Wizard on the messaging tab. You must configure the client mode to on.
If you need to increase the maximum size of the attachment or timeout properties you must add or modify the httpRunTime node of the applications config file. An example of setting these values from msdn is below:
<configuration>
<system.web>
<httpRuntime maxMessageLength="409600"
executionTimeoutInSeconds="300"/>
</system.web>
</configuration>
Then all you need to do is use the generated proxy for the client as normal. The following example from msdn demonstrates calling a service the returns a byte array which is converted into an image:
String fileName = "Winter.jpg";
// Create an instance of the Web service proxy class.
BinaryDataMTOMServiceWse serviceproxy = new BinaryDataMTOMServiceWse(); // Specify that MTOM encoding must be used.
serviceproxy.RequireMtom = true; serviceproxy.SetPolicy("ClientPolicy");
// Communicate with the Web service to get the requested file.
byte[] response = serviceproxy.GetFile(fileName); MemoryStream memory = new MemoryStream(response); // Display the file in a picture box.
pictureBox1.Image = System.Drawing.Image.FromStream(memory);
Other Resources & Links:
Sending and Receiving SOAP Messages Using WSE Messaging API
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/98517ae3-5669-4fb4-904f-ea893d6fcac3.asp
How to: Send and Receive a SOAP Message By Using the SoapSender and SoapReceiver Classes
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/4891146d-7d24-4ef7-8190-ea28e46d0853.asp
How to: Send and Receive a SOAP Message By Using the SoapClient and SoapService Classes
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/4891146d-7d24-4ef7-8190-ea28e46d0853.asp
How to: Enable a Web Service to Send and Receive Large Amounts of Data
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/4344d43e-ceb4-43a9-8f8c-6a3f89f786bd.asp
How to: Send and Receive Large Amounts of Data to and from a Web Service
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse3.0/html/4344d43e-ceb4-43a9-8f8c-6a3f89f786bd.asp