I am trying write simple request to REST service.Follow to documentation from REST Service provider:
I should use in header Content-Type: application/json.
Response return in json format
For authorization proccess I have to send two headers one with APIKey and second with APISign
Controller PING in REST service to test code.
I use .net 2.0
string sha1String = APIKey + "/rest/ping" + APISecret;
string XRestApiSign = SHA1HashStringForUTF8String(sha1String);
string data = "";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(restServer);
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("X-Rest-ApiSign", XRestApiSign);
request.Headers.Add("X-Rest-ApiKey", APIKey);
request.ContentLength = data.Length;
StreamWriter requestWriter;
Stream webStream = request.GetRequestStream();
using (requestWriter = new StreamWriter(webStream, System.Text.Encoding.ASCII)) ;
{
requestWriter.Write(data);
}
request.BeginGetResponse((x) =>
{
using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(x))
{
List<string> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(response.GetResponseStream().ToString());
}
}, null);
I should get response string PONG but I get below message
Unexpected character encountered while parsing value: S. Path '', line 0, position 0
Is code OK ? Why I get this message?
This is mostly the case because the script that generates the JSON on the server side adds the byte order mark to the response.
In your case, however, you're trying to convert the stream to JSON, not the content of the stream. You need to read all text from the stream and deserialize the object from that. You need to call one of the methods on the stream that reads the content.
I modified my code with yours suggestion and it works. Now I have problem with send data :)
Subscription user1 = new Subscription
{
Email = "kubaIt#test.com.pl",
List = "xfct2bjcdv",
};
List<Subscription> user = new List<Subscription>();
user.Add(user1);
string json = JsonConvert.SerializeObject(user);
string data = json;
I added above. Other code is the same. I got error :The request was aborted: The request was canceled."
json = [{\"email\":\"kubaIt#test.com.pl\",\"list\":\"xfct2bjcdv\"}] //value from debuger
Related
I'm trying to get a simple response from a local .net site of my own. (Really I'm just trying to see what the content-body looks like from the server side.) Here is the controller method that's sending the response:
public HttpResponseMessage Post([FromBody]string value)
{
data.Add(value);
var msg = Request.CreateResponse(HttpStatusCode.Created);
msg.Headers.Location = new Uri(Request.RequestUri + "/" + (data.Count-1).ToString());
msg.Content = new StringContent(value);
return msg;
}
And here is the code that's making the request:
HttpWebRequest request;
request = (HttpWebRequest)WebRequest.Create ("http://localhost:50203/api/Values");
request.Method = "POST";
try
{
WebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
byte[] requestBody = ASCIIEncoding.ASCII.GetBytes(HttpUtility.UrlEncode("grant_type=client_credentials"));
request.ContentLength = requestBody.Length;
dataStream.Write(requestBody, 0, requestBody.Length);
StreamReader reader = new StreamReader(dataStream);
myString = reader.ReadToEnd();
}
I'm getting the response message: HTTP Error 411. The request must be chunked or have a content length. But as you can see I DO assign the content length in the line: request.ContentLength = requestBody.Length;.
Why am I getting this error?
Thanks to help from itsme86 I was able to see what was happening. It had to do with misunderstanding the HttpWebRequest method. I was trying to set the content length and write to the request after I'd already posted it using the GetResponse method. I should have posted the length first. This wasn't a particularly good question, and no one else should answer.
I'm not sure why this PayPal Pay operation is giving me this error even though I seem to have covered all the required fields:
Error Code: 81002 Severity: Error Message: Unspecified Method (Method Specified is not Supported)"
string postData = JsonConvert.SerializeObject(request);
value of postData:
"actionType=PAY
¤cyCode=USD
&cancelUrl=https%3a%2f%2fexample.com%2fcancel
&returnUrl=https%3a%2f%2fexample.com%2freturn
&requestenvelope.errorLanguage=en_US
&receiverList.receiver(0).email=recipientemail%40gmail.com
&receiverList.receiver(0).amount=0.05
&VERSION=94.0
&USER=bizemail-facilitator_api1.gmail.com
&PWD=xxxxx
&SIGNATURE=xxxxxxxxx"
Here's how I do the post:
SendRequest("https://api-3t.sandbox.paypal.com/nvp", postData);
public string SendRequest(string url, string postData)
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var encoding = new UTF8Encoding();
var requestData = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = (300*1000); //TODO: Move timeout to config
request.ContentLength = requestData.Length;
using (var stream = request.GetRequestStream()) {
stream.Write(requestData, 0, requestData.Length);
}
var response = request.GetResponse();
string result;
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII)) {
result = reader.ReadToEnd();
}
return result;
}
The method PAY doesn't exist on the NVP api. Full list of methods supported by that API is found here.
The PAY method, however, is defined in the Adaptive Payments API. Depending on your needs, you have two options:
Change the endpoint to https://svcs.paypal.com/AdaptivePayments/PAY and modify your values
Use another method, like DoDirectPayment, but I'm not sure it does what you want to.
I assume the value of postData is before you serialize it to a JSON string, instead of after as you say, since it is clearly not a JSON string.
If so, then it is already x-www-form-urlencoded, and you do not need to serialize it to a JSON string at all.
Or if you do after all, then change just this: request.ContentType = "application/json";
For the most part, I have managed quite quickly to move my code from standard .NET code to using RestSharp. This has been simple enough for GET processes, but I'm stumped for POST processes
Consider the following
var request = System.Net.WebRequest.Create("https://mytestserver.com/api/usr") as System.Net.HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json;version=1";
request.Headers.Add("Content-Type", "application/json;version=1");
request.Headers.Add("Accepts", "application/json;version=1");
request.Headers.Add("Authorize", "key {key}");
using (var writer = new System.IO.StreamWriter(request.GetRequestStream())) {
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes("{\n \"firstName\": \"Dan\",\n \"lastName\": \"Eccles\",\n \"preferredNumber\": 1,\n \"email\" : \"testuser#example.com\",\n \"password\": \"you cant get the wood\"\n}");
request.ContentLength = byteArray.Length;
writer.Write(byteArray);
writer.Close();
}
string responseContent;
using (var response = request.GetResponse() as System.Net.HttpWebResponse) {
using (var reader = new System.IO.StreamReader(response.GetResponseStream())) {
responseContent = reader.ReadToEnd();
}
This is fairly straight forward to move across, except for the serialisation code. Is there a particular way this has to be done for RestSharp? I've tried creating an object and using
var json = JsonConvert.SerializeObject(user);
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddBody(json);
but the server still comes back with an error.
I'm also currently using JSON.NET for deserialization to an error object when the user passes in bad data. Is there a way I can deserialize to error object based on a single string using RestSharp?
You're close, but you don't need to worry about serialization with RestSharp.
var request = new RestRequest(...);
request.RequestFormat = DataFormat.Json;
request.AddBody(user); // user is of type User (NOT string)
By telling it that the format is JSON, then passing your already-serialized-as-JSON string, RestSharp is actually encoding it again as a string.
So you pass the string: {"firstName":"foo"} and it actually gets sent to the server as a JSON string object: "{\"firstName\":\"foo\"}" (note how your JSON is escaped as a string literal), which is why it's failing.
Note you can also use an anonymous object for the request:
var request = new RestRequest(...);
request.RequestFormat = DataFormat.Json;
request.AddBody(new{
firstName = "Dan",
lastName = "Eccles",
preferredNumber = 1,
// etc..
});
You use the same typed objects with the response (eg, RestSharp deserializes for you):
var response = client.Execute<UserResponse>(request);
// if successful, response.Data is of type UserResponse
This code is for an outlook plugin. We're trying to POST to a page and are getting this error:
The remote server returned an error: (422) Unprocessable Entity.
The C# code is here:
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
Byte[] postData = asciiEncoding.GetBytes("email=e2#email.com&password=hunter2");
char[] resultHTML = asciiEncoding.GetChars(webClient.UploadData("http://url", "POST", postData));
string convertedResultHTML = new string(resultHTML);
Any idea what could be causing this?
POST data must be encoded prior to be sent out on the wire as ASCII, if you are sending character not in the ASCII range. You should try something like:
Byte[] postData = asciiEncoding.GetBytes(HttpUtility.UrlEncode("email=e2#email.com&password=hunter2"));
Because of its limited functionality, I avoid using WebClient and use WebRequest instead. The code below:
does not expect an HTTP 100 status code to be returned,
creates a CookieContainer to store any cookies we pick up,
sets the Content Length header, and
UrlEncodes each value in the post data.
Give the following a try and see if it works for you.
System.Net.ServicePointManager.Expect100Continue = false;
System.Net.CookieContainer cookies = new System.Net.CookieContainer();
// this first request just ensures we have a session cookie, if one exists
System.Net.WebRequest req = System.Net.WebRequest.Create("http://localhost/test.aspx");
((System.Net.HttpWebRequest)req).CookieContainer = cookies;
req.GetResponse().Close();
// this request submits the data to the server
req = System.Net.WebRequest.Create("http://localhost/test.aspx");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
((System.Net.HttpWebRequest)req).CookieContainer = cookies;
string parms = string.Format("email={0}&password={1}",
System.Web.HttpUtility.UrlEncode("e2#email.com"),
System.Web.HttpUtility.UrlEncode("hunter2"));
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parms);
req.ContentLength = bytes.Length;
// perform the POST
using (System.IO.Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
// read the response
string response;
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return;
using (System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()))
{
response = sr.ReadToEnd().Trim();
}
}
// the variable response holds the results of the request...
Credits: Hanselman, Simon (SO Question)
This is the RoR application telling you that you have not formed a request that it can handle; the destination script exists (otherwise you'd see a 404), the request is being handled (otherwise you'd get a 400 error) and it's been encoded correctly (or you'd get a 415 error) but the actual instruction can't be carried out.
Looking at it, you seem to be loading some email information. The RoR application could be telling you that the username and password is wrong, or that the user doesn't exist, or something else. It's up to the RoR application itself.
I think the code itself is good; it's just that the app at the other end isn't happy about doing what you ask it. Are you missing something else in the request information, like a command? (eg command=getnetemails&email=e2#email.com&password=hunter2) Are you sure the email/password combination you are passing is good?
see here for more on the 422 error.
Add the below line above your code.
System.Net.ServicePointManager.Expect100Continue = false;
Are you trying to access an authentication required page?
it was solved by returning xml instead of just unstructured text on the RoR side
This may be a pathetically simple problem, but I cannot seem to format the post webrequest/response to get data from the Wikipedia API. I have posted my code below if anyone can help me see my problem.
string pgTitle = txtPageTitle.Text;
Uri address = new Uri("http://en.wikipedia.org/w/api.php");
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string action = "query";
string query = pgTitle;
StringBuilder data = new StringBuilder();
data.Append("action=" + HttpUtility.UrlEncode(action));
data.Append("&query=" + HttpUtility.UrlEncode(query));
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
request.ContentLength = byteData.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream.
StreamReader reader = new StreamReader(response.GetResponseStream());
divWikiData.InnerText = reader.ReadToEnd();
}
You might want to try a GET request first because it's a little simpler (you will only need to POST for wikipedia login). For example, try to simulate this request:
http://en.wikipedia.org/w/api.php?action=query&prop=images&titles=Main%20Page
Here's the code:
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create("http://en.wikipedia.org/w/api.php?action=query&prop=images&titles=Main%20Page");
using (HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse())
{
string ResponseText;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
ResponseText = reader.ReadToEnd();
}
}
Edit: The other problem he was experiencing on the POST request was, The exception is : The remote server returned an error: (417) Expectation failed. It can be solved by setting:
System.Net.ServicePointManager.Expect100Continue = false;
(This is from: HTTP POST Returns Error: 417 "Expectation Failed.")
I'm currently in the final stages of implementing an C# MediaWiki API which allows the easy scripting of most MediaWiki viewing and editing actions.
The main API is here: http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/O2_XRules_Database/_Rules/APIs/OwaspAPI.cs and here is an example of the API in use:
var wiki = new O2MediaWikiAPI("http://www.o2platform.com/api.php");
wiki.login(userName, password);
var page = "Test"; // "Main_Page";
wiki.editPage(page,"Test content2");
var rawWikiText = wiki.raw(page);
var htmlText = wiki.html(page);
return rawWikiText.line().line() + htmlText;
You seem to be pushing the input data on HTTP POST, but it seems you should use HTTP GET.
From the MediaWiki API docs:
The API takes its input through
parameters in the query string. Every
module (and every action=query
submodule) has its own set of
parameters, which is listed in the
documentation and in action=help, and
can be retrieved through
action=paraminfo.
http://www.mediawiki.org/wiki/API:Data_formats