Understanding cURL Requests (C#) - c#

I am looking at some documentation that only shows examples of how to send web requests in cURL, however I'm using .NET and am trying to understand how I would send the same requests but using c#
Some examples of the requests I'm trying to send:
curl -X POST -H "Content-Type: application/json" -u "{username}":"{password}" -d #parameters.json "https://gateway.watsonplatform.net/natural-language-understanding/api/v1/analyze?version=2017-02-27"
with example parameters:
{
"text": "IBM is an American multinational technology company headquartered in Armonk, New York, United States, with operations in over 170 countries.",
"features": {
"entities": {
"emotion": true,
"sentiment": true,
"limit": 2
},
"keywords": {
"emotion": true,
"sentiment": true,
"limit": 2
}
}
}
I have made several different attempts to hit the API in C# with no success, always getting a Bad Request response so I must be doing something wrong. Here are some of the attempts I've made:
Attempt 1:
string url = $"{Properties.Settings.Default.WatsonLanguageUnderstandingUrl}/v1/analyze?version=2017-02-27";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
string auth = $"{Properties.Settings.Default.WatsonLanguageUnderstandingUsername}:{Properties.Settings.Default.WatsonLanguageUnderstandingPassword}";
string auth64 = Convert.ToBase64String(Encoding.ASCII.GetBytes(auth));
string credentials = $"Basic {auth64}";
httpWebRequest.Headers[HttpRequestHeader.Authorization] = credentials;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(new
{
features = new
{
entities = new
{
emotion = true,
sentiment = true,
limit = 2
},
keywords = new
{
emotion = true,
sentiment = true,
limit = 2
}
}
});
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Attempt 2:
var authValue = new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{Properties.Settings.Default.WatsonLanguageUnderstandingUsername}:{Properties.Settings.Default.WatsonLanguageUnderstandingPassword}")));
var client = new HttpClient() { DefaultRequestHeaders = {Authorization = authValue} };
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var anonString = new
{
text = "IBM is an American multinational technology company headquartered in Armonk, New York, United States, with operations in over 170 countries.",
features = new
{
entities = new
{
emotion = true,
sentiment = true,
limit = 2
},
keywords = new
{
emotion = true,
sentiment = true,
limit = 2
}
}
};
string json = JsonConvert.SerializeObject(anonString);
HttpResponseMessage blah = await client.PutAsync($"{ Properties.Settings.Default.WatsonLanguageUnderstandingUrl}/v1/analyze?version=2017-02-27", new StringContent(json)).ConfigureAwait(false);
Attempt 3:
Dictionary<string, string> parameters = new Dictionary<string, string>
{
{ "version", "2017-02-27" },
{ "features", "sentiment" }
};
string queryParameters = DictToString(parameters);
var thing = new {text = angry };
string json = JsonConvert.SerializeObject(thing);
string url = $"{Properties.Settings.Default.WatsonLanguageUnderstandingUrl}/v1/analyze?{queryParameters}";
string result;
using (WebClient client = new WebClient())
{
client.UseDefaultCredentials = true;
client.Credentials = new NetworkCredential(Properties.Settings.Default.WatsonLanguageUnderstandingUsername, Properties.Settings.Default.WatsonLanguageUnderstandingPassword);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
result = client.UploadString(url, "POST", json);
}
Where my DictToString() method looks like:
private static string DictToString(Dictionary<string, string> dict)
{
StringBuilder builder = new StringBuilder();
foreach (KeyValuePair<string, string> kvp in dict)
{
builder.Append(kvp.Key + "=" + kvp.Value + "&");
}
return builder.ToString();
}
Note that attempt 3 works and returns an ok request, but I can't get attempt 3 to work with all those example parameters and more.
Any help into why my requests aren't working would be great! Thanks

Related

HttpClient Post data form-url-encoded (national encoding - win-1250) [duplicate]

I'm using the HttpClient. I'm posting with web form parameters. One of the values (not name) is a foreign Swedish character ö , #246; ö ASCII: Latin Small Letter O Umlaut
Manually, IE, Firefox and Chrome all convert this character to S%F6k and everything works fine. However VS 2012 C# release converts it (via FormUrlEncodedContent(dict)) to %C3%B6
Is there a way to tell VS 2012 to convert it, to the friendly S%F6k (and still use HttpClient)?
I've attached most of the code, which may help others (cookies, proxy, etc...)
// Create Handler
var handler = new HttpClientHandler();
// Cookies
var cc = new CookieContainer();
handler.CookieContainer = cc;
// Proxy - for fiddler
WebProxy proxy = new WebProxy();
proxy.Address = new Uri("http://localhost:8888");
handler.Proxy = proxy;
// Create the client
var client = new HttpClient(handler);
var request4 = new HttpRequestMessage();
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "text/html, application/xhtml+xml, */*");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8,sv-SE;q=0.5,sv;q=0.3");
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
// Form Data
var dict4 = new Dictionary<string, string>
{
{ "page", "kantlista" },
{ "kod", "A0004n" },
{ "termin", "H12" },
{ "anmkod", "17113" },
{ "urval", "ant" },
{ "listVal", "namn" },
{ "method", "Sök" } // S%F6k
}; // dict
request4.Content = new FormUrlEncodedContent(dict4);
var value4 = new FormUrlEncodedContent(dict4);
string uri4 = "https://www.ltu.se/ideal/ListaKursant.do";
var response4 = await client.PostAsync(uri4, value4);
response4.Headers.Add("Cache-Control", "no-cache")
response4.EnsureSuccessStatusCode();
string responseBody4 = await response4.Content.ReadAsStringAsync();
FormUrlEncodedContent class encode form data in utf8 encoding.
try ByteArrayContent class and HttpUtility.UrlEncode(String, Encoding) to encode.
Just to complete #TylerTsai's answer
Replace
var dict = new Dictionary<string, string>();
dict.Add("param1", value1);
dict.Add("param1", value2);
var response = await httpClient.PostAsync(endpoint, new FormUrlEncodedContent(dict));
With
string postData = HttpUtility.UrlEncode(
$"param1={value1}&param2={value2}",Encoding.GetEncoding(myEncoding));
byte[] data = System.Text.Encoding.GetEncoding(myEncoding).GetBytes(postData);
ByteArrayContent content = new ByteArrayContent(data);
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var response = await httpClient.PostAsync(endpoint, content);
With this small adjustment you can keep your dictionary
var postEncoding= "ISO-8859-1";
var dict4 = new Dictionary<string, string>
{
{ "page", "kantlista" },
{ "kod", "A0004n" },
{ "termin", "H12" },
{ "anmkod", "17113" },
{ "urval", "ant" },
{ "listVal", "namn" },
{ "method", "Sök" } // S%F6k
}; // dict
string postData = HttpUtility.UrlEncode(string.Join("&", dict4.Select(kvp => $"{kvp.Key}={kvp.Value}")) ,Encoding.GetEncoding(postEncoding));
byte[] data = Encoding.GetEncoding(postEncoding).GetBytes(postData);
ByteArrayContent content = new ByteArrayContent(data);
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var response = await httpClient.PostAsync(endpoint, content);

