Trying to call a WCF service with a WebRequest
Solution 1
I think you're mixing up two different things here:
-
WebRequest
and aPOST
and the[WebInvoke]
attribute suggests you're trying to do something like REST - Your service config however has
basicHttpBinding
- a SOAP protocol which won't fly withWebRequest
So - make up your mind!
Do you want to use SOAP? Then you're fine with the basicHttpBinding as is, but you cannot access a SOAP service just like that from a WebRequest with POST - you need to use the SOAP client generated by Visual Studio or svcutil.exe
on the command line.
Do you want to use WebRequest and a simple POST request?? Then you need to create a REST based WCF service - use the webHttpBinding
and the WebServiceHost
(as opposed to a plain ServiceHost).
For SOAP-based WCF services, check out the WCF Developer Center on MSDN.
For REST-based WCF services (which you can navigate to in your browser, and which you can call from WebRequest), check out the WCF REST Developer Center on MSDN and have a look at the excellent screencast series by Pluralsight on REST based development in WCF - most notably:
Solution 2
basicHttpBinding is also suitable!
I spend almost a day figuring out whats wrong with WebRequest to WCF service with basicHttpBinding and it turned out I missed small but crucial thing: SOAPAction header has to be set!
newRequest.Headers["SOAPAction"] = "http://tempuri.org/INotificationService/MyMethodName"
Seth
Updated on June 23, 2022Comments
-
Seth almost 2 years
I have a WCF service that needs to be called by a 3rd party app, posting some raw XML.
I am trying to test my service by constructing a simple WebRequest and making the request to the service.
Here's my service code:
Interface:
[ServiceContract(Namespace = "http://test.mydomain.com")] public interface ITest { [WebInvoke(UriTemplate = "", BodyStyle = WebMessageBodyStyle.Bare, Method="POST")] [OperationContract] Stream SaveXML(Stream input); }
Service:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(Namespace = "http://test.mydomain.com")] public class Test : ITest { public Stream SaveXML(Stream input) { StreamReader streamReader = new StreamReader(input); string rawString = streamReader.ReadToEnd(); streamReader.Dispose(); // here need to save the input stream to xml format file Encoding encoding = Encoding.GetEncoding("ISO-8859-1"); WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml"; byte[] returnBytes = encoding.GetBytes(rawString); return new MemoryStream(returnBytes); } }
config:
<services> <service behaviorConfiguration="Blah.TestBehavior" name="Blah.Test"> <endpoint address="http://localhost:51494/Blah/Test.svc" binding="basicHttpBinding" contract="Blah.ITest"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services>
faulty client code:
string postData = "<Message version=\"1.5\" xmlns=\"http://test.mydomain.com\" ><books>Blah</books></Message>"; WebRequest request = WebRequest.Create("http://localhost:51494/Blah/Test.svc/SaveXML"); request.Method = "POST"; byte[] byteArray = Encoding.UTF8.GetBytes(postData); request.ContentType = "application/x-www-form-urlencoded"; //request.ContentType = "text/xml; charset=utf-8"; //request.ContentType = "text/xml;"; //request.ContentType = "application/xml;"; request.ContentLength = byteArray.Length; Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); // Get the response. WebResponse response = request.GetResponse();
On that last line I get a 400 (Bad Request) or 415 (Unsupported Media Type) error, depending on which ContentType I specify.
Also, if I add a service reference in my client app, and call the service using the API it works fine. Any insights would be greatly appreciated, as I am new to WCF and completely stumped.
-
Cheeso about 14 yearsWhat I would do: use Fiddler fiddler2.com/fiddler2 to see the request for "the API" - the one that works. Then compare it to the request that doesn't work. That should narrow it down.
-
John Saunders about 14 yearsYour
StreamReader
needs to be in ausing
block, as do several of your other objects. Ausing
block will cause them to be disposed of even if an exception is thrown.
-
-
Abhijeet over 10 yearsWhat did you supply in body of the
WebRequest
. Did it include SOAPHeaders as well. -
Alexander Selishchev over 10 years@autrevo, you mean request stream? You can install http proxy (such as Fiddler) and check whats being sent in WCF service call. You will see request body and headers. I had to forward request in my task, so im not constructing request body by myself.
-
default almost 7 yearsWCF Developer Center seems dead - any updated link available?
-
default almost 7 years.. And the RESTful videos as well unfortunately.
-
marc_s almost 7 years@Default: sorry, those links were ok - in 2010 when I answered - but you're right, they seem to be dead know. I'm sorry, I don't have any alternate links..... try to ask Google or Bing, maybe??
-
default almost 7 yearsI know that you wrote the answer in 2010. No need to point it out. When links rot on stackoverflow I usually let the OP know since I don't just want to randomly update links to some other resource. My intention was to let the links get updated somehow for other visitors as well, not just now, for me. I am sorry if you took offence. I will try Google.