Everything works fine on Postman with x-www-from-urlencoded and basic auth. Now trying to get my hands dirty, I just get status code 200 with nothing on mailgun, no logs recorded.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.mailgun.net/v3");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("api", "key-withheld-till-a-verdict-has-passed");
var msg = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("from",
$"Excited User <mailgun#sandboxSOMEGUIDHERE.mailgun.org>"),
new KeyValuePair<string, string>("to","approved-to-receive#mailgun"),
new KeyValuePair<string, string>("subject", "Test Please Do Not Reply"),
new KeyValuePair<string, string>("text","Thanks for borrowing me your inbox")
};
var request = new HttpRequestMessage(HttpMethod.Post,
"sandboxSOMEGUIDHERE.mailgun.org/messages");
request.Content = new FormUrlEncodedContent(msg);
var response = await client.SendAsync(request);
// I get 200 status code
var result = await response.Content.ReadAsStringAsync();
//I get result = "Mailgun Magnificent API"
}
First, it turns out I was getting the BaseAddress not right. I had to place a slash at the end of the BaseAddress.
client.BaseAddress = new Uri("https://api.mailgun.net/v3/");
without the slash, I was posting to (note v3 is missing),
https://api.mailgun.net/sandboxSOMEGUIDHERE.mailgun.org/messages
After sorting that out, another problem emerged 401 - ANAUTHORIZED. And with the help of this SO answer I do,
var byteArray = new UTF8Encoding()
.GetBytes("api:key-withheld-till-a-verdict-has-passed");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
But the reason why mailgun was responding with Ok still remain mysterious. To investigate further, I used Postman to post to,
https://api.mailgun.net/sandboxSOMEGUIDHERE.mailgun.org/messages
and to my surprise, Mailgun mysteriously responded with Ok.
Related
I have a WebAPI that sends BASIC authorization information as following.
var client = new HttlpClient();
client.BaseAddress = new Uri(GlobalConstants.LdapUri);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));
Task<HttpResponseMessage> results = client.GetAsync(GlobalConstants.FortressAPIUriDev);
var response = await results;
I've built this API using MVC Core 1.x and the receiving API is built using MVC5.
The problem is that this GetAsync sends two requests at the same time, and I have no clue how to resolve this. I've done some Googling myself to see if I can find a fix for this but so far no luck. Did anyone experience this problem and know how to resolve it?
Thank you very much in advance.
Long story short, found a solution as follows:
using (var client = new HttpClient())
{
var requestMessage = new HttpRequestMessage(HttpMethod.Get, GlobalConstants.LdapUri + GlobalConstants.FortressAPIUriDev);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));
var response = await client.SendAsync(requestMessage);
}
After replacing with this code, it is sending one request at a time.
Found a hint at :
Adding headers when using httpClient.GetAsync
I need to update a record in CRM 2015 using web api in C#. However when processing, I got this error "Method not allowed" Status Code 405.
Here is some sample code.
HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("username", "password", "domain") });
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add(HttpRequestHeader.ContentType.ToString(), "application/json");
HttpRequestMessage retrieveReq = new HttpRequestMessage(HttpMethod.Post, serviceUrl + "SalesOrderSet(guid'" + orderId + "')");
retrieveReq.Headers.Accept.Clear();
retrieveReq.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
retrieveReq.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-us"));
retrieveReq.Headers.Add(HttpRequestHeader.ContentType.ToString(), "application/json");
retrieveReq.Headers.Add("Prefer", "odata.include-annotations=\"*\"");
retrieveReq.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
retrieveReq.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
retrieveReq.Headers.Host = server_name;
retrieveReq.Headers.Add(HttpRequestHeader.ContentLength.ToString(), "117");
retrieveReq.Headers.Connection.Add("Keep-Alive");
retrieveReq.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("name", "value"));
HttpContent content = new FormUrlEncodedContent(postData);
retrieveReq.Content = content;
await client.SendAsync(retrieveReq).ContinueWith(
(postTask) =>
{
postTask.Result.EnsureSuccessStatusCode();
});
Any help?
Thanks in advance
Error 405 usually means you are trying to send a method different than the expected by the server (normally the HttpVerb is wrong). You are using POST so could you try with GET? HttpMessage.Get.
Edit: looks like update operations require a PATCH verb. Others will require a PUT, and deletions must use DELETE.
https://msdn.microsoft.com/en-us/library/mt607664.aspx
I've got a chunk of code:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", "Username", "password"))));
var method = new HttpMethod("PATCH");
var reqmsg = new HttpRequestMessage(method, uri)
{
Content = new StringContent(request, Encoding.UTF8, "application/json")
};
HttpResponseMessage response = await client.SendAsync(reqmsg);
This works fine using Basic authentication. I want to use a token though, and if I change the Authorization to use a webtoken:
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Token", WebToken);
I now get a 403 Forbidden error. If I'm doing a Post or a Get, the token works, but not for Patch or Put. I'm guessing the token is somehow being stripped off. is there a way around this?
You're getting a 403 error because the encoding is incorrect.
-facepalm-
You're using UTF8 while the default is ANCI... Doesn't make sense.
Before everyone tells me to increase the timeout values I don't want to increase it because it doesn't make sense that 100 seconds isn't long enough. All other get and post responses take less time without throwing a timeout/task cancel exception.
I am trying to mimic the following, I whited out the user and password...
Here is the code
var baseAddress = new Uri("http://www.foodservice.com/home/fs_login.cfm?logmode=Home");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var trypage = await client.GetAsync("http://www.foodservice.com/home/fs_login.cfm?logmode=Home");
trypage.EnsureSuccessStatusCode();
Console.WriteLine("something");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("user_name", "someuser"),
new KeyValuePair<string, string>("password", "somepass"),
new KeyValuePair<string, string>("logmode", "Home")
});
var result = await client.PostAsync("http://www.foodservice.com/home/fs_login_check.cfm", content);
Console.WriteLine("somethingelse");
result.EnsureSuccessStatusCode();
It hands on. something prints, somethingelse doesn't
var result = await client.PostAsync("http://www.foodservice.com/home/fs_login_check.cfm", content);
I don't see any reason why it should hang and fail here...
Summary: Why isn't my post getting through? I am I using the wrong address or something?
Try this
await client.GetAsync("http://www.foodservice.com/home/fs_login.cfm?logmode=Home").ConfigureAwait(false);
and
await client.PostAsync("http://www.foodservice.com/home/fs_login_check.cfm", content).ConfigureAwait(false);
you can get more information on Httpclient Async call
For some reason the process could not be multithreaded.
Switched from Tasks to blocking single threaded it worked fine...
I am figuring out the new HttpClient.
I try to POST a http uri like this:
http://server/API/user/login?login=name&password=password
I thought this would be the way to go:
using (var client = new HttpClient())
{
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("login", "user"),
new KeyValuePair<string, string>("password ", "password")
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://server/REST/user/login", content);
}
The only way I can get it to work is:
using (var client = new HttpClient())
{
var response = await client.PostAsync("http://server/REST/user/login?login=user&password=password",null);
}
Is the last way the correct way or am I doing something wrong in the first approach?
The sample shows that it is being passed along in the Cookie header, not the body. If I interpret the API correctly you have to indeed pass username and password in the URL and give the Cookie header the url-encoded data.
Essentially: use your second approach and for all subsequent calls, add this:
client.DefaultRequestHeaders.Add("Cookie", await content.ReadAsStringAsync());