cURL with user authentication in C# - c#

I want to do the following cURL request in c#:
curl -u admin:geoserver -v -XPOST -H 'Content-type: text/xml' \
-d '<workspace><name>acme</name></workspace>' \
http://localhost:8080/geoserver/rest/workspaces
I have tried using a WebRequest:
string url = "http://localhost:8080/geoserver/rest/workspaces";
WebRequest request = WebRequest.Create(url);
request.ContentType = "Content-type: text/xml";
request.Method = "POST";
request.Credentials = new NetworkCredential("admin", "geoserver");
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>my_workspace</name></workspace>");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
WebResponse response = request.GetResponse();
...
But I get an error: (400) Bad request.
If I change the request credentials and add the authentication in the header:
string url = "http://localhost:8080/geoserver/rest/workspaces";
WebRequest request = WebRequest.Create(url);
request.ContentType = "Content-type: text/xml";
request.Method = "POST";
string authInfo = "admin:geoserver";
request.Headers["Authorization"] = "Basic " + authInfo;
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>my_workspace</name></workspace>");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
WebResponse response = request.GetResponse();
...
Then I get: (401) Unauthorised.
My question is: Should I use another C# class like WebClient or HttpWebRequest or do I have to use the curl bindings for .NET?
All comments or guidance would be appreciated.

HTTP Basic authentication requies everything after "Basic " to be Base64-encoded, so try
request.Headers["Authorization"] = "Basic " +
Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));

The solution to my question was changing the ContentType property. If I change the ContentType to
request.ContentType = "text/xml";
the request works in both cases, if I also convert the authInfo to a Base64String in the last example like Anton Gogolev suggested.

Using:
request.ContentType = "application/xml";
request.Credentials = new NetworkCredential(GEOSERVER_USER, GEOSERVER_PASSWD);
also works. The second sets authentication information.

Or, if you want to use HttpClient:
var authValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("admin:geoserver")));
try
{
var client = new HttpClient()
{
DefaultRequestHeaders = { Authorization = authValue }
};
string url = "http://{BASE_URL}";
client.BaseAddress = new Uri(url);
var content = new StringContent("<workspace><name>TestTestTest</name></workspace>",
Encoding.UTF8, "text/xml");
var response = await client.PostAsync($"/{PATH_TO_API}/", content);
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
Console.WriteLine(ex.Message);
}

Related

c # desktop app error 401 How can I send the data

I do not have a problem getting tokens in the desktop application I developed. But when I try to send data, I get a 401 error.
HttpWebRequest webRequest;
string requestParams = "";
webRequest = (HttpWebRequest)WebRequest.Create("url");
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.Headers.Add("x-api-key", "112233");
webRequest.Headers.Add("AccessToken", token);
byte[] byteArray = Encoding.UTF8.GetBytes(req);
webRequest.ContentLength = byteArray.Length;
using (Stream requestStream = webRequest.GetRequestStream())
{
requestStream.Write(byteArray, 0, byteArray.Length);
}
using (WebResponse response = webRequest.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
StreamReader rdr = new StreamReader(responseStream, Encoding.UTF8);
string Json = rdr.ReadToEnd();
}
}
The problem is about setting the token. First, you need to be sure what your server wants as a token. You can try this for the Bearer token.
webRequest.Headers.Add("Authorization", "Bearer " + token);
For your program to work, you have to provide an actual URL, not just the string "url", in
webRequest = (HttpWebRequest)WebRequest.Create("url");
Post to api with c # windows form application. oauth2.0
using (var client1 = new HttpClient ())
{
client1.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client1.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token());
client1.DefaultRequestHeaders.Add("x-api-key", "xxxx");
var builder = new UriBuilder(new Uri("you - url"));
HttpRequestMessage request1 = new HttpRequestMessage(HttpMethod.Post, builder.Uri);
request1.Content = new StringContent("{\"values\":" + JsonConvert.SerializeObject("you -data")+ "}", Encoding.UTF8, "application/json");
HttpResponseMessage response = await client1.SendAsync(request1);
};

What the difference between this Post webrequest and similar request in Postman?

