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
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}¶m2={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);
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 :)
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
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)
{ }
}
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¶m2=value2";
string content = request.Post(
"www.whitehouse.gov", reqStr,
"application/x-www-form-urlencoded").ToString();
}