Export (0) Print
Expand All

Defining Service Operations

This topic explains how the operations in a service are defined. The code for the service class can be generated by the MfSvcUtil tool.

The Dpws.Device.Device.HostedServices collection is a collection of all the services hosted by the device. Each service is derived from the class Dpws.Device.Services.DpwsHostedService.

Call the Add method in your Main method to simultaneously instantiate your services and add them to the HostedServices collection, as shown here. Any number of hosted services can be added. Services should be added before the device stack is started.

      // Add hosted service to the device (in Main)
      SampleService sampleService = new SampleService();
      Device.HostedServices.Add(sampleService);
    

Service classes must be derived from the DpwsHostedService base class, which is used to define the service’s transport address, unique identifier, namespace, and type. A service provides one or more operations or actions, which are listed in the service class’s ServiceOperations collection. Operations are methods of the service class, not classes of their own. As shown in the following code, the service’s constructor should add the operations to the service’s ServiceOperations collection in much the same way that services are instantiated and added to the HostedServices collection. The SampleService class also needs methods for the two defined operations, OneWay and TwoWayRequest.

      class SampleService : DpwsHostedService
      {
      public SampleService()
      {
      // Add ServiceNamespace. Set ServiceID and ServiceTypeName
      ServiceNamespace = new WsXmlNamespace("smpl",
      "http://schemas.example.org/SampleService");
      ServiceID = "urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b90";
      ServiceTypeName = "SampleService";

      // Add additional namespaces if needed, for example:
      // Namespaces.Add("someprefix", "http://some/Namespace");

      // Add service operations
      ServiceOperations.Add(new WsdHostedServiceOperation("smpl",
      "http://schemas.example.org/SampleService", "OneWay"));
      ServiceOperations.Add(new WsdHostedServiceOperation("smpl",
      "http://schemas.example.org/SampleService", "TwoWayRequest"));

      }

      // method for the first defined operation
      public byte[] OneWayRequest(WsWsaHeader header, WsXmlDocument envelope)
      {
      ...
      }

      // method for the second defined operation
      public byte[] TwoWayRequest(WsWsaHeader header, WsXmlDocument envelope)
      {
      ...
      }


    

Methods used for operations receive two parameters: a Ws.Services.WsaAddressing.WsWsaHeader object containing header information validated by the DPWS stack, and a T:Ws.Services.Xml.WsXmlDocument object containing the entire SOAP request as an XML tree. The operation implementation must use methods of WsXmlDocument (for example, SelectSingleNode) to extract any values from the content of the message needed to perform the desired operation, and must return a byte array containing the SOAP response message for the request. The response is typically built using the original request header object, information provided by the method implementation, and a System.Ext.XML.XMLWriter object. (The System.Ext.Xml namespace is not a part of the base .NET Micro Framework, but is provided in MFDpwsExtensions.dll.)

The following code shows how parameters can be extracted from the SOAP message, for an operation that adds two integers.

      public byte[] TwoWayRequest(WsWsaHeader header, WsXmlDocument envelope)
      {
      WsXmlNode tempNode;
      WsFault fault = new WsFault();

      if ((tempNode =
      envelope.SelectSingleNode("Body/TwoWayRequest/X", false)) == null)
      return fault.RaiseFault(header, WsExceptionFaultType.XmlException,
      "Body/TwoWay X value is missing.");

      int X = Convert.ToInt32(tempNode.Value);
      if ((tempNode =
      envelope.SelectSingleNode("Body/TwoWayRequest/Y", false)) == null)
      return fault.RaiseFault(header, WsExceptionFaultType.XmlException,
      "Body/TwoWay Y value is missing.");
      int Y = Convert.ToInt32(tempNode.Value);

      return TwoWayResponse(header, X+Y);
      }
    

The response to a Web Services message is another message. It is often good practice to create a separate method that generates the response and call it from the method that handles the original request, particularly if either procedure is involved, or if similar responses are needed for more than one request. For example, the TwoWayRequest method (defined as part of the SampleService class partially shown above) might call a TwoWayResponse method to generate its response. Since the response method is called by the request handler and never by the DPWS stack, the request method is not limited to passing a header and a SOAP request to the response method, but can pass any values needed to construct the response.

The following code shows an example of how the XML might be built in the TwoWayResponse method that is called from the example TwoWayRequest method.

      public byte[] TwoWayResponse(WsWsaHeader header, int sum)
      {
      MemoryStream soapStream = new MemoryStream();
      XmlWriter xmlWriter = XmlWriter.Create(soapStream);

      // Write processing instructions and root element
      xmlWriter.WriteProcessingInstruction("xml",
      "version='1.0' encoding='UTF-8'");
      xmlWriter.WriteStartElement("soap", "Envelope",
      "http://www.w3.org/2003/05/soap-envelope");

      // Write namespaces
      xmlWriter.WriteAttributeString("xmlns", "wsdp", null,
      Device.Namespaces.GetNamespace("wsdp"));
      xmlWriter.WriteAttributeString("xmlns", "wsd", null,
      Device.Namespaces.GetNamespace("wsd"));
      xmlWriter.WriteAttributeString("xmlns", "wsa", null,
      Device.Namespaces.GetNamespace("wsa"));
      xmlWriter.WriteAttributeString("xmlns", "sim", null,
      TypeNamespaces.GetNamespace("sim");


      // Write header
      xmlWriter.WriteStartElement("soap", "Header", null);
      xmlWriter.WriteStartElement("wsa", "To", null);
      xmlWriter.WriteString(header.From);
      xmlWriter.WriteEndElement();
      xmlWriter.WriteStartElement("wsa", "Action", null);
      xmlWriter.WriteString(
      "http://schemas.example.org/SimpleService/TwoWayResponse");
      xmlWriter.WriteEndElement();
      xmlWriter.WriteStartElement("wsa", "RelatesTo", null);
      xmlWriter.WriteString(header.MessageID);
      xmlWriter.WriteEndElement(); // End RelatesTo
      xmlWriter.WriteStartElement("wsa", "MessageID", null);
      xmlWriter.WriteString("urn:uuid:" + Device.GetUuid());
      xmlWriter.WriteEndElement(); // End MessageID
      xmlWriter.WriteEndElement(); // End Header

      // write body
      xmlWriter.WriteStartElement("soap", "Body", null);
      xmlWriter.WriteStartElement("sim", "TwoWayResponse", null);
      xmlWriter.WriteStartElement("sim", "Sum", null);
      xmlWriter.WriteString(sum.ToString());
      xmlWriter.WriteEndElement(); // End Sum
      xmlWriter.WriteEndElement(); // End TwoWayResponse
      xmlWriter.WriteEndElement(); // End Body

      xmlWriter.WriteEndElement();

      // Create return buffer and close writer
      xmlWriter.Flush();
      byte[] soapBuffer = soapStream.ToArray();
      xmlWriter.Close();

      return soapBuffer;
      }
    
Show:
© 2014 Microsoft