using RestSharp; using System; using System.Collections.Generic; using System.Net; using System.Reflection; namespace UptimeSharp { /// /// UptimeClient /// public partial class UptimeClient { /// /// REST client used for the API communication /// protected readonly RestClient _restClient; /// /// The base URL for the UptimeRobot API /// protected static Uri baseUri = new Uri("http://api.uptimerobot.com/"); /// /// Accessor for the UptimeRebot API key /// see: http://http://www.uptimerobot.com/api.asp /// public string ApiKey { get; set; } /// /// Returns all associated data from the last request /// public IRestResponse LastRequestData { get; private set; } /// /// Initializes a new instance of the class. /// /// The API key public UptimeClient(string apiKey) { // assign public properties ApiKey = apiKey; // initialize REST client _restClient = new RestClient(baseUri.ToString()); // add default parameters to each request _restClient.AddDefaultParameter("apiKey", ApiKey); // defines the response format (according to the UptimeRobot docs) _restClient.AddDefaultParameter("format", "json"); // UptimeRobot returns by default JSON-P when json-formatting is set // with this param it can return raw JSON _restClient.AddDefaultParameter("noJsonCallback", "1"); // custom JSON deserializer (ServiceStack.Text) _restClient.AddHandler("application/json", new JsonDeserializer()); // add custom deserialization lambdas JsonDeserializer.AddCustomDeserialization(); } /// /// Makes a typed HTTP REST request to the API /// /// /// The request. /// protected T Request(RestRequest request) where T : new() { // fix content type if wrong determined by RestSharp request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; }; IRestResponse response = _restClient.Execute(request); LastRequestData = response; ValidateResponse(response); return response.Data; } /// /// Fetches a typed resource /// /// /// Requested resource /// Additional GET parameters /// protected T Get(string resource, List parameters = null) where T : class, new() { // UptimeRobot uses GET for all of its endpoints var request = new RestRequest(resource, Method.GET); // enumeration for params if (parameters != null) { parameters.ForEach( param => { if(param.Value != null) { request.AddParameter(param); } } ); } // do the request return Request(request); } /// /// Fetches a typed resource /// /// /// Requested resource /// The parameters. /// protected T Get(string resource, params Parameter[] parameters) where T : class, new() { List parameterList = new List(); parameterList.AddRange(parameters); return Get(resource, parameterList); } /// /// Creates a RestSharp.Parameter instance. /// /// The name. /// The value. /// internal static Parameter Parameter(string name, object value) { return new Parameter() { Name = name, Value = value, Type = ParameterType.GetOrPost }; } /// /// Validates the response. /// /// The response. /// /// /// Error retrieving response /// protected void ValidateResponse(IRestResponse response) where T : new() { Type responseType = response.Data.GetType(); // get status property from ResponseBase POCO PropertyInfo statusProp = responseType.GetProperty("Status"); object status = statusProp.GetValue(response.Data, null); // Error from UptimeSharp if (status.Equals(false)) { // get error properties from response PropertyInfo errorProp = responseType.GetProperty("ErrorMessage"); object error = errorProp.GetValue(response.Data, null); PropertyInfo errorCodeProp = responseType.GetProperty("ErrorCode"); object errorCode = errorCodeProp.GetValue(response.Data, null); // create exception UptimeSharpException exception = new UptimeSharpException( "UptimeRobot Exception: {0} (Code: {1})\n{2}", response.ErrorException, error, errorCode, "http://uptimerobot.com/api.asp#errorMessages" ); // add custom pocket fields exception.Error = error.ToString(); exception.ErrorCode = Convert.ToInt32(errorCode); // add to generic exception data exception.Data.Add("Error", error); exception.Data.Add("ErrorCode", errorCode); throw exception; } // HTTP Request Error else if (response.StatusCode != HttpStatusCode.OK) { throw new UptimeSharpException( "Request Exception: {0} (Code: {1})", response.ErrorException, response.ErrorMessage, response.StatusCode ); } // Exception by RestSharp else if (response.ErrorException != null) { throw new UptimeSharpException("Error retrieving response", response.ErrorException); } } } }