C# API Web Request with JSON and Files

I have this more complicated web request in C# which involves a File upload. I keep receiving 422 Unprocessable Entity error.
Basically this is the JSON structure that is required in the body of the request.
{
"title":"abc",
"publisher":
{
"city":"J Town",
"year":2021
}
"File":"???",
"Shed":[
{
"country":"NZ",
"postcode":12345
}
]
}
What I have written is the following (I converted the file path to byte).
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api-abc.com/upload");
httpWebRequest.ContentType = "multipart/form-data";
httpWebRequest.Headers.Add("Token", "3SHFHBVRH87BHDBGV");
httpWebRequest.Method = "POST";
var bytes = Encoding.UTF8.GetBytes(#"D:/abc.pdf");
var root = new RootObject()
{
upload = new UploadDoc()
{
title = "Test 321",
Publisher = new List<publishers>
{
new recipients()
{
city = "J Town",
year = 2021
}
},
file = $"Basic { Convert.ToBase64String(bytes) }",
Shed = new []
{
new
{
country = "NZ",
postcode = 12345
}
}
}
};
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
var book = JsonConvert.SerializeObject(new
{
root
});
streamWriter.Write(book);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Which part did I do wrong?
Appreciate the help in advance :)

Error 401 'INVALID_KEY_TYPE' with FireBase and c#

