[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1836
  • Last Modified:

Calling a RESTful WCF Service

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
shekhar_shashi
Asked:
shekhar_shashi
  • 4
  • 2
3 Solutions
 
DarrenDCommented:
0
 
shekhar_shashiAuthor Commented:
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
 
DarrenDCommented:
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
SMB Security Just Got a Layer Stronger

WatchGuard acquires Percipient Networks to extend protection to the DNS layer, further increasing the value of Total Security Suite.  Learn more about what this means for you and how you can improve your security with WatchGuard today!

 
shekhar_shashiAuthor Commented:
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
 
shekhar_shashiAuthor Commented:
Hi Darren,

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

0
 
shekhar_shashiAuthor Commented:
Thanks
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now