Issue
I'm trying to make an API call work to create an alert but I am not sure how to do it properly. It doesn't make a lot of sense to me so I supplied the code below that I wrote but can't work out why it's returning a Bad Request error.
It could be that my request is incorrectly formatted or something but I can't tell as I've never done anything to do with CURL before.
It's supposed to post a curl request that looks similar to:
curl -XPOST 'https://api.opsgenie.com/v1/json/alert' -d '
{
"apiKey": "eb243592-faa2-4ba2-a551q-1afdf565c889",
"message" : "WebServer3 is down",
"teams" : ["operations", "developers"]
}'
But it doesn't work.
Call to function:
OpsGenie.createAlert("1b9ccd31-966a-47be-92f2-ea589afbca8e", "Testing", null, null, new string[] { "ops_team" }, null, null);
At the end, it returns a bad request. I don't know if there's something wrong with how I'm putting in data or anything so any help would be greatly appreciated.
public static void createAlert(string api, string message, string description, string entity, string[] teams, string user, string[] tags)
{
var request = WebRequest.Create(new Uri("https://api.opsgenie.com/v1/json/alert"));
string json = "{";
if (api != null)
json = json + "'apiKey': '" + api + "'";
if (message != null)
json = json + ", 'message': '" + message + "'";
if (description != null)
json = json + ", 'description': '" + description + "'";
if (entity != null)
json = json + ", 'entity': '" + entity + "'";
if (teams != null)
{
json = json + ", 'teams': '['" + string.Join(",", teams) + "']'";
}
if (user != null)
json = json + ", 'user': '" + user + "'";
if (tags != null)
json = json + ", 'tags': '" + tags.ToString() + "'";
json = json + "}";
Console.WriteLine(json);
request.Method = "POST";
try
{
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(stream: httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
dynamic obj = JsonConvert.DeserializeObject(result);
var messageFromServer = obj.error.message;
Console.WriteLine(messageFromServer);
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
}
else
{
Console.WriteLine(e.Message);
}
}
}
Solution
It might be easier to use WebClient
for a task like this. It has a number of helper methods that make downloading and uploading content like strings really easy.
Also, instead of trying to build the JSON payload by concatenating strings, just use Newtonsoft.Json.
I refactored your method to use WebClient
and JsonConvert
. It's a lot simpler now! I left the debugging in place, but you can remove the console logging lines after you've tested it:
public static void CreateAlert(string api, string message, string description, string entity, string[] teams,
string user, string[] tags)
{
// Serialize the data to JSON
var postData = new
{
apiKey = api,
message,
teams
};
var json = JsonConvert.SerializeObject(postData);
// Set up a client
var client = new WebClient();
client.Headers.Add("Content-Type", "application/json");
try
{
var response = client.UploadString("https://api.opsgenie.com/v1/json/alert", json);
Console.WriteLine("Success!");
Console.WriteLine(response);
}
catch (WebException wex)
{
using (var stream = wex.Response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
// OpsGenie returns JSON responses for errors
var deserializedResponse = JsonConvert.DeserializeObject<IDictionary<string, object>>(reader.ReadToEnd());
Console.WriteLine(deserializedResponse["error"]);
}
}
}
Answered By - Nate Barbettini Answer Checked By - Senaida (WPSolving Volunteer)