I am implementing c # with FireBase, it sends me error 401 'INVALID_KEY_TYPE'
private static Uri FireBasePushNotificationsURL = new Uri("https://fcm.googleapis.com/fcm/send");
private static string ServerKey = "AIzaSyA9fL8lPyxcrngIDDsDeUbq9sPTkavXXXX";
public static async Task<bool> SendPushNotification(string deviceTokens, string title, string body, object data)
{
bool sent = false;
if (deviceTokens.Count() > 0)
{
//Object creation
var messageInformation = new
{
to = "fZ0EyxU-tsk:APA91bE3-qo4DwL9phteDJC8pG6iLdr-YSSl-N_2SJne3U6eyUhmEuZNQhJi0YM-XXXXXX",
priority = "high",
content_available = true,
notification = new
{
body = "Test",
title = "Test miguel",
badge = 1
},
};
//Object to JSON STRUCTURE => using Newtonsoft.Json;
string jsonMessage = JsonConvert.SerializeObject(messageInformation);
//Create request to Firebase API
var request = new HttpRequestMessage(HttpMethod.Post, FireBasePushNotificationsURL);
request.Headers.TryAddWithoutValidation("Authorization", "key=" + ServerKey);
request.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
HttpResponseMessage result;
using (var client = new HttpClient())
{
result = await client.SendAsync(request);
sent = sent && result.IsSuccessStatusCode;
}
}
return sent;
}
I have the same problem. The problem is that you take the wrong server key.
The right firebase server key is Project > Settings > Cloud Messaging > Server Key

C# Add item to Sharepoint list using REST API