I want to make Post request to "https://sslecal2.forexprostools.com/ajax.php". So there is my code:
string URI = "https://sslecal2.forexprostools.com/ajax.php";
string requestBody = String.Format("{{\"dateFrom\": \"{0}\", \"dateTo\": \"{1}\", \"timeZone\": {2}, \"action\": \"{3}\"}}",
"2018-12-24", "2018-12-24", 18, "filter"); //json format
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URI); //make request
request.Method = "POST";
request.UserAgent = "";
request.Headers.Add("X-Requested-With", "XMLHttpRequest");
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(requestBody); //write your request payload
}
WebResponse response = request.GetResponse();
string jsonData = String.Empty;
using (var reader = new StreamReader(response.GetResponseStream()))
{
jsonData = reader.ReadToEnd();
}
response.Close();
I made something not correct in "requestBody" in string " string requestBody = String.Format("{{\"dateFrom\"..." because I get 200 and empty html answer.
And I attach the screens of the same request in postman with html code in answer. This request in postman processes well.
What the difference between this Post webrequest and request in Postman?
With postman you posting different format data. To get same thing in code you need to change request body format and set content type of request:
string URI = "https://sslecal2.forexprostools.com/ajax.php";
string requestBody = String.Format("dateFrom={0}&dateTo={1}&timeZone={2}&action={3}",
"2018-12-24", "2018-12-24", 18, "filter"); //<-- Change this
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URI);
request.Method = "POST";
request.UserAgent = "";
request.Headers.Add("X-Requested-With", "XMLHttpRequest");
request.ContentType = "application/x-www-form-urlencoded"; //<-- Add this
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(requestBody);
}
WebResponse response = request.GetResponse();
string jsonData = String.Empty;
using (var reader = new StreamReader(response.GetResponseStream()))
{
jsonData = reader.ReadToEnd();
}
response.Close();
In PostMan, if you click the "Code" in the top right, under the send button, you can choose C# (RestSharp).. If you're not using RestSharp, there's a small amount of work to do to convert it to something else, but the basics are all there.
Here's the autogen output for your case (RestSharp):
var client = new RestClient("https://sslecal2.forexprostools.com/ajax.php");
var request = new RestRequest(Method.POST);
request.AddHeader("Postman-Token", "bfd1a3b3-983f-4160-a091-6f0962413e58");
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("X-Requested-With", "XMLHttpRequest");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("undefined", "dateFrom=2018-01-24&dateTo=2018-01-24&timeZone=18&action=filter", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Converting it to HttpWebRequest requires:
AddHeader -> Headers.Add
Specify method
Body data is set differently - take PostMan's string and write it to the request stream
Or install RestSharp free from NuGet

Post with parameters using HttpWebRequest in C#

Having the following code:
var request = HttpWebRequest.Create("https://api.channeladvisor.com/oauth2/token");
request.ContentType = "text/html";
request.Method = "POST";
request.Headers.Add("cache-control","no-cache");
request.Headers.Add("Authorization", "Basic " + Base64Translator.ToBase64(System.Text.Encoding.ASCII, devKey+":"+sharedSecret));
string postData = " grant_type=refresh_token&refresh_token=a12SL1bHhJwerxM2NFth2efZw0yIW7462kAhR43UCJA";
var data = Encoding.ASCII.GetBytes(postData);
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
What's wrong? I can't do the request but I can using external programs like Postman. Do you see anything wrong in the header?
Error: "The remote server returned an error: (400) Bad Request."
Thanks!
Your content type should be application/x-www-form-urlencoded.
request.ContentType = "application/x-www-form-urlencoded";

Connecting to a REST webservice in C#

I am not familiar with REST webservices, but I am trying to get a response from one of them in a C# application.
I am trying to connect to the webservice and authenticate my application to get a token. For this, I have an URL, a login and a password.
When I call the authentication method with cURL tool, I get a « success :true» answer, followed with the token string.
But when I try to do the same with my C# code, I always get a « success :false» answer and no token.
Can somebody help me to understand what is missing in my C# code to get the correct answer ? Thank you.
The cURL request (given by the webservice owner) is:
curl -X POST -d "{\"user\":\"mylogin\",\"pwd\":\"mypassword\"}" \
-H "Content-Type: application/json" http://webserviceURL/authenticate
My code is the following : (restlogin, restpassword and resturl are three strings and get the correct values for the connection. The resulting string is obtained in the variable nammed token).
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resturl + "authenticate");
request.Method = "POST";
request.Credentials = new NetworkCredential(restlogin, restpassword);
request.ContentType = "application/json";
request.Timeout = 30000;
request.ReadWriteTimeout = 30000;
request.Accept = "application/json";
request.ProtocolVersion = HttpVersion.Version11;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
{
using (Stream respStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream, Encoding.UTF8);
token = reader.ReadToEnd();
reader.Close();
reader.Dispose();
response.Close();
}
}
As per my comment to the question, you are not sending your credentials in the request body. With request.Credentials you're setting the Authentication Header in your HttpRequest.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resturl + "authenticate");
request.Method = "POST";
request.ContentType = "application/json";
request.Timeout = 30000;
request.ReadWriteTimeout = 30000;
request.Accept = "application/json";
request.ProtocolVersion = HttpVersion.Version11;
// Set your Response body
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = "{\"user\":\"" + restlogin + "\"," +
"\"pwd\":\"" + restpassword + "\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
{
using (Stream respStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream, Encoding.UTF8);
token = reader.ReadToEnd();
reader.Close();
reader.Dispose();
response.Close();
}
}

How can I convert curl request to WebRequest in C#?

