Solved

Calling a RESTful WCF Service

Posted on 2011-03-15
6
1,655 Views
Last Modified: 2012-06-27
Dear Experts,

I am trying to invoke a RESTful WCF service programmatically.

This is the OperationContract method.

 [WebInvoke(Method = "POST", UriTemplate = "submitPaymentToBankURI")]
[OperationContract]
Stream submitPaymentToBank(Stream info);

This is the client code:

 string baseAddress = "http://localhost:1287/CreditCardWebServiceRESTSite/CreditCardServiceREST.svc";

            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/submitPaymentToBankURI");
            req.Method = "POST";
            req.ContentType = "text/plain";

            Stream reqStream = req.GetRequestStream();
            string inputData = "MyData";
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            byte[] DataToSend = encoding.GetBytes(inputData);
            reqStream.Write(DataToSend, 0, DataToSend.Length);
            reqStream.Close();
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);

            StreamReader loResponseStream = new StreamReader(resp.GetResponseStream(), encoding);
            string lcHtml = loResponseStream.ReadToEnd();
            Console.WriteLine(lcHtml);
            Console.ReadLine();

I am using WebHttpBinding.

I am getting an exception on this line:
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

Exception Details:
System.Net.WebException was unhandled
  Message="The remote server returned an error: (400) Bad Request."
  Source="System"
  StackTrace:
       at System.Net.HttpWebRequest.GetResponse()
       at TestCreditCardWebServiceREST.Program.Main(String[] args) in C:\MyProject\TestCreditCardWebServiceREST\Program.cs:line 61
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

Any clues on how to fix this?

Thanks in advance for your help.
0
Comment
Question by:shekhar_shashi
  • 4
  • 2
6 Comments
 
LVL 18

Accepted Solution

by:
DarrenD earned 500 total points
ID: 35149800
0
 
LVL 3

Author Comment

by:shekhar_shashi
ID: 35151233
Hi Darren,

Yes, I have tried this link before. I can get the my code (and also the code in the link) to work with HTTP Get but not with Post.

Thanks
0
 
LVL 18

Assisted Solution

by:DarrenD
DarrenD earned 500 total points
ID: 35160706
Hi,

How about this?

[OperationContract]
    [WebInvoke
        (Method = "POST",
        RequestFormat = WebMessageFormat.Xml,
        UriTemplate = "/SetGasPrice/For/ZipCode/{zipCode}/Price/{price}"
        )]
    void SetPriceDataForZipCode(string zipCode, string price);
}

Got this from here:
http://stackoverflow.com/questions/385451/wcf-restful-post-question

Cheers,

Darren
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 3

Assisted Solution

by:shekhar_shashi
shekhar_shashi earned 0 total points
ID: 35183189
Hi Darren,

I managed to fix the issue by doing the following:

1. Removed old code and started from scratch.
2. Created WCF Library and added a new service and the same method.
The method signature is:

[WebInvoke(Method = "POST", UriTemplate = "submitPayment", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
        [OperationContract]
        Stream submitPaymentToBank(Stream info);

3. Made sure I exposed an endpoint with WebHttpBinding binding. Also I added an endpoint behavior that used webHttp behavior.

Config file is:

<system.serviceModel>
    <services>
      <service behaviorConfiguration="CreditCardWebServiceREST.CreditCardWebServiceRESTBehavior"
        name="CreditCardWebServiceREST.CreditCardWebServiceREST">
        <clear />
        <endpoint behaviorConfiguration="WebBehavior" binding="webHttpBinding"
          bindingConfiguration="" contract="CreditCardWebServiceREST.ICreditCardWebServiceREST"
          listenUriMode="Explicit" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"
          listenUriMode="Explicit" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:2524/CreditCardWebServiceREST/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="WebBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="CreditCardWebServiceREST.CreditCardWebServiceRESTBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
 
4. I added a new WCF website that uses the WCF library. This is a pre-compiled site that has a service file with this code.

<%@ ServiceHost Service="CatalogWebServiceREST.CatalogWebServiceREST"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

Also - both projects have a reference to System.ServiceModel.Web.


5. This is my client code.


  string baseAddress = "http://localhost:xxxx/CreditCardService.svc";

            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/submitPayment/");
            req.Method = "POST";
            req.ContentType = "text/plain";

            Stream reqStream = req.GetRequestStream();
            string inputData = "MyData";
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            byte[] DataToSend = encoding.GetBytes(inputData);
            reqStream.Write(DataToSend, 0, DataToSend.Length);
            reqStream.Close();
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);

            StreamReader loResponseStream = new StreamReader(resp.GetResponseStream(), encoding);
            string lcHtml = loResponseStream.ReadToEnd();
            Console.WriteLine(lcHtml);
            Console.ReadLine();


This code is stolen from:
http://www.west-wind.com/presentations/dotnetwebrequest/dotnetwebrequest.htm

Everything works like a charm!!!


0
 
LVL 3

Author Comment

by:shekhar_shashi
ID: 35183204
Hi Darren,

Thanks for the all the research work. You deserve full points and so I'll award points shortly.

0
 
LVL 3

Author Closing Comment

by:shekhar_shashi
ID: 35221232
Thanks
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

While working on Silverlight and WCF application, I faced one issue where fault exception occurred at WCF operation contract is not getting propagated to Silverlight client. So after searching net I came to know that it was behavior by default for s…
Users of Windows 10 Professional can disable automatic reboots using the policy editor. This tool is not included in the Windows home edition. But don't worry! Follow the instructions below to install (a Win7) policy editor on your Windows 10 Home e…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now