HTTP POST request body returns code 400 - c#

I'm using C#.
I'm trying to make a POST request with the following request body:
{"taskId":15, "values" : [{"Key": "myKey","Value":"<Items>
<Item>
<Item id="17362"/>
</Item>
</Items>"}]}
And the following code:
var postData = "{\"taskId\":15, \"values\" : [{\"Key\": \"myKey\",\"Value\":\"<Items> <Item> <Item id=\"17362\"/> </Item> </Items>\"}]}"
var data = Encoding.ASCII.GetBytes(postData);//postData is the reqeust body
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
And got the following execption:
The remote server returned an error: (400) Bad Request
How can i solve it? Thanks!
Edit:
The web method signature is: MyWebMethod(int taskId, Dictionary<string, object> values)
And the both requests are works for me:
{"taskId":15, "values" : 123 }]}
{"taskId":15, "values" : "123" }]}
My Web Server is C# WebService (.asmx)

Problem solved by replace " to ".
The disadvantage is that i need to change my server side to replace again " to ".

Related

WebService Call from .net C# getting error : (502) Bad Gateway

Trying to call WebServices from C# and getting below error:
System.Net.WebException: 'The remote server returned an error: (502) Bad Gateway
Code:
WebRequest request = WebRequest.Create("https://xxxxx/cgi/webservice.pl?function=get_latest_ts_values&site_list=130105B&datasource=AT&varfrom=10.00&varto=10.00&lookback=60&format=csv");
request.Method = "GET";
WebResponse response = request.GetResponse();
using (Stream dataStream = response.GetResponseStream() )
{
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
Console.ReadLine();
}
But works fine when i use Postman or just copy url in browser and also works fine with below python code:
import requests
dataload = {}
dataurl = "https://xxxxx/cgi/webservice.pl?function=get_latest_ts_values&site_list=130105B&datasource=AT&varfrom=10.00&varto=10.00&lookback=60"
headers = {}
response = requests.request("GET", dataurl, headers=headers, data=dataload)
for dataresp in response:
print(dataresp)
What am I doing wrong with C# code?
The uri for the WebRequest has the query parameter &format=csv. Maybe this is why you are getting a 502. The Python request is missing that query parameter. Did you try the WebRequest by removing that part?
Could be incorrect content type or user agent having the wrong information. Postman could be setting these values without your knowledge. Might try in the exception seeing if there is a a response stream and read it through a streamreader to see if there is any more information you're not seeing to point you in the correct direction.
Ended up using RestSharp and it works fine. (https://www.nuget.org/packages/RestSharp)
string Uri = "https://xxxx/cgi/webservice.pl?xxxx";
var client = new RestSharp.RestClient(Uri);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

Is it possible to consume an XML RPC service using a basic HTTP request?

I've been tasked to consume an XML RPC API, and I'm quite unfamiliar with it. I've glanced around a few pages describing it, and I've seen there's a few libraries out there as well.
However, it's left me with a feeling that all it comes down to is posting an HTTP request, similar to REST, except using XML in the body as opposed to JSON.
I imagine constructing an HTTP request similar to the below:
POST /path/service.cfm HTTP/1.0
From: example#example.com
User-Agent: whatever/1.0
Content-Type: application/xml
Content-Length: 155
<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>40</i4></value>
</param>
</params>
</methodCall>
Am I on the right track? The abundance of libraries around give me the feeling that perhaps it's more complicated than what I thought. Ideally I'd like to write a quick client in .NET myself.
static void Main(string[] args)
{
HttpWebRequest request = BuildWebRequest();
var response = request.GetResponse() as HttpWebResponse;
var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
private static HttpWebRequest BuildWebRequest()
{
var request = WebRequest.Create(Url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/xml";
request.Timeout = 40000;
request.ServicePoint.Expect100Continue = true;
string body = #"<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>40</i4></value>
</param>
</params>
</methodCall>";
byte[] bytes = Encoding.Default.GetBytes(body);
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
return request;
}
Yes it is not a problem, here is an example how to do it. In string body you must write only your xml and you should put the correct content type. If the service provider have requirements like specific Headers you should add them.

ContentMD5Missing - Amazon Webservice

I'm trying to post to Feed -> SubmitFeed.
However the exception I receive back is:
you must pass a Content-MD5 HTTP header for your feed so we can be
sure it was not corrupted (e.g. dropped a 0 from a price) before we
process it
What I don't understand is the documentation states that it is optional so unsure why I am receiving this. Plus I am actually passing something through.
XML
<?xml version="1.0" encoding="UTF-8" ?>
- <AmazonEnvelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" schemaLocation="amzn-base.xsd">
- <Header>
<DocumentVersion>1</DocumentVersion>
<MerchantIdentifier>A1ddWU5JfffWJEddV9Xf668B</MerchantIdentifier>
</Header>
<MessageType>Product</MessageType>
<PurgeAndReplace>false</PurgeAndReplace>
- <Message>
<MessageId>1</MessageId>
<OperationType>Update</OperationType>
</Message>
- <Product>
<SKU>3308ff6-01</SKU>
</Product>
</AmazonEnvelope>
How I attach the Body/Header
var request = Helper.CreateWebRequest(xmlRequest.Config, genericparameters, signatureHelpers);
request.Headers.Add("x-amazon-user-agent", amazonHostAgent);
request.Method = "POST";
request.ContentType = amazonConfig.ContentType;
request.Timeout = 50000;
Helper.AddXmlDocumentToRequest(xmlRequest.XmlDocument.InnerXml, request);
public static void AddXmlDocumentToRequest(string xmlDocument, WebRequest request)
{
var bytes = Encoding.ASCII.GetBytes(xmlDocument);
request.ContentLength = bytes.Length;
var requestStream = request.GetRequestStream();
request.Headers.Add("Content-MD5", GetMd5HashFromStream(bytes));
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
}
public static string GetMd5HashFromStream(byte[] bytes)
{
using (var md5 = MD5.Create())
{
var hash = md5.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
}
Within the request when I drill down to Headers I have the following:
{x-amazon-user-agent: MWSApplication/1.0 (Language=c#)
Content-Type: text/xml
Host: mws.amazonservices.co.uk
Content-Length: 478
Expect: 100-continue
Content-MD5: 1xLxj5Y+WVsAVR9BbQfzQA==
}
When I run the xml through scratchpad it returns the same Content-MD5: 1xLxj5Y+WVsAVR9BbQfzQA==
Am I doing something wrong?
Thanks,
Clare
This might not be the answer for everyone however it was for me and if it helps one other person I will be happy :-)
Me being very stupid, added the header after the streaming, this is not what you should be doing.
Create the URL
Add headers and other elements i.e.
request.ContentType
Stream documents (body of request) if required
request.GetResponse.
Thanks,
Clare

Soap Request in C#

I've got a soap request I've written in http & javascript but I cannot seem to convert it into C# correctly.
Original: (Works)
<button onclick="doStuff()" type="submit">Send</button>
<textarea name="REQUEST_DATA" cols=120 rows=17 >
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<createModifyRequest>
<username>josephs</username>
<lookupIds>
<lookupIds>4225</lookupIds><!--firepass-->
</lookupIds>
</createModifyRequest>
</soap:Body>
</soap:Envelope>
</textarea>
<script language="javascript">
function doStuff() {
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.3.0");
xmlhttp.open("POST", "http://tpdev-itreq.transpower.co.nz:7777/usr/services/CreateModifyRequest", false);
xmlhttp.setRequestHeader("SOAPAction", "createModifyRequest");
var userpass = "josephs" + ":" + "pass";
xmlhttp.setRequestHeader("Authorization", "Basic " + (userpass));
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send(REQUEST_DATA.value);
}
Converted in C# (Does not work)
private void button1_Click(object sender, EventArgs e)
{
string soap =#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<createModifyRequest>
<username>josephs</username>
<lookupIds>
<lookupIds>4225</lookupIds>
<!--firepass-->
</lookupIds>
</createModifyRequest>
</soap:Body>
</soap:Envelope>";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://tpdev-itreq.transpower.co.nz:7777/usr/services/CreateModifyRequest");
req.Headers.Add("SOAPAction", "\"createModifyRequest\"");
var userpass = "josephs" + ":" + "pass";
req.Headers.Add("Authorization", "Basic " + (userpass));
// req.Headers.Add("Content-Type", "text/xml");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
using (Stream stm = req.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(soap);
}
}
WebResponse response = req.GetResponse();
Stream responseStream = response.GetResponseStream();
// TODO: Do whatever you need with the response
}
At the moment when I run the C# code I get an internal 500 server error, so what have I done wrong?
I have tried to reproduce your problem. Currently i am not able to create your request but i have generated local request with your data.
One thing I came to know is if I remove double quotes(") around the utf-8 and it worked fine.
Just pass charset=utf-8 instead of charset=\"utf-8\""
I am not sure it will work for you or not.
Is there a reason you can't just use Visual Studio's built in support for SOAP web services?
You can add a service reference or a web reference (depending on whch framework version you are targeting).
Then you can just use the proxy class that VS creates for you.
There's no advantage to writing all of the HTTP code yourself. Actually, there's a big disadvantage, in that you are aren't getting proper data types from the WSDL of your SOAP service.

Posting to a REST webservice from .NET?

I was trying to hit a web service using the instructions here:
http://help.seeclickfix.com/kb/api/creating-an-issue
I came up with the code below:
string paramContent = "api_key=afs684eas3ef86saef78s68aef68sae&issue[summary]=abeTest&issue[lat]=39.26252982783172&issue[lng]=-121.01738691329956&issue[address]=111 Abe St., Nevada City, CA";
byte[] paramBytes = Encoding.UTF8.GetBytes(paramContent);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://seeclickfix.com/api/issues.xml");
req.Method = "POST";
req.ContentLength = paramBytes.Length;
//req.ContentType = "application/x-www-form-urlencoded";
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(paramBytes, 0, paramBytes.Length);
}
using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) //HERE!
{
if (resp.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("POST failed. Received HTTP {0}", resp.StatusCode);
throw new ApplicationException(message);
}
StreamReader sr = new StreamReader(resp.GetResponseStream());
string response = sr.ReadToEnd();
Console.WriteLine(response + System.Environment.NewLine);
}
But at the line with the HERE! comment it throws the error:
The remote server returned an error: (500) Internal Server Error.
Can anyone see any problems with the way I am trying to implement this?
The 500 error you are getting indicates a problem on the server, not necessarily a problem with your code. You are successfully sending a request and receiving a response.
The problem could be a bug in the server, or a problem with the content of your request that the server can't handle. (Either way the server is failing to provide a valid error message like their documentation suggests it would)
You should start by making sure the content of your request is valid. See the example on the seeclickfix url you posted. Try directly posting with curl like they show, but use the content of your own message like so:
curl -v -d 'api_key=afs684eas3ef86saef78s68aef68sae&issue[summary]=abeTest&issue[lat]=39.26252982783172&issue[lng]=-121.01738691329956&issue[address]=111 Abe St., Nevada City, CA' http://seeclickfix.com/api/issues.xml
I expect you'll still get a 500 error (I just tried it and I got a 500 error).
Bottom line, it looks like their api is broken, not your logic.
You didn't do anything wrong. I tried making the request using Fiddler and it returned the same 500 status code.
If there was something wrong with the data you passed then they should have returned a 4XX response code.

Categories

Resources