using Microsoft.AspNetCore.SignalR.Client; using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Windows; namespace WD7UVN_SzTGUI_2023242.Client.WPF { public class RestService { HttpClient client; public RestService(string baseurl, string pingableEndpoint = "swagger") { bool isOk = false; do { isOk = Ping(baseurl + pingableEndpoint); } while (isOk == false); Init(baseurl); } private bool Ping(string url) { try { WebClient wc = new WebClient(); wc.DownloadData(url); return true; } catch { return false; } } private void Init(string baseurl) { client = new HttpClient(); client.BaseAddress = new Uri(baseurl); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue ("application/json")); try { client.GetAsync("").GetAwaiter().GetResult(); } catch (HttpRequestException) { throw new ArgumentException("Endpoint is not available!"); } } public async Task> GetAsync(string endpoint) { List items = new List(); HttpResponseMessage response = await client.GetAsync(endpoint); if (response.IsSuccessStatusCode) { items = await response.Content.ReadAsAsync>(); } else { var error = await response.Content.ReadAsAsync(); throw new ArgumentException(error.Msg); } return items; } public List Get(string endpoint) { List items = new List(); HttpResponseMessage response = client.GetAsync(endpoint).GetAwaiter().GetResult(); if (response.IsSuccessStatusCode) { items = response.Content.ReadAsAsync>().GetAwaiter().GetResult(); } else { var error = response.Content.ReadAsAsync().GetAwaiter().GetResult(); throw new ArgumentException(error.Msg); } return items; } public async Task GetSingleAsync(string endpoint) { T item = default(T); HttpResponseMessage response = await client.GetAsync(endpoint); if (response.IsSuccessStatusCode) { item = await response.Content.ReadAsAsync(); } else { var error = await response.Content.ReadAsAsync(); throw new ArgumentException(error.Msg); } return item; } public T GetSingle(string endpoint) { T item = default(T); HttpResponseMessage response = client.GetAsync(endpoint).GetAwaiter().GetResult(); if (response.IsSuccessStatusCode) { item = response.Content.ReadAsAsync().GetAwaiter().GetResult(); } else { var error = response.Content.ReadAsAsync().GetAwaiter().GetResult(); throw new ArgumentException(error.Msg); } return item; } public async Task GetAsync(int id, string endpoint) { T item = default(T); HttpResponseMessage response = await client.GetAsync(endpoint + "/" + id.ToString()); if (response.IsSuccessStatusCode) { item = await response.Content.ReadAsAsync(); } else { var error = await response.Content.ReadAsAsync(); throw new ArgumentException(error.Msg); } return item; } public T Get(int id, string endpoint) { T item = default(T); HttpResponseMessage response = client.GetAsync(endpoint + "/" + id.ToString()).GetAwaiter().GetResult(); if (response.IsSuccessStatusCode) { item = response.Content.ReadAsAsync().GetAwaiter().GetResult(); } else { var error = response.Content.ReadAsAsync().GetAwaiter().GetResult(); throw new ArgumentException(error.Msg); } return item; } public async Task PostAsync(T item, string endpoint) { HttpResponseMessage response = await client.PostAsJsonAsync(endpoint, item); if (!response.IsSuccessStatusCode) { var error = await response.Content.ReadAsAsync(); throw new ArgumentException(error.Msg); } response.EnsureSuccessStatusCode(); } public void Post(T item, string endpoint) { HttpResponseMessage response = client.PostAsJsonAsync(endpoint, item).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { var error = response.Content.ReadAsAsync().GetAwaiter().GetResult(); throw new ArgumentException(error.Msg); } response.EnsureSuccessStatusCode(); } public async Task DeleteAsync(int id, string endpoint) { HttpResponseMessage response = await client.DeleteAsync(endpoint + "/" + id.ToString()); if (!response.IsSuccessStatusCode) { var error = await response.Content.ReadAsAsync(); throw new ArgumentException(error.Msg); } response.EnsureSuccessStatusCode(); } public void Delete(int id, string endpoint) { HttpResponseMessage response = client.DeleteAsync(endpoint + "/" + id.ToString()).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { var error = response.Content.ReadAsAsync().GetAwaiter().GetResult(); throw new ArgumentException(error.Msg); } response.EnsureSuccessStatusCode(); } public async Task PutAsync(T item, string endpoint) { HttpResponseMessage response = await client.PutAsJsonAsync(endpoint, item); if (!response.IsSuccessStatusCode) { var error = await response.Content.ReadAsAsync(); throw new ArgumentException(error.Msg); } response.EnsureSuccessStatusCode(); } public void Put(T item, string endpoint) { HttpResponseMessage response = client.PutAsJsonAsync(endpoint, item).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { var error = response.Content.ReadAsAsync().GetAwaiter().GetResult(); throw new ArgumentException(error.Msg); } response.EnsureSuccessStatusCode(); } } public class RestExceptionInfo { public RestExceptionInfo() { } public string Msg { get; set; } } class NotifyService { private HubConnection conn; public NotifyService(string url) { conn = new HubConnectionBuilder() .WithUrl(url) .Build(); conn.Closed += async (error) => { await Task.Delay(new Random().Next(0, 5) * 1000); await conn.StartAsync(); }; } public void AddHandler(string methodname, Action value) { conn.On(methodname, value); } public async void Init() { await conn.StartAsync(); } } public class RestCollection : INotifyCollectionChanged, IEnumerable { public event NotifyCollectionChangedEventHandler? CollectionChanged; NotifyService notify; RestService rest; List items; bool hasSignalR; Type type = typeof(T); public RestCollection(string baseurl, string endpoint, string hub = null) { hasSignalR = hub != null; this.rest = new RestService(baseurl, endpoint); if (hub != null) { this.notify = new NotifyService(baseurl + hub); this.notify.AddHandler(type.Name + "Created", (T item) => { items.Add(item); CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); }); this.notify.AddHandler(type.Name + "Deleted", (T item) => { var element = items.FirstOrDefault(t => t.Equals(item)); if (element != null) { items.Remove(item); CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } else { Init(); } }); this.notify.AddHandler(type.Name + "Updated", (T item) => { Init(); }); this.notify.Init(); } Init(); } private async Task Init() { items = await rest.GetAsync(typeof(T).Name); CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } public IEnumerator GetEnumerator() { if (items != null) { return items.GetEnumerator(); } else return new List().GetEnumerator(); } public List GetItems() { if (items != null) { return items; } else return new List(); } IEnumerator IEnumerable.GetEnumerator() { if (items != null) { return items.GetEnumerator(); } else return new List().GetEnumerator(); } public void Add(T item) { if (hasSignalR) { this.rest.PostAsync(item, typeof(T).Name); } else { this.rest.PostAsync(item, typeof(T).Name).ContinueWith((t) => { Init().ContinueWith(z => { Application.Current.Dispatcher.Invoke(() => { CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); }); }); }); } } public void Update(T item) { if (hasSignalR) { this.rest.PutAsync(item, typeof(T).Name); } else { this.rest.PutAsync(item, typeof(T).Name).ContinueWith((t) => { Init().ContinueWith(z => { Application.Current.Dispatcher.Invoke(() => { CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); }); }); }); } } public void Delete(int id) { if (hasSignalR) { this.rest.DeleteAsync(id, typeof(T).Name); } else { this.rest.DeleteAsync(id, typeof(T).Name).ContinueWith((t) => { Init().ContinueWith(z => { Application.Current.Dispatcher.Invoke(() => { CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); }); }); }); } } } }