maingun reply with OK but nothing happens - c#

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

Using DefaultRequestHeaders sends requests twice?

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

Update record in CRM 2015 using HttpRequestMessage

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

Performing a put or patch request with token

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.

HTTPClient POST Hangs/Timeout Exception

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...

How to pass variable into POST request using HttpClient

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());

Categories