I struggled for about a day trying to authenticate against the Pardot API. It didn't like how I was trying to post the message body. So I wanted to post the solution that worked for me. If you have any tips or alternatives I'd like to hear them.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
var url = "https://pi.pardot.com/api/login/version/3";
//(Edit) Shorter way to pass the parameters below
//var postData = new List<KeyValuePair<string, string>>
//{
// new KeyValuePair<string, string>("email", "<value>"),
// new KeyValuePair<string, string>("password", "<value>"),
// new KeyValuePair<string, string>("user_key", "<value>")
//};
var postData = new Dictionary<string, string>
{
{"email", "<value>"},
{"password", "<value>"},
{"user_key", "<value>"}
};
var httpContent = new FormUrlEncodedContent(postData);
using (var client = new HttpClient())
{
HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
if (response.IsSuccessStatusCode)
{
string resultValue = response.Content.ReadAsStringAsync().Result;
}
}
Thanks!
Related
I am using the following code to extract records from the Dahua XVR camera and it returns records successfully.
var domain = "http://IP";
var credCache = new CredentialCache();
credCache.Add(new Uri(domain), "Digest", new
NetworkCredential(username, password));
var httpClient = new HttpClient(new HttpClientHandler {
Credentials = credCache });
var result= await httpClient.GetStringAsync(new Uri(URL));
but when I am posting records using the following code it's not working and results in a bad request.
string url = "http://IP/cgi-bin/faceRecognitionServer.cgi";
var postData = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>( "action", "addPerson"),
new KeyValuePair<string, string>("groupID", "1"),
new KeyValuePair<string, string>("name", "Test Name"),
new KeyValuePair<string, string>("birthday", "1980-01-05"),
new KeyValuePair<string, string>("sex", "Male"),
new KeyValuePair<string, string>("country", "Pakistan"),
new KeyValuePair<string, string>("province", "KPK"),
new KeyValuePair<string, string>("city", "Peshawar")
};
var content = new FormUrlEncodedContent(postData);
var domain = "http://IP";
var credCache = new CredentialCache();
credCache.Add(new Uri(domain), "Digest", new NetworkCredential(username, password));
var httpClient = new HttpClient(new HttpClientHandler { Credentials = credCache });
var result = await httpClient.PostAsync(new Uri(url), content);
above code always return 400 bad request. if anyone can help?
I fixed the issue as below. Maybe it help someone.
reduced the size of the image that I had to embed within the request
body.
concatenated the URL and parameters in a single string.
string url = "http://IP/cgi-bin/faceRecognitionServer.cgi?
action=addPerson&groupID=1&name=TestName&sex=Male";
string domain = "http://IP";
CredentialCache credCache = new CredentialCache {
{
new Uri(domain), "Digest", new NetworkCredential(username,
password)
}
};
using HttpClient client = new HttpClient(new HttpClientHandler {
Credentials = credCache });
using FileStream stream =
File.OpenRead(AppContext.BaseDirectory.
Replace("\\bin\\Debug\\netcoreapp3.1", "") + "Files\\14.jpg");
var file_content = new ByteArrayContent(new StreamContent(stream).ReadAsByteArrayAsync().Result);
file_content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var response = await client.PostAsync(url, file_content);
I'm working on Xamarin.Android App. I have to consume rest API of content type x-www-form-urlencoded. I'm unable to call the Rest API Successfully, before this, I consumed many web services but I'm working on this type of API first time. I'm stuck in this.
I tried two ways to consume it:
public static string makePostEncodedRequest(string url, string jsonparams)
{
string ret = "";
var httpwebrequest = (HttpWebRequest)WebRequest.Create(url);
httpwebrequest.ContentType = "application/x-www-form-urlencoded";
//httpwebrequest.Accept = Config.JsonHeaderAJ;
httpwebrequest.Method = Methods.Post.ToString();
byte[] bytearray = Encoding.UTF8.GetBytes(jsonparams);
using (var streamWriter = new StreamWriter(httpwebrequest.GetRequestStream(), Encoding.ASCII))
{
streamWriter.Write(bytearray);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpwebrequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
ret = streamReader.ReadToEnd();
}
return ret;
}
the next one is:
Dictionary<string, string> requestParams = new Dictionary<string, string ();
requestParams.Add("value=", data1);
requestParams.Add("&value=", data2);
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpResponseMessage response = client.PostAsync(Config.DomainURl + Config.StudentLoginUrl, new FormUrlEncodedContent(requestParams)).Result;
var tokne = response.Content.ReadAsStringAsync().Result;
}
i have used the following code for authenticating user in my project might help you.
public static async Task<UserData> GetUserAuth(UserAuth userauth)
{
bool asd= CheckNetWorkStatus().Result;
if (asd)
{
var client = new HttpClient(new NativeMessageHandler());
client.BaseAddress = new Uri(UrlAdd);// ("http://192.168.101.119:8475/");
var postData = new List<KeyValuePair<string, string>>();
var dto = new UserAuth { grant_type = userauth.grant_type, password = userauth.password, username = userauth.username };
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("grant_type", userauth.grant_type));
nvc.Add(new KeyValuePair<string, string>("password", userauth.password));
nvc.Add(new KeyValuePair<string, string>("username", userauth.username));
var req = new HttpRequestMessage(HttpMethod.Post, UrlAdd + "token") { Content = new FormUrlEncodedContent(nvc) };
var res = await client.SendAsync(req);
if (res.IsSuccessStatusCode)
{
string result = await res.Content.ReadAsStringAsync();
var userData = JsonConvert.DeserializeObject<UserData>(result);
userData.ErrorMessage = "true";
return userData;
}
else
{
UserData ud = new UserData();
ud.ErrorMessage = "Incorrect Password";
return ud;
}
}
else
{
UserData ud = new UserData();
ud.ErrorMessage = "Check Ur Connectivity";
return ud;
}
}
I need to make some api calls in C#. I'm using Web API Client from Microsoft to do that. I success to make some POST requests, but I don't know how to add the field "Body" into my requests. Any idea ?
Here's my code:
static HttpClient client = new HttpClient();
public override void AwakeFromNib()
{
base.AwakeFromNib();
notif_button.Activated += (sender, e) => {
};
tips_button.Activated += (sender, e) =>
{
Tip t1 = new Tip(title_tips.StringValue, pic_tips.StringValue, content_tips.StringValue, "TEST");
client.BaseAddress = new Uri("my_url");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
CreateProductAsync(t1).Wait();
};
}
static async Task<Uri> CreateProductAsync(Tip tips)
{
HttpResponseMessage response = await client.PostAsJsonAsync("api/add_tips", tips);
response.EnsureSuccessStatusCode();
return response.Headers.Location;
}
Step 1. Choose a type that derives from HttpContent. If you want to write a lot of content with runtime code, you could use a StreamContent and open some sort of StreamWriter on it. For something short, use StringContent. You can also derive your own class for custom content.
Step 2. Pass the content in a call to HttpClient.PostAsync.
Here's an example that uses StringContent to pass some JSON:
string json = JsonConvert.SerializeObject(someObject);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var httpResponse = await httpClient.PostAsync("http://www.foo.bar", httpContent);
See also How do I set up HttpContent?.
Thanks to this and this, I finally found the solution to send post requests with headers AND body content. Here's the code:
var cl = new HttpClient();
cl.BaseAddress = new Uri("< YOUR URL >");
int _TimeoutSec = 90;
cl.Timeout = new TimeSpan(0, 0, _TimeoutSec);
string _ContentType = "application/x-www-form-urlencoded";
cl.DefaultRequestHeaders.Add(key, value);
cl.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_ContentType));
cl.DefaultRequestHeaders.Add("key", "value");
cl.DefaultRequestHeaders.Add("key", "value");
var _UserAgent = "d-fens HttpClient";
cl.DefaultRequestHeaders.Add("User-Agent", _UserAgent);
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("key of content", "value"));
var req = new HttpRequestMessage(HttpMethod.Post, "http://www.t-lab.fr:3000/add_tips") { Content = new FormUrlEncodedContent(nvc) };
var res = cl.SendAsync(req);
a little more understandable
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
client.DefaultRequestHeaders.Add("Accept", "*/*");
var Parameters = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Id", "1"),
};
var Request = new HttpRequestMessage(HttpMethod.Post, "Post_Url")
{
Content = new FormUrlEncodedContent(Parameters)
};
var Result = client.SendAsync(Request).Result.Content.ReadAsStringAsync();
}
I am trying to figure out what I can do (logging, things to check) before having to read server logs as I don't want to miss something stupid before requesting that.
Here is my code:
const string URL = "https://SomeURL/api/security/";
string urlParameters = string.Format("grant_type=password&username={0}&password={1}", username, password);
StringContent content = new StringContent(urlParameters, Encoding.UTF8, "application/x-www-form-urlencoded");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
StringContent content = new StringContent(urlParameters, Encoding.UTF8, "application/x-www-form-urlencoded");
var tokenResponse = client.PostAsync("token", content).Result;
I am a little newer to this so I'm not sure what to check next but have tried the same request using postman and get a response with my token so it looks like I am missing something or maybe formatting something incorrectly?
I was following an online course, and the code for setting the URL parameters were set like this:
public async Task<AuthenticatedUser> Authenticate(string userName, string password)
{
var data = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username ", "userName"),
new KeyValuePair<string, string>("password", "password")
});
using (HttpResponseMessage response = await apiClient.PostAsync("/Token", data))
{
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsAsync<AuthenticatedUser>();
return result;
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
}
When testing, found that 500 error was being returned for the PostAsync call. I checked my URL address and parameters and they all looked correct. If I tested in Swagger, then I received a 200 status and token was shown.
Following the link by Thomas Levesque I changed how the data variables were set to :
var data = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["username"] = username,
["password"] = password
});
Now the response status is 200 and the AuthenticatedUser model is populated correctly. However I couldn't understand why Dictionary seem to work and KeyValuePair didn't. So I created the list and then encoded it:
var dataList = new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password)
};
var content = new FormUrlEncodedContent(dataList);
using (HttpResponseMessage response = await apiClient.PostAsync(requestUrl, content))
This also worked. I freely admit that I do not fully understand why.....yet.
I did not URL encode my parameters, here's the fix (probably a better way of doing it).
string urlParameters = string.Format("grant_type=password&username={0}&password={1}", Uri.EscapeDataString(username), Uri.EscapeDataString(password));
i'm trying to create a POST request and I can't get it to work.
this is the format of the request which has 3 params, accountidentifier / type / seriesid
http://someSite.com/api/User_Favorites.php?accountid=accountidentifier&type=type&seriesid=seriesid
and this is my C#
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://somesite.com");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("accountidentifier", accountID),
new KeyValuePair<string, string>("type", "add"),
new KeyValuePair<string, string>("seriesid", seriesId),
});
httpClient.PostAsync("/api/User_Favorites.php", content);
}
Any ideas?
IMO, dictionaries in C# are very useful for this kind of task.
Here is an example of an async method to complete a wonderful POST request:
public class YourFavoriteClassOfAllTime {
//HttpClient should be instancied once and not be disposed
private static readonly HttpClient client = new HttpClient();
public async void Post()
{
var values = new Dictionary<string, string>
{
{ "accountidentifier", "Data you want to send at account field" },
{ "type", "Data you want to send at type field"},
{ "seriesid", "The data you went to send at seriesid field"
}
};
//form "postable object" if that makes any sense
var content = new FormUrlEncodedContent(values);
//POST the object to the specified URI
var response = await client.PostAsync("http://127.0.0.1/api/User_Favorites.php", content);
//Read back the answer from server
var responseString = await response.Content.ReadAsStringAsync();
}
}
You can try WebClient too. It tries to accurately simulate what a browser would do:
var uri = new Uri("http://whatever/");
WebClient client = new WebClient();
var collection = new Dictionary<string, string>();
collection.Add("accountID", accountID );
collection.Add("someKey", "someValue");
var s = client.UploadValuesAsync(uri, collection);
Where UploadValuesAsync POSTs your collection.