Campaign Monitor Post with API Key - c#

I'm new to this so what I want to do is post an Ajax to campaign monitor to add a new subscriber to a my list. The issue here is that I've carried out the right procedures using Campaign Monitors documentation. However I get a 401 error on the response regarding that the request was not authenticated. I'm just wondering how would I use the API Key for this instance.
In JSON i am passing:
{ "Email Address": "test#test.com", "Name": "Test" }
Im passing this through by C#
using (var client = new HttpClient())
{
var response = await client.PostAsync("https://api.createsend.com/api/v3.1/subscribers/LISTID.json", new StringContent(senderInfo, Encoding.UTF8, "application/json"));
}
Is there something I'm meant to be passing through here?

Seems i was missing out the header for this response

Related

GET Request return 400 bad response

It's a generic question, but I need help with my specific case.
I have a simple GET endpoint (see image) which I've tested with Postman and it works
It takes two id tokens in the header and thats it.
I've put breakpoints in the code and copied the exact instance of the ids into Postman and the request works, but executing from code, I get a 400 response
using (HttpClient client = new HttpClient())
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://*******.execute-api.ap-southeast-2.amazonaws.com/dev/uploads/image.jpg"),
Method = HttpMethod.Get,
};
var idToken = Application.Current.Properties["id_token"].ToString();
var accessToken = Application.Current.Properties["access_token"].ToString();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Add("Id-Token", idToken);
request.Headers.Add("Access-Token", accessToken);
var response = await client.SendAsync(request);
}
I've tried with and without the content-type header and makes no difference. Also doesn't matter if it's present in Postman
This is a Xamarin project which is where Application.Current.Properties comes from. I'm utilising other endpoints in the application are there are no issues with accessing the tokens like this.

Difficulty receiving an HTTP Response from API -- Bad Request Error

I'm attempting to pass username/password from an application to the API to receive a token authorization key. When I attempt to do so, I receive a 400 Bad Request error and I cannot figure out why. Below is the method in question:
public User UserAuthentication(string username, string password)
{
string endpoint = baseURL + "/TOKEN";
// Could be POST maybe
string method = "POST";
Credential jsonObj = new Credential
{
grant_type = "password",
username = username,
password = password
};
string jsonStr = JsonConvert.SerializeObject(jsonObj);
WebClient wc = new WebClient();
//x - www - form - urlencoded
wc.Headers[HttpRequestHeader.ContentType] = "application/x - www - form - urlencoded";
wc.Headers.Add("Access-Control-Allow-Headers", "content-type");
wc.Headers.Add("Access-Control-Allow-Origin", "*");
wc.Headers[HttpRequestHeader.Authorization] = "Bearer <token>";
wc.Headers.Add("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, OPTIONS");
string header = wc.Headers.ToString();
try
{
string response = wc.UploadString(endpoint, method, jsonStr);
return JsonConvert.DeserializeObject<User>(response);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I've messed around altering just about everything in this method in search of a fix.
What I've done:
/TOKEN was /values & /api/values
POST method was GET -- With this, I received a "Cannot send a content-body with this verb-type." error.
ContentType was changed to "application/json"
Access-Control-Allow-Origin had the baseURL
Checked the format of header & body:
Header:
{Content-Type: application/x - www - form - urlencoded
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Origin: *
Authorization: Bearer <token>
Access-Control-Allow-Methods: POST, PUT, GET, DELETE, OPTIONS}
Body:
{"grant_type":"password",
"username":"test#gmail.com",
"password":"password123"}
I obviously have something wrong in my request, I've just run out of ideas to try. I'm not entirely sure if UploadString() is the correct method to be using in this situation, but I couldn't find another method in the WebClient class that would be better. Any help to try and push me in the right direction would be very much appreciated.
So what I think you are trying to do is a form-urlencoded post to a "token" endpoint with a username/password grant. These are typically done like so:
using (var request = new HttpRequestMessage(HttpMethod.Post, new Uri("https://example.com/token"))
{
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "grant_type", "password" },
{ "username", "username#site.com" },
{ "password", "password12345" }
})
})
{
using (var resp = await _client.SendAsync(request))
{
resp.EnsureSuccessStatusCode();
//await resp.Content.ReadAsAsync<BearerToken>();
// for testing purposes, try this:
var returnData = await resp.Content.ReadAsStringAsync();
Console.WriteLine(returnData);
}
}
You should define this outside all scopes where you need to do Http requests:
private static readonly HttpClient _client = new HttpClient();
So, first off, try to stick with HttpClient. Other patterns such as WebClient are considered legacy.
Next, CORS headers are typically returned from the server when an OPTIONS call is sent to the server. You aren't doing that here, and you should never have to worry about that kind of stuff inside a C# program running from your computer. So you can drop the access-control header stuff.
Form-urlencoded data is not JSON data. It's a different way to format data. If you want to send JSON data, you should use the content-type application/json
Finally, you are trying to add an Authorization header. But that doesn't make much sense as you are trying to authenticate yourself to become authorized. If you send the right username/password, you will receive a bearer token that you can use in an Authorization header for future requests to said service.
Oh and I forgot to add: Whenever you see an error in the [400,499] range (in this case "400 - bad request") it means that you sent something wrong and the server doesn't understand what you are trying to do. For example: a 401 means you sent invalid or missing authorization information. A 400 means your data was probably malformed.
But I like your question... I can see what you were doing and you tried all kinds of different things.
Download a program called Fiddler if you want to see how HTTP works. It's a great tool to debug your HTTP calls.

