Logicamente aprendo un progetto di qualche anno fà troverai sempre delle cose da cambiare/aggiornare ma spesso il tempo a disposizione non è quello che vorresti 🙁
Per l’implementazione è stato deciso di utilizzare HttpClient (fornisce una classe di base per l’invio di richieste HTTP e la ricezione di risposte HTTP da una risorsa identificata da un URI) per consumare le API.
L’implementazione delle API prevedeva:
- autenticazione tramite API passando nell’header le credenziali;
- ricezione di un Token (da passare a tutte le chiamate Read/Write/Delete/Update);
- perform della richiesta passando il token nell’header ed eventuali parametri nell’url e nel content della richiesta.
Ho creato una classe che verrà inizializzata con le credenziali:
public class AuthConfig { public string ClientID { get; set; } public string ClientSecret { get; set; } public string AccountId { get; set; } }
In seguito ho creato la classe che contiene l’integrazione con le API tramite una richiesta HttpClient ed i metodi pubblici per effettuare l’inizializzazione delle credenziali ed in seguito l’update:
public class Api { public AuthToken Token { get; private set; } public AuthConfig Config { get; private set; } public Api(AuthConfig config) { if (null == config) throw new ArgumentNullException("config"); Config = config; } /// <summary> /// inizializza la configurazione /// </summary> public static AuthConfig InitApiConfig() { var config = new AuthConfig() { ClientID = "username", ClientSecret = "password", AccountId = "accountid" }; return config; } /// <summary> /// metodo pubblico richiamato dal controller per l'update tramite le API /// </summary> public Task<Video> UpdateVideo(Video video,long videoId) { if (null == video) throw new ArgumentNullException("video"); var requestUri = string.Format("https://terzepartiapiurl.com/accounts/{0}/videos/{1}", Config.AccountId, videoId); var method = new HttpMethod("PATCH"); var request = new HttpRequestMessage(method, requestUri) { Content = new StringContent(JsonConvert.SerializeObject(video), Encoding.UTF8, "application/json") }; var a = PerformRequestHttp(request); return null; } /// <summary> /// effettua la chiamata alle API con le info valorizzate nell' HttpRequestMessage tramite una /// richiesta HTTPClient /// </summary> private string PerformRequestHttp(HttpRequestMessage request) { this.InitToken(); using (var client = new HttpClient()) { client.SetAuthTokenHeader(Token); var response = client.SendAsync(request).Result; if (!response.IsSuccessStatusCode) { if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) throw new UnauthorizedAccessException("User not authorized"); if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new ArgumentNullException("accountData", "Not all the parameters have been provided, account name has a wrong length or email is not valid"); if (response.StatusCode == System.Net.HttpStatusCode.Conflict) throw new InvalidOperationException("Name already assigned to a existing account"); var exMsg = string.Empty; if (null != response.Content) exMsg = response.Content.ReadAsStringAsync().Result; throw new Exception("Unknown error: " + exMsg); } if (null == response.Headers.Location) throw new Exception("Invalid location"); return null; } } /// <summary> /// usato per il refresh OAuth token. Bisogna chiamarlo prima di ogni chiamata API /// </summary> private void InitToken() { if (null != Token && DateTime.Now < Token.ExpiresDate) return; var request = WebRequest.Create("https://terzepartiapiurl.com/access_token"); SetBasicAuthHeader(request, Config.ClientID, Config.ClientSecret); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; string postData = "grant_type=client_credentials"; byte[] byteArray = Encoding.UTF8.GetBytes(postData); request.ContentLength = byteArray.Length; using (var dataStream = request.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); } var response = (HttpWebResponse)request.GetResponse(); var responseEncoding = Encoding.GetEncoding(response.CharacterSet); using (var sr = new StreamReader(response.GetResponseStream(), responseEncoding)) { var jsonData = sr.ReadToEnd(); Token = Newtonsoft.Json.JsonConvert.DeserializeObject<AuthToken>(jsonData); } } /// <summary> /// imposta nell'header le credenziali per l'autorizzazione /// </summary> private void SetBasicAuthHeader(WebRequest request, string userName, string userPassword) { string authInfo = userName + ":" + userPassword; authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); request.Headers["Authorization"] = "Basic " + authInfo; } }
Alla fine non resta che inizializzare la configurazione delle API e chiamare il metodo:
//inizializzo la configurazione var config = Api.InitApiConfig(); //instanzio la classe delle API passando la configurazione var api = new Api(config); Video video = new Video(); video.Name = "Lorem ipsum API"; //effettuo la chiamata alle API per l'update api.UpdateVideo(video, 423423);