public async Task <bool> UpdateAsync() { if (string.IsNullOrEmpty(UpdateURL)) { return(false); } try { string oldMd5; string newMd5; Timetable newTimetable = null; using (var localFile = File.OpenRead(DataFilePath)) { var hasher = MD5.Create(); var hash = hasher.ComputeHash(localFile); oldMd5 = string.Concat(hash.Select(x => x.ToString("X2"))); } using (var client = new WebClient()) { #if !__WASM__ byte[] data = await client.DownloadDataTaskAsync(UpdateURL); #else byte[] data = await WasmWebClient.DownloadDataTaskAsync(UpdateURL); #endif using (var stream = new MemoryStream(data)) using (var sr = new StreamReader(stream)) { var response = (UpdateResponse)JsonConvert.DeserializeObject(sr.ReadToEnd(), typeof(UpdateResponse)); newMd5 = response.MD5; if (string.Compare(oldMd5, newMd5, true) != 0) { #if !__WASM__ data = await client.DownloadDataTaskAsync(response.Location); #else data = await WasmWebClient.DownloadDataTaskAsync(response.Location); #endif var hash = MD5.Create().ComputeHash(data); var hashString = string.Concat(hash.Select(x => x.ToString("X2"))); if (string.Compare(newMd5, hashString, true) != 0) { return(false); } using (var timetableStream = new MemoryStream(data)) using (var timetableReader = new StreamReader(timetableStream)) { var timetableData = timetableReader.ReadToEnd().Replace("$ASSEMBLY_NAME", Assembly.GetExecutingAssembly().GetName().Name); //throw new Exception(timetableData); newTimetable = (Timetable)JsonConvert.DeserializeObject(timetableData, typeof(Timetable), new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); } } else { return(true); } } } if (newTimetable != null) { Name = newTimetable.Name; UpdateURL = newTimetable.UpdateURL; Lessons = newTimetable.Lessons; } try { OnSucessfulUpdate?.Invoke(this, null); } catch { } SaveAsync(); return(true); } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.ToString()); //throw; return(false); } }