I'm trying to convert curl request to WebRequest in C# but not able to get the response as it always returns 401 unauthorized error
Here is the working curl request:
curl -k -v https://api.demo.peertransfer.com/v1/transfers -H "Content-Type: application/json" -X POST -d "{\"provider\":\"HUL\",\"payment_destination\":\"hult-applicationfee\",\"amount\":\"29000\",\"callback_url\":\"http://studentapplication.local/en/nextsteps\",\"callback_id\":\"abc1234546asas\",\"dynamic_fields\":{\"student_id\":\"32453245\",\"student_first_name\":\"Candy\",\"student_last_name\":\"Student\"}}" -H "X-Peertransfer-Digest: zYUt+Pn0A06wsSbCrrbAZn68Aslq9CbSUAKBrUEwIzI="
Output:
The result in the red box is what I need to get in WebRequest Response,
here is my C# code
private void testnewfunc()
{
string value = "{\"provider\":\"HUL\",\"payment_destination\":\"hult-applicationfee\",\"amount\":\"29000\",\"callback_url\":\"http://studentapplication.local/en/nextsteps\",\"callback_id\":\"abc1234546asas\",\"dynamic_fields\":{\"student_id\":\"32453245\",\"student_first_name\":\"Candy\",\"student_last_name\":\"Student\"}}";
var URI = new Uri("https://api.demo.peertransfer.com/v1/transfers");
byte[] data = System.Text.ASCIIEncoding.Default.GetBytes(value);
var requst = (HttpWebRequest)WebRequest.Create(URI);
requst.UserAgent = "curl/7.43.0";
requst.Method = "POST";
requst.KeepAlive = true;
requst.AllowAutoRedirect = true;
requst.ContentType = " application/json";
requst.ContentLength = data.Length;
// wc.Headers["Content-Type"] = "application/json";
requst.Accept = "*/*";
//Or any other encoding type.
string result = System.Convert.ToBase64String(data);
var uname = "hultdemo2015";
var pword = "gEejgC0GF8pCbI7C";
var creds = string.Format("{0}:{1}", uname, pword);
creds = Convert.ToBase64String(Encoding.ASCII.GetBytes(creds));
requst.Headers["Authorization"] = string.Format("{0} {1}", "Basic", creds);
requst.Headers["X-Peertransfer-Digest"] = string.Format("{0}", "zYUt+Pn0A06wsSbCrrbAZn68Aslq9CbSUAKBrUEwIzI=");
using (Stream stream = requst.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var httpResponse = (HttpWebResponse)requst.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
//Now you have your response.
//or false depending on information in the response
// return true;
}
}
Not sure what I'm making wrong in the WebRequest.
Here's my solution:
var client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
var message = new HttpRequestMessage(HttpMethod.Post, new Uri("https://api.demo.peertransfer.com/v1/transfers"));
message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
message.Headers.Add("X-Peertransfer-Digest", "zYUt+Pn0A06wsSbCrrbAZn68Aslq9CbSUAKBrUEwIzI=");
message.Content = new StringContent("{\"provider\":\"HUL\",\"payment_destination\":\"hult-applicationfee\",\"amount\":\"29000\",\"callback_url\":\"http://studentapplication.local/en/nextsteps\",\"callback_id\":\"abc1234546asas\",\"dynamic_fields\":{\"student_id\":\"32453245\",\"student_first_name\":\"Candy\",\"student_last_name\":\"Student\"}}", Encoding.UTF8, "application/json");
var responseMessage = await client.SendAsync(message);
MessageBox.Show(string.Format("Status Code: {0}{1}Content-Type: {2}{1}Date: {3}{1}Location:{4}", responseMessage.StatusCode, Environment.NewLine, responseMessage.Content.Headers.ContentType, responseMessage.Headers.Date, responseMessage.Headers.Location));
And here's the response from the server (same as curl):
Version compatible with .Net 4.0
var data = "{\"provider\":\"HUL\",\"payment_destination\":\"hult-applicationfee\",\"amount\":\"29000\",\"callback_url\":\"http://studentapplication.local/en/nextsteps\",\"callback_id\":\"abc1234546asas\",\"dynamic_fields\":{\"student_id\":\"32453245\",\"student_first_name\":\"Candy\",\"student_last_name\":\"Student\"}}";
var request = (HttpWebRequest)WebRequest.Create(new Uri("https://api.demo.peertransfer.com/v1/transfers"));
request.Method = "POST";
request.AllowAutoRedirect = false;
request.Accept = "*/*";
request.Headers.Add("X-Peertransfer-Digest", "zYUt+Pn0A06wsSbCrrbAZn68Aslq9CbSUAKBrUEwIzI=");
request.ContentType = "application/json";
request.ContentLength = data.Length;
using (var reqStream = request.GetRequestStream())
using (var writer = new StreamWriter(reqStream))
{
writer.Write(data);
}
var response = request.GetResponse();
MessageBox.Show(response.Headers.ToString());
Make sure you include these using statements:
using System.IO;
using System.Net;
and these are the response headers from the server:

Categories