From 150cca45ec70a65ad9009e04f0b40d6867a92b3c Mon Sep 17 00:00:00 2001 From: Jade VAN BRABANDT Date: Wed, 13 Dec 2023 09:59:39 +0100 Subject: [PATCH 1/6] Feat : Page & Start of API integration --- Blazor/Blazor.sln | 50 +++++++-------- Blazor/Blazor/Blazor.csproj | 7 +++ Blazor/Blazor/Models/AdministratorsModel.cs | 28 +++++++++ Blazor/Blazor/Models/AnswerModel.cs | 16 +++++ Blazor/Blazor/Models/ChaptersModel.cs | 13 ++++ Blazor/Blazor/Models/PlayerModel.cs | 25 ++++++++ Blazor/Blazor/Models/QuestionsModel.cs | 24 ++++++++ .../Pages/{FetchData.razor => Admins.razor} | 2 +- Blazor/Blazor/Pages/Admins.razor.cs | 61 +++++++++++++++++++ Blazor/Blazor/Pages/Chapters.razor | 13 ++++ Blazor/Blazor/Pages/Chapters.razor.cs | 61 +++++++++++++++++++ Blazor/Blazor/Pages/Index.razor.cs | 6 ++ Blazor/Blazor/Pages/Questions.razor | 47 ++++++++++++++ Blazor/Blazor/Pages/Questions.razor.cs | 6 ++ Blazor/Blazor/Program.cs | 11 ++++ Blazor/Blazor/Shared/NavMenu.razor | 13 ++-- 16 files changed, 353 insertions(+), 30 deletions(-) create mode 100644 Blazor/Blazor/Models/AdministratorsModel.cs create mode 100644 Blazor/Blazor/Models/AnswerModel.cs create mode 100644 Blazor/Blazor/Models/ChaptersModel.cs create mode 100644 Blazor/Blazor/Models/PlayerModel.cs create mode 100644 Blazor/Blazor/Models/QuestionsModel.cs rename Blazor/Blazor/Pages/{FetchData.razor => Admins.razor} (98%) create mode 100644 Blazor/Blazor/Pages/Admins.razor.cs create mode 100644 Blazor/Blazor/Pages/Chapters.razor create mode 100644 Blazor/Blazor/Pages/Chapters.razor.cs create mode 100644 Blazor/Blazor/Pages/Index.razor.cs create mode 100644 Blazor/Blazor/Pages/Questions.razor create mode 100644 Blazor/Blazor/Pages/Questions.razor.cs diff --git a/Blazor/Blazor.sln b/Blazor/Blazor.sln index f68a3ac..812049d 100644 --- a/Blazor/Blazor.sln +++ b/Blazor/Blazor.sln @@ -1,25 +1,25 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.8.34330.188 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazor", "Blazor\Blazor.csproj", "{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {75BB0A32-C002-4B33-88B3-421A9369D9CB} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor", "Blazor\Blazor.csproj", "{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {75BB0A32-C002-4B33-88B3-421A9369D9CB} + EndGlobalSection +EndGlobal diff --git a/Blazor/Blazor/Blazor.csproj b/Blazor/Blazor/Blazor.csproj index 4c2bb77..9b5a10d 100644 --- a/Blazor/Blazor/Blazor.csproj +++ b/Blazor/Blazor/Blazor.csproj @@ -6,4 +6,11 @@ enable + + + + + + + diff --git a/Blazor/Blazor/Models/AdministratorsModel.cs b/Blazor/Blazor/Models/AdministratorsModel.cs new file mode 100644 index 0000000..023cce4 --- /dev/null +++ b/Blazor/Blazor/Models/AdministratorsModel.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Cryptography.KeyDerivation; +using Microsoft.AspNetCore.Identity; +using System.Security.Cryptography; + +namespace Blazor.Models; + +public class AdministratorsModel : PasswordHasher +{ + public int Id { get; private set; } + public string Username { get; private set; } + public string HashedPassword { get; set; } + + private byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // for password hash + + AdministratorsModel(int id, string username, string password) + { + this.Id = id; + this.Username = username; + //hash password + this.HashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2( + password: password!, + salt: salt, + prf: KeyDerivationPrf.HMACSHA256, + iterationCount: 100000, + numBytesRequested: 256 / 8) + ); + } +} diff --git a/Blazor/Blazor/Models/AnswerModel.cs b/Blazor/Blazor/Models/AnswerModel.cs new file mode 100644 index 0000000..5464dbe --- /dev/null +++ b/Blazor/Blazor/Models/AnswerModel.cs @@ -0,0 +1,16 @@ +namespace Blazor.Models; + +public class AnswerModel + +{ + public int Id { get; private set; } + public string Content { get; set; } + public int IdQuestion { get; private set; } + + public AnswerModel(int id, string content, int idQuestion) + { + Id = id; + Content = content; + IdQuestion = idQuestion; + } +} diff --git a/Blazor/Blazor/Models/ChaptersModel.cs b/Blazor/Blazor/Models/ChaptersModel.cs new file mode 100644 index 0000000..24862f0 --- /dev/null +++ b/Blazor/Blazor/Models/ChaptersModel.cs @@ -0,0 +1,13 @@ +namespace Blazor.Models; + +public class ChaptersModel +{ + public int Id { get; private set; } + public string Name { get; set; } + + public ChaptersModel(int id, string name) + { + Id = id; + Name = name; + } +} diff --git a/Blazor/Blazor/Models/PlayerModel.cs b/Blazor/Blazor/Models/PlayerModel.cs new file mode 100644 index 0000000..2079d18 --- /dev/null +++ b/Blazor/Blazor/Models/PlayerModel.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Cryptography.KeyDerivation; +using System.Security.Cryptography; + +namespace Blazor.Models; + +public class PlayerModel +{ + public int Id { get; private set; } + public string Nickname { get; private set; } + public string HashedPassword { get; set; } + private byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // for password hash + public PlayerModel(int id, string nickname, string password) + { + Id = id; + Nickname = nickname; + //hash password + HashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2( + password: password!, + salt: salt, + prf: KeyDerivationPrf.HMACSHA256, + iterationCount: 100000, + numBytesRequested: 256 / 8) + ); + } +} diff --git a/Blazor/Blazor/Models/QuestionsModel.cs b/Blazor/Blazor/Models/QuestionsModel.cs new file mode 100644 index 0000000..19c395c --- /dev/null +++ b/Blazor/Blazor/Models/QuestionsModel.cs @@ -0,0 +1,24 @@ +namespace Blazor.Models; + +public class QuestionsModel +{ + public int Id { get; private set; } + public string Content { get; set; } + public int IdChapter { get; private set; } + public int? IdAnswerGood { get; set; } + public int Difficulty { get; set; } + public int NbFails { get; private set; } + + public QuestionsModel(int id, string content, int idChapter, int difficulty, int nbFails, int? idAnswerGood = null) + { + Id = id; + Content = content; + IdChapter = idChapter; + Difficulty = difficulty; + NbFails = nbFails; + IdAnswerGood = idAnswerGood; + } + + public void addFails(int nb) { NbFails += nb; } + public void removeFails(int nb) { NbFails -= nb; } +} diff --git a/Blazor/Blazor/Pages/FetchData.razor b/Blazor/Blazor/Pages/Admins.razor similarity index 98% rename from Blazor/Blazor/Pages/FetchData.razor rename to Blazor/Blazor/Pages/Admins.razor index 5ae9d70..74ddbb0 100644 --- a/Blazor/Blazor/Pages/FetchData.razor +++ b/Blazor/Blazor/Pages/Admins.razor @@ -1,4 +1,4 @@ -@page "/fetchdata" +@page "/admins" @using Blazor.Data @inject WeatherForecastService ForecastService diff --git a/Blazor/Blazor/Pages/Admins.razor.cs b/Blazor/Blazor/Pages/Admins.razor.cs new file mode 100644 index 0000000..af73c75 --- /dev/null +++ b/Blazor/Blazor/Pages/Admins.razor.cs @@ -0,0 +1,61 @@ +using Blazor.Models; +using Blazored.LocalStorage; +using Blazorise.DataGrid; +using Microsoft.AspNetCore.Components; + +namespace Blazor.Pages; +public partial class Admins +{ + private List items; + + private int totalItem; + + [Inject] + public IWebHostEnvironment WebHostEnvironment { get; set; } + + [Inject] + public HttpClient Http { get; set; } + + [Inject] + public ILocalStorageService LocalStorage { get; set; } + + [Inject] + public NavigationManager NavigationManager { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + // Do not treat this action if is not the first render + if (!firstRender) + { + return; + } + + var currentData = await LocalStorage.GetItemAsync("data"); + + // Check if data exist in the local storage + if (currentData == null) + { + // this code add in the local storage the fake data (we load the data sync for initialize the data before load the OnReadData method) + var originalData = Http.GetFromJsonAsync($"trusting-panini.87-106-126-109.plesk.page/api/chapters").Result; + await LocalStorage.SetItemAsync("data", originalData); + } + } + + private async Task OnReadData(DataGridReadDataEventArgs e) + { + if (e.CancellationToken.IsCancellationRequested) + { + return; + } + + // When you use a real API, we use this follow code + //var response = await Http.GetJsonAsync( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" ); + var response = (await LocalStorage.GetItemAsync("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList(); + + if (!e.CancellationToken.IsCancellationRequested) + { + totalItem = (await LocalStorage.GetItemAsync>("data")).Count; + items = new List(response); // an actual data for the current page + } + } +} \ No newline at end of file diff --git a/Blazor/Blazor/Pages/Chapters.razor b/Blazor/Blazor/Pages/Chapters.razor new file mode 100644 index 0000000..3ba135f --- /dev/null +++ b/Blazor/Blazor/Pages/Chapters.razor @@ -0,0 +1,13 @@ +@page "/chapters" +@using Blazor.Models +

Liste

+ + + + \ No newline at end of file diff --git a/Blazor/Blazor/Pages/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters.razor.cs new file mode 100644 index 0000000..ae50696 --- /dev/null +++ b/Blazor/Blazor/Pages/Chapters.razor.cs @@ -0,0 +1,61 @@ +using Blazor.Models; +using Blazored.LocalStorage; +using Blazorise.DataGrid; +using Microsoft.AspNetCore.Components; + +namespace Blazor.Pages; +public partial class Chapters +{ + private List items; + + private int totalItem; + + [Inject] + public IWebHostEnvironment WebHostEnvironment { get; set; } + + [Inject] + public HttpClient Http { get; set; } + + [Inject] + public ILocalStorageService LocalStorage { get; set; } + + [Inject] + public NavigationManager NavigationManager { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + // Do not treat this action if is not the first render + if (!firstRender) + { + return; + } + + var currentData = await LocalStorage.GetItemAsync("data"); + + // Check if data exist in the local storage + if (currentData == null) + { + // this code add in the local storage the fake data (we load the data sync for initialize the data before load the OnReadData method) + var originalData = Http.GetFromJsonAsync($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result; + await LocalStorage.SetItemAsync("data", originalData); + } + } + + private async Task OnReadData(DataGridReadDataEventArgs e) + { + if (e.CancellationToken.IsCancellationRequested) + { + return; + } + + // When you use a real API, we use this follow code + //var response = await Http.GetJsonAsync( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" ); + var response = (await LocalStorage.GetItemAsync("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList(); + + if (!e.CancellationToken.IsCancellationRequested) + { + totalItem = (await LocalStorage.GetItemAsync>("data")).Count; + items = new List(response); // an actual data for the current page + } + } +} \ No newline at end of file diff --git a/Blazor/Blazor/Pages/Index.razor.cs b/Blazor/Blazor/Pages/Index.razor.cs new file mode 100644 index 0000000..20708a0 --- /dev/null +++ b/Blazor/Blazor/Pages/Index.razor.cs @@ -0,0 +1,6 @@ +namespace Blazor.Pages; + +public partial class Index +{ +} + diff --git a/Blazor/Blazor/Pages/Questions.razor b/Blazor/Blazor/Pages/Questions.razor new file mode 100644 index 0000000..a123a0c --- /dev/null +++ b/Blazor/Blazor/Pages/Questions.razor @@ -0,0 +1,47 @@ +@page "/questions" +@using Blazor.Data +@inject WeatherForecastService ForecastService + +Weather forecast + +

Weather forecast

+ +

This component demonstrates fetching data from a service.

+ +@if (forecasts == null) +{ +

Loading...

+} +else +{ + + + + + + + + + + + @foreach (var forecast in forecasts) + { + + + + + + + } + +
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
+} + +@code { + private WeatherForecast[]? forecasts; + + protected override async Task OnInitializedAsync() + { + forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now)); + } +} diff --git a/Blazor/Blazor/Pages/Questions.razor.cs b/Blazor/Blazor/Pages/Questions.razor.cs new file mode 100644 index 0000000..2a62003 --- /dev/null +++ b/Blazor/Blazor/Pages/Questions.razor.cs @@ -0,0 +1,6 @@ +namespace Blazor.Pages; + +public partial class Questions +{ +} + diff --git a/Blazor/Blazor/Program.cs b/Blazor/Blazor/Program.cs index 5195276..be52cc7 100644 --- a/Blazor/Blazor/Program.cs +++ b/Blazor/Blazor/Program.cs @@ -1,4 +1,8 @@ using Blazor.Data; +using Blazored.LocalStorage; +using Blazorise; +using Blazorise.Bootstrap; +using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; @@ -8,6 +12,13 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddSingleton(); +builder.Services.AddHttpClient(); + +builder.Services + .AddBlazorise() + .AddBootstrapProviders() + .AddFontAwesomeIcons(); +builder.Services.AddBlazoredLocalStorage(); var app = builder.Build(); diff --git a/Blazor/Blazor/Shared/NavMenu.razor b/Blazor/Blazor/Shared/NavMenu.razor index 5553e13..617155c 100644 --- a/Blazor/Blazor/Shared/NavMenu.razor +++ b/Blazor/Blazor/Shared/NavMenu.razor @@ -15,13 +15,18 @@ + From 528308d655f222b5934920492997dc8fa340e1a9 Mon Sep 17 00:00:00 2001 From: "Jade.VAN_BRABANDT" Date: Wed, 13 Dec 2023 10:43:13 +0100 Subject: [PATCH 2/6] Feat : API chapter integration --- Blazor/Blazor/Pages/Chapters.razor | 10 +++++----- Blazor/Blazor/Pages/Chapters.razor.cs | 12 ++++++------ Blazor/Blazor/_Imports.razor | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Blazor/Blazor/Pages/Chapters.razor b/Blazor/Blazor/Pages/Chapters.razor index 3ba135f..641bdc5 100644 --- a/Blazor/Blazor/Pages/Chapters.razor +++ b/Blazor/Blazor/Pages/Chapters.razor @@ -1,13 +1,13 @@ @page "/chapters" @using Blazor.Models

Liste

- - - + + \ No newline at end of file diff --git a/Blazor/Blazor/Pages/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters.razor.cs index ae50696..21ff61e 100644 --- a/Blazor/Blazor/Pages/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters.razor.cs @@ -6,9 +6,9 @@ using Microsoft.AspNetCore.Components; namespace Blazor.Pages; public partial class Chapters { - private List items; + private List chapters; - private int totalItem; + private int totalChapter; [Inject] public IWebHostEnvironment WebHostEnvironment { get; set; } @@ -49,13 +49,13 @@ public partial class Chapters } // When you use a real API, we use this follow code - //var response = await Http.GetJsonAsync( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" ); - var response = (await LocalStorage.GetItemAsync("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList(); + //var response = await Http.GetFromJsonAsync( $"https://trusting-panini.87-106-126-109.plesk.page/api/chapters?page={e.Page}&pageSize={e.PageSize}" ); + var response = Http.GetFromJsonAsync($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result; if (!e.CancellationToken.IsCancellationRequested) { - totalItem = (await LocalStorage.GetItemAsync>("data")).Count; - items = new List(response); // an actual data for the current page + totalChapter = (await LocalStorage.GetItemAsync>("data")).Count; + chapters = new List(response); // an actual data for the current page } } } \ No newline at end of file diff --git a/Blazor/Blazor/_Imports.razor b/Blazor/Blazor/_Imports.razor index 2945557..0bfa3cd 100644 --- a/Blazor/Blazor/_Imports.razor +++ b/Blazor/Blazor/_Imports.razor @@ -8,3 +8,4 @@ @using Microsoft.JSInterop @using Blazor @using Blazor.Shared +@using Blazorise.DataGrid From c9dc0c30a793c2e1bcd010fddc8669bf07ebe134 Mon Sep 17 00:00:00 2001 From: "Jade.VAN_BRABANDT" Date: Wed, 13 Dec 2023 11:54:12 +0100 Subject: [PATCH 3/6] Feat : Not finished / Export implementation --- Blazor/Blazor/Blazor.csproj | 3 +++ Blazor/Blazor/Pages/Chapters.razor | 27 +++++++++++++------------- Blazor/Blazor/Pages/Chapters.razor.cs | 28 +++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Blazor/Blazor/Blazor.csproj b/Blazor/Blazor/Blazor.csproj index 9b5a10d..8584edf 100644 --- a/Blazor/Blazor/Blazor.csproj +++ b/Blazor/Blazor/Blazor.csproj @@ -11,6 +11,9 @@ + + + diff --git a/Blazor/Blazor/Pages/Chapters.razor b/Blazor/Blazor/Pages/Chapters.razor index 641bdc5..4bdef15 100644 --- a/Blazor/Blazor/Pages/Chapters.razor +++ b/Blazor/Blazor/Pages/Chapters.razor @@ -1,13 +1,14 @@ -@page "/chapters" -@using Blazor.Models -

Liste

- - - - \ No newline at end of file +@page "/chapters" +@using Blazor.Models +

Liste

+ + + + + diff --git a/Blazor/Blazor/Pages/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters.razor.cs index 21ff61e..d9c6866 100644 --- a/Blazor/Blazor/Pages/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters.razor.cs @@ -1,7 +1,10 @@ using Blazor.Models; using Blazored.LocalStorage; using Blazorise.DataGrid; +using ChoETL; using Microsoft.AspNetCore.Components; +using System.Reflection.Metadata; +using System.Text; namespace Blazor.Pages; public partial class Chapters @@ -58,4 +61,29 @@ public partial class Chapters chapters = new List(response); // an actual data for the current page } } + + private async void Export() + { + StringBuilder sb = new StringBuilder(); + HttpResponseMessage response = await Http.GetAsync("https://trusting-panini.87-106-126-109.plesk.page/api/chapters"); + var json = await response.Content.ReadAsStringAsync(); + using (var jsonFile = ChoJSONReader.LoadText(json)) + { + using (var csvFile = new ChoCSVWriter(sb).WithFirstLineHeader()) + { + csvFile.Write(json); + } + } + string path = @"C:\temp\file"; // path to file + using (FileStream fs = File.Create(path)) + { + // writing data in string + byte[] info = new UTF8Encoding(true).GetBytes(sb.ToString()); + fs.Write(info, 0, info.Length); + + // writing data in bytes already + byte[] data = new byte[] { 0x0 }; + fs.Write(data, 0, data.Length); + } + } } \ No newline at end of file From 77f5a566e944b6d397a163d4bdbae6b9bafd2035 Mon Sep 17 00:00:00 2001 From: "Jade.VAN_BRABANDT" Date: Wed, 13 Dec 2023 13:32:18 +0100 Subject: [PATCH 4/6] =?UTF-8?q?Fix=20:=20c'mieux=20quand=20je=20r=C3=A9fl?= =?UTF-8?q?=C3=A9chis=20=20correctement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Blazor/Blazor/Pages/Chapters.razor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Blazor/Blazor/Pages/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters.razor.cs index d9c6866..d577b97 100644 --- a/Blazor/Blazor/Pages/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters.razor.cs @@ -71,9 +71,12 @@ public partial class Chapters { using (var csvFile = new ChoCSVWriter(sb).WithFirstLineHeader()) { - csvFile.Write(json); + csvFile.Write(jsonFile); } } + + + string path = @"C:\temp\file"; // path to file using (FileStream fs = File.Create(path)) { @@ -85,5 +88,6 @@ public partial class Chapters byte[] data = new byte[] { 0x0 }; fs.Write(data, 0, data.Length); } + } } \ No newline at end of file From 00cb290649ae999a1c76e3106d46a366a244eb36 Mon Sep 17 00:00:00 2001 From: "Jade.VAN_BRABANDT" Date: Thu, 14 Dec 2023 13:53:27 +0100 Subject: [PATCH 5/6] Feat : Finished CSV export, code might not be clean --- Blazor/Blazor/Pages/Chapters.razor | 2 ++ Blazor/Blazor/Pages/Chapters.razor.cs | 19 +++++++------------ Blazor/Blazor/Pages/Chapters.razor.js | 11 +++++++++++ 3 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 Blazor/Blazor/Pages/Chapters.razor.js diff --git a/Blazor/Blazor/Pages/Chapters.razor b/Blazor/Blazor/Pages/Chapters.razor index 4bdef15..d9df7c8 100644 --- a/Blazor/Blazor/Pages/Chapters.razor +++ b/Blazor/Blazor/Pages/Chapters.razor @@ -12,3 +12,5 @@ + + \ No newline at end of file diff --git a/Blazor/Blazor/Pages/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters.razor.cs index d577b97..7e481e2 100644 --- a/Blazor/Blazor/Pages/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters.razor.cs @@ -3,7 +3,7 @@ using Blazored.LocalStorage; using Blazorise.DataGrid; using ChoETL; using Microsoft.AspNetCore.Components; -using System.Reflection.Metadata; +using Microsoft.JSInterop; using System.Text; namespace Blazor.Pages; @@ -25,6 +25,9 @@ public partial class Chapters [Inject] public NavigationManager NavigationManager { get; set; } + [Inject] + public IJSRuntime IJSRuntime { get; set; } + protected override async Task OnAfterRenderAsync(bool firstRender) { // Do not treat this action if is not the first render @@ -75,19 +78,11 @@ public partial class Chapters } } + var sentFile = new MemoryStream(Encoding.ASCII.GetBytes(sb.ToString())); - - string path = @"C:\temp\file"; // path to file - using (FileStream fs = File.Create(path)) + using (var streamRef = new DotNetStreamReference(stream: sentFile)) { - // writing data in string - byte[] info = new UTF8Encoding(true).GetBytes(sb.ToString()); - fs.Write(info, 0, info.Length); - - // writing data in bytes already - byte[] data = new byte[] { 0x0 }; - fs.Write(data, 0, data.Length); + await IJSRuntime.InvokeVoidAsync("downloadFileFromStream", "data.csv", streamRef); } - } } \ No newline at end of file diff --git a/Blazor/Blazor/Pages/Chapters.razor.js b/Blazor/Blazor/Pages/Chapters.razor.js new file mode 100644 index 0000000..37f904d --- /dev/null +++ b/Blazor/Blazor/Pages/Chapters.razor.js @@ -0,0 +1,11 @@ +window.downloadFileFromStream = async (fileName, contentStreamReference) => { + const arrayBuffer = await contentStreamReference.arrayBuffer(); + const blob = new Blob([arrayBuffer]); + const url = URL.createObjectURL(blob); + const anchorElement = document.createElement('a'); + anchorElement.href = url; + anchorElement.download = fileName ?? ''; + anchorElement.click(); + anchorElement.remove(); + URL.revokeObjectURL(url); +} \ No newline at end of file From 0f6e18d1f355d62035cc85fecec51a6bbd3da738 Mon Sep 17 00:00:00 2001 From: "Jade.VAN_BRABANDT" Date: Fri, 15 Dec 2023 15:38:00 +0100 Subject: [PATCH 6/6] Fix : UTF32 encoding --- Blazor/Blazor/Pages/Chapters.razor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Blazor/Blazor/Pages/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters.razor.cs index 7e481e2..cc65a84 100644 --- a/Blazor/Blazor/Pages/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters.razor.cs @@ -78,7 +78,7 @@ public partial class Chapters } } - var sentFile = new MemoryStream(Encoding.ASCII.GetBytes(sb.ToString())); + var sentFile = new MemoryStream(Encoding.UTF32.GetBytes(sb.ToString())); using (var streamRef = new DotNetStreamReference(stream: sentFile)) {