I am trying to create a simple XML SOAP request to a web service.
The service itself is proven to be OK, I accessed it by using WSDL-generated class without any problems. But if I try to access it using regular WebRequest - it always returns 400 Bad Request.
Here's my code:
class Program
{
static void Main(string[] args)
{
HttpWebRequest request = CreateWebRequest("http://localhost:8000/ExchangeService", "WhoAmI");
XmlDocument SoapEnvelopeXml = new XmlDocument();
SoapEnvelopeXml.LoadXml(
#"<?xml version=""1.0""?>
<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope""
xmlns:tem=""http://tempuri.org"">
<soapenv:Header/>
<soapenv:Body>
<tem:WhoAmI/></soapenv:Body></soapenv:Envelope>");
using (Stream stream = request.GetRequestStream())
{
SoapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
public static HttpWebRequest CreateWebRequest(string url, string soapAction)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.ContentType = "text/xml;charset=UTF-8;action=\"" + soapAction + "\"";
webRequest.Method = "POST";
return webRequest;
}
}
The XML is generated by SoapUI and works there perfectly. Here is the SoapUI's HTTP header:
POST http://localhost:8000/ExchangeService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://tempuri.org/IExchangeFunctions/WhoAmI"
Content-Length: 211
Host: localhost:8000
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
What am I doing wrong?
UPD: changed the service from my to some third-party:
http://wsf.cdyne.com/WeatherWS/Weather.asmx
Through WSDL - it works. SoapUI returns data. From my code - Internal Error 500.
Try remove carriage return from soap message
.Replace("\r\n", "");
If not work verify the http request sended with fiddler, to me it was very helpful.
Related
When testing the call through Postman and a C# WebRequest it works, but I am unable to do the same using an HttpClient with a PostAsync or PostJsonAsync call.
Error: Unsupported Media Type, although application/json is required and applied.
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent(data, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://pos.api.here.com/positioning/v1/locate?app_id={id}&app_code={code}", content);
return response;
StatusCode: 415, ReasonPhrase: 'Unsupported Media Type', Version: 1.1,
Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent,
Headers:{ Date: Fri, 08 Nov 2019 13:38:37 GMT Server: nginx-clojure
Content-Type: application/json Content-Length: 114}
WebRequest
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
if (!string.IsNullOrEmpty(data))
{
request.ContentType = "application/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
}
using (HttpWebResponse webresponse = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader = new StreamReader(webresponse.GetResponseStream()))
{
string response = reader.ReadToEnd();
return response;
}
}
There are two differences I see:
You are setting the Accept header in your HttpClient code, where you were not in your WebRequest code. This defines the type of data that you accept. If this API call does not return JSON, then it could be just saying "I have nothing to say to you then". You can try just deleting that whole line.
The Content-Type in your HttpClient code will be application/json; charset=utf-8, whereas you set it to just application/json in your WebRequest code. I don't see why the charset would make it choke, but if changing #1 doesn't work, you can try setting the Content-Type directly and see if it makes any difference:
var content = new StringContent("");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
I am having an issue when calling an external third-part soap web service: the error am getting is 'The remote server returned an error: (500) Internal Server Error.'(from client), but the problem is when I do call using SoapUI 5.4.0 (on the same PC under the same user) it runs fine. The code works on any other web services.
Can someone give me any idea?
using System;
using System.IO;
using System.Net;
using System.Xml;
namespace ConsoleApp1
{
class Program
/// Soap WebService call
public static void Execute()
{
HttpWebRequest request = CreateWebRequest();
request.Credentials = CredentialCache.DefaultCredentials;
XmlDocument soapEnvelopeXml = new XmlDocument();
NewMethod(soapEnvelopeXml);
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
Console.WriteLine("Done!");
Console.ReadKey();
}
}
}
private static void NewMethod(XmlDocument soapEnvelopeXml)
{
soapEnvelopeXml.LoadXml(xml: #"<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:out=""http://www.test.com/test/Services/Outage""><soap:Header/><soap:Body><out:GetLocations/></soap:Body></soap:Envelope>");
}
/// Create a soap webrequest to [Url]
public static HttpWebRequest CreateWebRequest()
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://test:557/OutageService.svc");
webRequest.ContentType = #"application/soap+xml;charset=UTF-8";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
static void Main(string[] args)
{
Execute();
}
}
}
And SoapUI 5.4.0 (I've changed the domain name to 'test')
XML
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:out="http://www.test.com/test/Services/Outage">
<soap:Header/>
<soap:Body>
<out:GetLocations/>
</soap:Body>
</soap:Envelope>
RAW
POST http://test:557/OutageService.svc HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="http://www.test.com/test/Services/Outage/IOutageService/GetLocations"
Content-Length: 390
Host: test:557
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Respond
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 155883
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 12 Mar 2018 16:09:46 GMT
<s:Envelope xmlns:s="http://www.w3.org/2003/05/so.........
SoapUI
Thank you #Broom!
I've done a few tests using fiddler and I've got the following message:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/fault</a:Action></s:Header><s:Body><s:Fault><s:Code><s:Value>s:Sender
</s:Value><s:Subcode><s:Value>
a:ActionMismatch</s:Value></s:Subcode></s:Code><s:Reason><s:Text xml:lang="en-US">
The SOAP action specified on the message, '"http://www.test.com/test/Services/Outage/IOutageService/GetLocations"',
does not match the HTTP SOAP Action, 'http://www.test.com/test/Services/Outage/IOutageService/GetLocations'.
</s:Text></s:Reason><s:Detail><a:ProblemHeaderQName>a:Action</a:ProblemHeaderQName></s:Detail></s:Fault></s:Body></s:Envelope>
so in my code I've changed
private static void NewMethod(XmlDocument soapEnvelopeXml)
{
soapEnvelopeXml.LoadXml(xml: #"<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:out=""http://www.test.com/test/Services/Outage""><soap:Header/><soap:Body><out:GetLocations/></soap:Body></soap:Envelope>");
}
to the following
soapEnvelopeXml.LoadXml(xml: #"<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:out=""http://www.test.com/test/Services/Outage""><soap:Header xmlns:wsa=""http://www.w3.org/2005/08/addressing""><wsa:Action>http://www.test.com/test/Services/Outage/IOutageService/GetLocations</wsa:Action></soap:Header><soap:Body><out:GetLocations/></soap:Body></soap:Envelope>");
Which defines the Action in Content-Type
Content-Type: application/soap+xml;charset=UTF-8;action="http://www.test.com/test/Services/Outage/IOutageService/GetLocations"
And then I've changed Content-Type in WebRequest
var contentString = #"application/soap+xml;charset=UTF-8;action=""http://www.test/test/Services/Outage/IOutageService/GetLocations""";
webRequest.ContentType = contentString;
And the code receives the xml from web service.
Just need to be aware of double quotes!!!!
I need to replicate a HTTP request using C# and the HttpWebRequest, that looks like this:
HEADER: POST /upnp/control/x_contact HTTP/1.1 Host: fritz.box:49000
Connection: Keep-Alive User-Agent:...
So far I got everything working, except for the part after the POST
"/upnp/control/x_contact HTTP/1.1".
How would I have to modify the HttpWebRequest to get these additional data to the server?
PS: This is how the java code looks, that generates the correct request. I would like to port this code to C# and send the same request from there:
socket = new Socket(InetAddress.getByName("fritz.box"), 49000);
// Send header
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
writer.write("POST /igdupnp/control/WANIPConn1 HTTP/1.1");
writer.write("Host: fritz.box:49000\r\n");
writer.write("SOAPACTION: \"urn:schemas-upnp-org:service:WANIPConnection:1#GetStatusInfo\"\r\n");
writer.write("Content-Type: text/xml; charset=\"utf-8\""+"\r\n");
writer.write("Content-Length: " + myData.length() + "\r\n");
writer.write("\r\n");
// Send data
writer.write(myData);
writer.flush();
And this is my C# code so far (producing an incomplete HTML request):
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create (#"http://fritz.box:49000");
webRequest.Headers.Add ("SOAPACTION", "urn:schemas-upnp-org:service:WANIPConnection:1#GetStatusInfo");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
I am trying to send Facebook graph link to the AppEngine server. I receive "Malformed string exception". Here is my method sending json to server:
public async Task<string> SendJSONData(string urlToCall, string JSONData)
{
// server to POST to
string url = urlToCall;
// HTTP web request
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
// Write the request Asynchronously
using (var stream = await Task.Factory.FromAsync<Stream>(httpWebRequest.BeginGetRequestStream,
httpWebRequest.EndGetRequestStream, null))
{
//create some json string
string json = "action=" + JSONData;
// convert json to byte array
byte[] jsonAsBytes = Encoding.UTF8.GetBytes(json);
// Write the bytes to the stream
await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
}
WebResponse response = await httpWebRequest.GetResponseAsync();
StreamReader requestReader = new StreamReader(response.GetResponseStream());
String webResponse = requestReader.ReadToEnd();
return webResponse; }
Here is what I sniff using Fiddler:
POST http://x.appspot.com/register HTTP/1.1
Accept: */*
Content-Length: 376
Accept-Encoding: identity
Content-Type: application/x-www-form-urlencoded
User-Agent: NativeHost
Host: x.appspot.com
Connection: Keep-Alive
Pragma: no-cache
action={
"mailFb": "mail#gmail.com",
"userName": "Michael",
"userSurname": "w00t",
"nickname": "Michael w00t",
"userSex": "male",
"userAvatar": "https://graph.facebook.com/myperfectid/picture?type=large&access_token=BlahblahblahblahToken"
}
So everything looks fine, but the problem is that i receive the following error in AppEngine log:
2013-03-02 17:52:10.431 /register 500 56ms 0kb NativeHost
W 2013-03-02 17:52:10.427 /register com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated string at line 7 column 79 at com.google.g
C 2013-03-02 17:52:10.429 Uncaught exception from servlet com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated string at line 7 colu
I managed to narrow the problem to its source, which is "&" character. So my question is, how to fix the code, so that it works with AppEngine.
Oh, here is how i read the received data on the server:
gson.fromJson(reader, User.class);
The problem is highlighted by the fact you're claiming you are sending "Content-Type: application/x-www-form-urlencoded"
But it isn't. Hence the error.
The correct encoding for & is &.
Has been using Service Reference without any success:
Web service return only XML
Now I am using the raw SOAP message to do it:
XmlDocument doc = new XmlDocument();
doc.Load("Service.xml");
// create the request to your URL
Uri wsHost = new Uri("http://www.rrr.net/services/Connect");
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(wsHost);
// add the headers
// the SOAPACtion determines what action the web service should use
request.Headers.Add("SOAPAction", "act");
// set the request type
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Accept = "text/xml";
request.Method = "POST";
// add our body to the request
Stream stream = request.GetRequestStream();
doc.Save(stream);
stream.Close();
// get the response back
using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() )
{
Stream dataStream = response.GetResponseStream();
StreamReader dataReader = new StreamReader(dataStream);
// Use Linq to read the xml response
using (XmlReader reader = XmlReader.Create(dataStream))
{
The post is correct, but response always give me text/plain empty result, the reponse header:
Headers = {Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/plain
Date: Thu, 06 Sep 2012 15:59:28 GMT
}
The SOAP message is, act is the function:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webService">
<soapenv:Header/>
<soapenv:Body>
<web:act>
<web:d1>1</web:d1>
<web:d2>14</web:d2>
</web:act>
</soapenv:Body>
</soapenv:Envelope>
I use SoapUI, below is the raw request from SoapUI, it return a xml result:
POST http://www.rrr.net/services/Connect HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Content-Length: 516
Host: www.rrr.net
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Thank you.
SOAP webservices require action/method to be specified (and NOT empty). If you don't know which action you want you can look at webservice WSDL by invoking the webservice with queryString "?WSDL". I.e. www.yourSite.com/your/Web/Service/URL?WSDL
You must specify an action in both the request and also the service interface. You can set the action value on the interface member using the attributes shown below and then in the request using the method you have used but by specifying the action name you used in the contract:
The attributes on the interface member
[OperationContract Name="YourActionName"]
[WebInvoke (Method = "POST", UriTemplate = "YourActionName")]
Message YourServiceFunction();
One method of specifying the action on the message
Message inputMessage = Message.CreateMessage (MessageVersion.Soap, "YourActionName", reader);