C# Eventbrite Create Event

I am attempting to integrate with the Eventbrite API, I am just trying to create an event using RestSharp.
// Request to create an event.
var restClient = new RestClient("https://www.eventbriteapi.com/v3/");
This is the base url I am using {MyOrganiserID} and MyToken to replace my actual token.
var createEventRequest = new RestRequest("organizations/{MyOrganiserID}/events", Method.POST);
createEventRequest.AddHeader("Authorization", "Bearer MyToken");
createEventRequest.AddHeader("content-type", "application/x-www-form-urlencoded");
createEventRequest.AddQueryParameter("event.name.html", "My Event is good mate");
createEventRequest.AddQueryParameter("event.start.utc", "2019-12-12T18:00:00Z");
createEventRequest.AddQueryParameter("event.start.timezone", "Australia/Melbourne");
createEventRequest.AddQueryParameter("event.end.utc", "2019-12-12T20:00:00Z");
createEventRequest.AddQueryParameter("event.end.timezone", "Australia/Melbourne");
createEventRequest.AddQueryParameter("event.currency", "AUD");
IRestResponse createEventRestResponse = restClient.Execute(createEventRequest);
var requestContent = createEventRestResponse.Content;
I have also tried to send the parameters in the requestbody using AddBody and AddXMLBody from the RestSharp API.
createEventRequest.AddBody("event.name.html=<p>A DARQ Room Production Woof Woof</p>&event.start.utc=2019-12-12T18:00:00Z&event.start.timezone=Australia/Melbourne&event.end.utc=2019-12-12T20:00:00Z&event.end.timezone=Australia/Melbourne&event.currency=AUD");
createEventRequest.AddXmlBody("event.name.html=<p>A DARQ Room Production Woof Woof</p>&event.start.utc=2019-12-12T18:00:00Z&event.start.timezone=Australia/Melbourne&event.end.utc=2019-12-12T20:00:00Z&event.end.timezone=Australia/Melbourne&event.currency=AUD");
I've also tried to add the fields via the AddParameters method as well.
createEventRequest.AddParameter("event.name.html", "This is a good event mate");
createEventRequest.AddParameter("event.start.utc", "2019-12-12T18:00:00Z");
createEventRequest.AddParameter("event.start.timezone", "Australia/Melbourne");
createEventRequest.AddParameter("event.end.utc", "2019-12-12T20:00:00Z");
createEventRequest.AddParameter("event.end.timezone", "Australia/Melbourne");
createEventRequest.AddParameter("event.currency", "AUD");
With the AddQueryParameter I get a 401 Unauthorised I have tried putting the token as a query parameter aswell and it still says I'm unauthorized.
And another error I get is
{
"status_code": 403,
"error_description": "You do not have permission to access the resource you requested.",
"error": "NOT_AUTHORIZED"
}
When I send the parameter via the request body.
Any help anyone can provide would be deeply appreciated.

Delete email using mailinator API

I am creating application to access public emails in mailinator. I can view emails but I have difficulties when I am trying to delete them.
https://mailinator.com/apidocs.jsp all examples from documentacion worked except this one.
I have code to POST Http request:
using (var client = new HttpClient())
{
var values = new Dictionary<string, string>
{
{ "msgid", id}
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://api.mailinator.com/api/delete?", content);
var responseString = await response.Content.ReadAsStringAsync();
}
Only error it throws is (405) Method Not Allowed. or Method is not supported by this URL.
So I guess either my url that I'm sending is bad, either my code.
I need some help to figure it out.
According to the API docs you need to pass a valid token with every call. The delete API example looks like this:
curl "https://api.mailinator.com/api/delete?id=1373143878-0-test22&token=..."
The elipsis (...) there needs to be a valid token. So, add the token to your values dictionary.

Why can my WebApi client make only a single GET request?

I wrote a simple client for my web service with Web Api as explained in this tutorial:
http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
The first request (GET a table) is executed successfully. That is, table data is fetched from the web service and bound to TableContent object.
But the program is totally blocked before executing the second request (GET table list); nothing happens, not even an error message!
If I comment out the code section related with the first request (GET a table) the second request (GET table list) is executed successfully.
What happens here? Why can this client execute only a single GET request?
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56510/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response;
// GET a table from web service
response = await client.GetAsync("api/table/GetMatrixTable");
if (response.IsSuccessStatusCode)
{
var tblcont = await response.Content.ReadAsAsync<TableContent>();
// do things ...
}
// GET a table list from web service
response = await client.GetAsync("api/table/GetTableList");
if (response.IsSuccessStatusCode)
{
var TblContList = await response.Content.ReadAsAsync<IList<TableContent>>();
// do things ...
}
}
Looking at the following SO question and its accepted answer (maybe not directly relevant but still useful in its own right):
HttpClient.GetAsync(...) never returns when using await/async
it might help if you replace your calls to GetAsync() as follows:
response = await client.GetAsync("api/table/GetMatrixTable",
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
. . .
response = await client.GetAsync("api/table/GetTableList",
HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
I'm not able to test that so I can't take all the credit if that works.

Categories