A day with .Net

My day to day experince in .net

Archive for June, 2012

WCF REST Service accepting Raw Xml- WebContentTypeMapper

Posted by vivekcek on June 14, 2012

My Problem
———-

I want to develop a WCF-REST service that accept XML through POST method. Process the xml and send an xml response back. Different types of xml string are posted to my service. My service need to accept any format like text/xml,appilcation/xml etc.

How i am going to solve
————————————–

I am planning to use .NET 4.0 for my WCF service. In .NET 4.0 WCF support Raw data in the form of Stream.

To Code
——-

1. Create a WCF Service application.

2. In the Service contract write below code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
using System.IO;
using System.Xml.Linq;
namespace RestRaw
{    
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "Push",
               RequestFormat = WebMessageFormat.Xml,
               ResponseFormat = WebMessageFormat.Xml,
               BodyStyle = WebMessageBodyStyle.Bare)]
        XElement DoWork(Stream xml);
    }
}

3. In the Service implementation write the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
using System.Xml.Linq;
namespace RestRaw
{
   
    public class Service1 : IService1
    {
        public XElement DoWork(Stream xml)
        {
            StreamReader reader = null;
            XDocument xDocRequest = null;
            string strXmlRequest = string.Empty;
            reader = new StreamReader(xml);
            strXmlRequest = reader.ReadToEnd();
            xDocRequest = XDocument.Parse(strXmlRequest);
            string response = "<Result>OK</Result>";
            return XElement.Parse(response);
        }
    }
}

4. Now create a class named RawContentTypeMapper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace RestRaw
{
    public class RawContentTypeMapper : WebContentTypeMapper
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {

            if (contentType.Contains("text/xml") || contentType.Contains("application/xml"))
            {

                return WebContentFormat.Raw;

            }

            else
            {

                return WebContentFormat.Default;

            }
        }
    }
}

5. Change your Web.config as below.

<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="" name="RestRaw.Service1">
        <endpoint address="" behaviorConfiguration="web" contract="RestRaw.IService1" binding="customBinding" bindingConfiguration="RawReceiveCapable"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception 

information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
      <customBinding>
        <binding name="RawReceiveCapable">
          <webMessageEncoding webContentTypeMapperType="RestRaw.RawContentTypeMapper, RestRaw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <httpTransport manualAddressing="true" maxReceivedMessageSize="524288000"
           transferMode="Streamed" />
        </binding>

      </customBinding>
    </bindings>
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  
</configuration>

6. Code to test service

 private static string PostXml(string xml, string url)
        {
            // Restful service URL
            //string url = txtURL.Text;

            // declare ascii encoding
            ASCIIEncoding encoding = new ASCIIEncoding();
            string strResult = string.Empty;
            // sample xml sent to Service & this data is sent in POST
            string SampleXml = xml;
            string postData = SampleXml.ToString();
            // convert xmlstring to byte using ascii encoding
            byte[] data = encoding.GetBytes(postData);
            // declare httpwebrequet wrt url defined above
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
            // set method as post
            webrequest.Method = "POST";
            // set content type
            webrequest.ContentType = "text/xml";
            // set content length
            webrequest.ContentLength = data.Length;
            // get stream data out of webrequest object
            Stream newStream = webrequest.GetRequestStream();
            newStream.Write(data, 0, data.Length);
            newStream.Close();
            // declare & read response from service
            HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse();

            // set utf8 encoding
            Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
            // read response stream from response object
            StreamReader loResponseStream =
        new StreamReader(webresponse.GetResponseStream(), enc);
            // read string from stream data
            strResult = loResponseStream.ReadToEnd();
            // close the stream object
            loResponseStream.Close();
            // close the response object
            webresponse.Close();

            return strResult;
        }

Solution

DOWNLOAD

http://sdrv.ms/M0AunA

Advertisements

Posted in WCF | Tagged: , , | 19 Comments »