Web Service always return empty plain/text - c#

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);

Related

C# Soap 1.2 WebService

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!!!!

How to read http response of multi-part stream in c#

I need to receive response from a http server using c#.The response is a multi-part stream; the header would contain
Content-Type: multipart/x-mixed-replace; boundary=userdata
The body of response would be similar to below:
--userdata
Content-type: text/plain
Content-length: <length-of-content>
UserId: <user-Id>
ParentId: <parent-Id>
ParentName: <parent-name>
Time: <time>
--userdata
Content-type: text/plain
Content-length: <length-of-content>
UserId: <user-Id>
ParentId: <parent-Id>
ParentName: <parent-name>
Time: <time>
I need to recieve the response and save these information continuously in
List<UserData>
which contains the list of UserData class having information of user.
Http response url is like
http://username:password#userIp:port-number/transactionStream
I have written following code but no result, Please help:
NetworkCredential networkCredential = new NetworkCredential(this.UserName, this.Password);
string requestingURL = "http://" + this.UserName + ":" + this.Password + "#" +this.UserIp+ ":" + this.PortNo + "/transactionDataStream";
Uri uri = new Uri(requestingURL);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Credentials = networkCredential;
HttpWebResponse Answer = (HttpWebResponse)request.GetResponse();
Stream aStream = Answer.GetResponseStream();
StreamReader aStreamReader = new StreamReader(aStream);
string response = aStreamReader.ReadToEnd();
I've used this before and it works well. StreamingMultipartFormDataParser
The Http Multipart Parser does it exactly what it claims on the tin: parses multipart/form-data. This particular parser is well suited to parsing large data from streams as it doesn't attempt to read the entire stream at once and produces a set of streams for file data.

.NET SOAP request returns "400 Bad Request"

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.

Malformed string exception while sending "&" in Json to AppEngine

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 &.

.NET C# using HTTPrequest similar to Curl script

I´m using .NET C# and want to use HTTPrequest to make a POST in the same way as it is written in Curl:
curl
--header ’Accept: text/html’
--user ’test1:password’
--Form ’wait=0’
--Form ’data=#data.csv;type=text/csv’
some URL address here
I´m getting Error 500 Internal error from the Internet server.
The data to be send is a CSV file.
My source code in C#:
string data = "Time, A, B\n20120101, 100, 24\n20120102\n, 101, 27";
// Create a request using a URL that can receive a post.
request = WebRequest.Create(url);
//Set authorization
request.Credentials = new NetworkCredential(username, password);
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(data);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the original response.
WebResponse response = request.GetResponse();
this.Status = ((HttpWebResponse)response).StatusDescription;
// Get the stream containing all content returned by the requested server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content fully up to the end.
string responseFromServer = reader.ReadToEnd();
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
What am I doing wrong?
cURL uses the multipart/form-data content type to create its requests. I think this is required in your case as you are passing both a text parameter and a file. Sadly the .Net framework does not appear to have built in support for creating this content type.
There is a question on SO that gives example code for how to do it yourself here: Multipart forms from C# client
For reference the HTTP request generated by that cURL command looks something like this:
POST http://www.example.com/example HTTP/1.1
Authorization: Basic J3Rlc3Q6cGFzc3dvcmQn
User-Agent: curl/7.33.0
Host: www.example.com
Accept: text/html
Connection: Keep-Alive
Content-Length: 335
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------99aa46d554951aa6
--------------------------99aa46d554951aa6
Content-Disposition: form-data; name="'wait"
0'
--------------------------99aa46d554951aa6
Content-Disposition: form-data; name="'data"; filename="data.csv"
Content-Type: text/csv'
Time, A, B\n20120101, 100, 24\n20120102\n, 101, 27
--------------------------99aa46d554951aa6--
Doesn't data need to be URL encoded for a form post? http://en.wikipedia.org/wiki/POST_%28HTTP%29#Use_for_submitting_web_forms

Categories