I would like to add an item to a list in sharepoint using below code:
protected string httpGetPost(string getPostMode, string url, string dataToPost = "")
{
HttpWebRequest endpointRequest = (HttpWebRequest)WebRequest.Create(url);
endpointRequest.Method = getPostMode;
var credentialCache = new CredentialCache();
credentialCache.Add(
new Uri(endpointRequest.RequestUri.GetLeftPart(UriPartial.Authority)), // request url's host
"Digest", // authentication type
new NetworkCredential(userName, password) // credentials
);
endpointRequest.Credentials = credentialCache;
endpointRequest.Accept = "application/json;odata=verbose";
endpointRequest.ContentType = "application/json;odata=verbose";
if (!string.IsNullOrEmpty(dataToPost))
{
using (Stream dataStream = endpointRequest.GetRequestStream())
{
byte[] bs = Encoding.ASCII.GetBytes(dataToPost);
dataStream.Write(bs, 0, bs.Length);
}
}
using (var resp = endpointRequest.GetResponse())
{
var html = new StreamReader(resp.GetResponseStream()).ReadToEnd();
return html;
}
}
And call the above method using below code:
httpGetPost("POST", url, "{\"__metadata\": { \"type\": \"SP.Data.Test_x0020_ListListItem\" }, \"Title\": \"Test\", \"Column B\", \"BBB\"}");
Here's the data I'm posting:
{"__metadata": { "type": "SP.Data.Test_x0020_ListListItem" }, "Title":
"Test", "Column B", "BBB"}
I've took a look at this website https://msdn.microsoft.com/en-us/library/office/dn292552.aspx, but the authorization is different, it's using an accesstoken, but here's the problem:
In this website: http://sharepoint.stackexchange.com/questions/69617/sharepoint-2013-oauth-url-to-get-token, it saids I can't get the accesstoken, so I used username and password to login the sharepoint, but here comes another problem:
A System.Net.WebException is thrown in var resp = endpointRequest.GetResponse(), the error is saying The remote server returned an error: (403) Forbidden.
The account is a domain admin as well as a sharepoint admin.
Why I'm still getting the 403 error?
For some reasons, I can only use the REST API to communicate with sharepoint.
Here is a slightly different method to achieve your goals. Some of the objects are specific to Store Apps in this example, but they can all easily be replaced with other values in a standard app.
public string digest()
{
String retVal = "";
try
{
string url = "https://YourSite.com/";
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
string cmd = "_api/contextinfo";
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json");
client.DefaultRequestHeaders.Add("ContentLength", "0");
StringContent httpContent = new StringContent("");
var response = client.PostAsync(cmd, httpContent).Result;
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
JsonObject val = JsonValue.Parse(content).GetObject();
JsonObject d = val.GetNamedObject("d");
JsonObject wi = d.GetNamedObject("GetContextWebInformation");
retVal = wi.GetNamedString("FormDigestValue");
}
}
catch
{ }
return retVal;
}
FileOpenPicker picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types.
picker.FileTypeFilter.Clear();
picker.FileTypeFilter.Add(".bmp");
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".jpg");
// Open the file picker.
StorageFile path = await picker.PickSingleFileAsync();
if (path != null)
{
string url = "https://YourSite.com/Subsite/";
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-RequestDigest", digest());
client.DefaultRequestHeaders.Add("X-HTTP-Method", "POST");
client.DefaultRequestHeaders.Add("binaryStringRequestBody", "true");
IRandomAccessStream fileStream = await path.OpenAsync(FileAccessMode.Read);
var reader = new DataReader(fileStream.GetInputStreamAt(0));
await reader.LoadAsync((uint)fileStream.Size);
Byte[] content = new byte[fileStream.Size];
reader.ReadBytes(content);
ByteArrayContent file = new ByteArrayContent(content);
HttpResponseMessage response = await client.PostAsync("_api/web/lists/getByTitle(#TargetLibrary)/RootFolder/Files/add(url=#TargetFileName,overwrite='true')?#TargetLibrary='Project Photos'&#TargetFileName='TestUpload.jpg'", file);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{ }
}

xNet request problems

HttpResponse response;
request.AllowAutoRedirect = false;
request.UserAgent = HttpHelper.IEUserAgent();
response = request.Post("https://www.site.com", "value=1");
But after request, program trys to open file value=1. Why?
Try this option, code:
using (var request = new HttpRequest())
{
request.UserAgent = HttpHelper.RandomUserAgent();
request.Proxy = Socks5ProxyClient.Parse("127.0.0.1:1080");
var reqParams = new StringDictionary();
reqParams["login"] = "neo";
reqParams["password"] = "knockknock";
string content = request.Post(
"www.whitehouse.gov", reqParams).ToText();
string secretsGovernment = content.Substring("secrets_government=\"", "\"");
}
And read documentation here
Post(string address, string path) - send file. You can set the parameters as:
1:
using (var request = new HttpRequest())
{
var reqParams = new RequestParams();
reqParams["login"] = "neo";
reqParams["password"] = "knockknock";
string content = request.Post(
"www.whitehouse.gov", reqParams).ToString();
}
2:
using (var request = new HttpRequest("www.whitehouse.gov"))
{
request
.AddParam("login", "neo")
.AddParam("password", "knockknock");
string content = request.Post("/").ToString();
}
3:
using (var request = new HttpRequest())
{
var reqParams = new Dictionary<string, string>()
{
{"login", "neo"},
{"password", "knockknock"},
};
var httpContent = new FormUrlEncodedContent(reqParams);
string content = request.Post(
"www.whitehouse.gov", httpContent).ToString();
}
4:
using (var request = new HttpRequest())
{
string reqStr = "param1=value1&param2=value2";
string content = request.Post(
"www.whitehouse.gov", reqStr,
"application/x-www-form-urlencoded").ToString();
}

Categories