diff --git a/BlazorApp/BlazorApp.sln b/BlazorApp/BlazorApp.sln
index acb22ab..76c4eec 100644
--- a/BlazorApp/BlazorApp.sln
+++ b/BlazorApp/BlazorApp.sln
@@ -11,6 +11,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorStateApp", "BlazorSta
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RankingApp", "RankingApp\RankingApp.csproj", "{6DCA770F-A98B-4A84-9139-A24F77C592D3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAPI", "WebAPI\WebAPI.csproj", "{0AC89B1F-7635-4513-B030-CABF1D582DB1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedData", "SharedData\SharedData.csproj", "{0985C05F-BC2C-4BBE-A413-5E668EC9CFA0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,6 +37,14 @@ Global
{6DCA770F-A98B-4A84-9139-A24F77C592D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6DCA770F-A98B-4A84-9139-A24F77C592D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6DCA770F-A98B-4A84-9139-A24F77C592D3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0AC89B1F-7635-4513-B030-CABF1D582DB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AC89B1F-7635-4513-B030-CABF1D582DB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AC89B1F-7635-4513-B030-CABF1D582DB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0AC89B1F-7635-4513-B030-CABF1D582DB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0985C05F-BC2C-4BBE-A413-5E668EC9CFA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0985C05F-BC2C-4BBE-A413-5E668EC9CFA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0985C05F-BC2C-4BBE-A413-5E668EC9CFA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0985C05F-BC2C-4BBE-A413-5E668EC9CFA0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/BlazorApp/RankingApp/RankingApp.csproj b/BlazorApp/RankingApp/RankingApp.csproj
index 91c0eb0..ceea0ce 100644
--- a/BlazorApp/RankingApp/RankingApp.csproj
+++ b/BlazorApp/RankingApp/RankingApp.csproj
@@ -15,4 +15,8 @@
+
+
+
+
diff --git a/BlazorApp/SharedData/Models/GameResult.cs b/BlazorApp/SharedData/Models/GameResult.cs
new file mode 100644
index 0000000..139b44e
--- /dev/null
+++ b/BlazorApp/SharedData/Models/GameResult.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedData.Models
+{
+ public class GameResult
+ {
+ public int Id { get; set; }
+ public int UserId { get; set; }
+ public string UserName { get; set; }
+ public int Score { get; set; }
+ public DateTime Date { get; set; }
+ }
+}
diff --git a/BlazorApp/SharedData/SharedData.csproj b/BlazorApp/SharedData/SharedData.csproj
new file mode 100644
index 0000000..27ac386
--- /dev/null
+++ b/BlazorApp/SharedData/SharedData.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/BlazorApp/WebAPI/Controllers/WeatherForecastController.cs b/BlazorApp/WebAPI/Controllers/WeatherForecastController.cs
new file mode 100644
index 0000000..e8bf7d2
--- /dev/null
+++ b/BlazorApp/WebAPI/Controllers/WeatherForecastController.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace WebAPI.Controllers
+{
+ [ApiController]
+ [Route("[controller]")]
+ public class WeatherForecastController : ControllerBase
+ {
+ private static readonly string[] Summaries = new[]
+ {
+ "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
+ };
+
+ private readonly ILogger _logger;
+
+ public WeatherForecastController(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ [HttpGet(Name = "GetWeatherForecast")]
+ public IEnumerable Get()
+ {
+ return Enumerable.Range(1, 5).Select(index => new WeatherForecast
+ {
+ Date = DateTime.Now.AddDays(index),
+ TemperatureC = Random.Shared.Next(-20, 55),
+ Summary = Summaries[Random.Shared.Next(Summaries.Length)]
+ })
+ .ToArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/BlazorApp/WebAPI/Data/ApplicationDbContext.cs b/BlazorApp/WebAPI/Data/ApplicationDbContext.cs
new file mode 100644
index 0000000..2e9ce35
--- /dev/null
+++ b/BlazorApp/WebAPI/Data/ApplicationDbContext.cs
@@ -0,0 +1,16 @@
+using Microsoft.EntityFrameworkCore;
+using SharedData.Models;
+
+namespace WebAPI.Data
+{
+ public class ApplicationDbContext : DbContext
+ {
+ public DbSet GameResults { get; set; }
+
+ public ApplicationDbContext(DbContextOptions options)
+ : base(options)
+ {
+
+ }
+ }
+}
diff --git a/BlazorApp/WebAPI/Migrations/20230825060048_WebAPI.Designer.cs b/BlazorApp/WebAPI/Migrations/20230825060048_WebAPI.Designer.cs
new file mode 100644
index 0000000..3694422
--- /dev/null
+++ b/BlazorApp/WebAPI/Migrations/20230825060048_WebAPI.Designer.cs
@@ -0,0 +1,56 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using WebAPI.Data;
+
+#nullable disable
+
+namespace WebAPI.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20230825060048_WebAPI")]
+ partial class WebAPI
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("SharedData.Models.GameResult", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Date")
+ .HasColumnType("datetime2");
+
+ b.Property("Score")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("GameResults");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/BlazorApp/WebAPI/Migrations/20230825060048_WebAPI.cs b/BlazorApp/WebAPI/Migrations/20230825060048_WebAPI.cs
new file mode 100644
index 0000000..1745751
--- /dev/null
+++ b/BlazorApp/WebAPI/Migrations/20230825060048_WebAPI.cs
@@ -0,0 +1,38 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace WebAPI.Migrations
+{
+ ///
+ public partial class WebAPI : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "GameResults",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ UserId = table.Column(type: "int", nullable: false),
+ UserName = table.Column(type: "nvarchar(max)", nullable: false),
+ Score = table.Column(type: "int", nullable: false),
+ Date = table.Column(type: "datetime2", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_GameResults", x => x.Id);
+ });
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "GameResults");
+ }
+ }
+}
diff --git a/BlazorApp/WebAPI/Migrations/ApplicationDbContextModelSnapshot.cs b/BlazorApp/WebAPI/Migrations/ApplicationDbContextModelSnapshot.cs
new file mode 100644
index 0000000..65ae33e
--- /dev/null
+++ b/BlazorApp/WebAPI/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -0,0 +1,53 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using WebAPI.Data;
+
+#nullable disable
+
+namespace WebAPI.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ partial class ApplicationDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("SharedData.Models.GameResult", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Date")
+ .HasColumnType("datetime2");
+
+ b.Property("Score")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("GameResults");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/BlazorApp/WebAPI/Program.cs b/BlazorApp/WebAPI/Program.cs
new file mode 100644
index 0000000..33a8bd8
--- /dev/null
+++ b/BlazorApp/WebAPI/Program.cs
@@ -0,0 +1,42 @@
+using Microsoft.EntityFrameworkCore;
+using WebAPI.Data;
+
+namespace WebAPI
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+
+ builder.Services.AddControllers();
+ // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+ builder.Services.AddEndpointsApiExplorer();
+ builder.Services.AddSwaggerGen();
+
+ var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
+ builder.Services.AddDbContext(options =>
+ options.UseSqlServer(connectionString));
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+
+ app.UseHttpsRedirection();
+
+ app.UseAuthorization();
+
+
+ app.MapControllers();
+
+ app.Run();
+ }
+ }
+}
\ No newline at end of file
diff --git a/BlazorApp/WebAPI/Properties/launchSettings.json b/BlazorApp/WebAPI/Properties/launchSettings.json
new file mode 100644
index 0000000..573b824
--- /dev/null
+++ b/BlazorApp/WebAPI/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:56899",
+ "sslPort": 44377
+ }
+ },
+ "profiles": {
+ "WebAPI": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "https://localhost:7021;http://localhost:5024",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/BlazorApp/WebAPI/WeatherForecast.cs b/BlazorApp/WebAPI/WeatherForecast.cs
new file mode 100644
index 0000000..f154876
--- /dev/null
+++ b/BlazorApp/WebAPI/WeatherForecast.cs
@@ -0,0 +1,13 @@
+namespace WebAPI
+{
+ public class WeatherForecast
+ {
+ public DateTime Date { get; set; }
+
+ public int TemperatureC { get; set; }
+
+ public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+
+ public string? Summary { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/BlazorApp/WebAPI/WebAPI.csproj b/BlazorApp/WebAPI/WebAPI.csproj
new file mode 100644
index 0000000..bdfb108
--- /dev/null
+++ b/BlazorApp/WebAPI/WebAPI.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BlazorApp/WebAPI/appsettings.Development.json b/BlazorApp/WebAPI/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/BlazorApp/WebAPI/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/BlazorApp/WebAPI/appsettings.json b/BlazorApp/WebAPI/appsettings.json
new file mode 100644
index 0000000..436a4c6
--- /dev/null
+++ b/BlazorApp/WebAPI/appsettings.json
@@ -0,0 +1,12 @@
+{
+ "ConnectionStrings": {
+ "DefaultConnection": "Data Source=peacecloud.synology.me,21433;Initial Catalog=RankingAPI;User ID=study;Password=Study1234;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}