diff --git a/EstusShots.Client/EstusShots.Client.csproj b/EstusShots.Client/EstusShots.Client.csproj
index 548a249..d130a6f 100644
--- a/EstusShots.Client/EstusShots.Client.csproj
+++ b/EstusShots.Client/EstusShots.Client.csproj
@@ -8,4 +8,8 @@
+
+
+
+
diff --git a/EstusShots.Client/EstusShotsClient.cs b/EstusShots.Client/EstusShotsClient.cs
index f5f3927..4a126fe 100644
--- a/EstusShots.Client/EstusShotsClient.cs
+++ b/EstusShots.Client/EstusShotsClient.cs
@@ -55,6 +55,8 @@ namespace EstusShots.Client
var response = await HttpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
+ if (json.IsNullOrWhiteSpace() || json == "{}")
+ return new ApiResponse(new OperationResult(false, "Invalid response", "The server returned no or empty data"));
var result = JsonSerializer.Deserialize>(json, _serializerOptions);
return result;
}
diff --git a/EstusShots.Client/Routes/Players.cs b/EstusShots.Client/Routes/Players.cs
new file mode 100644
index 0000000..de2bfde
--- /dev/null
+++ b/EstusShots.Client/Routes/Players.cs
@@ -0,0 +1,32 @@
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using EstusShots.Shared.Interfaces;
+using EstusShots.Shared.Models;
+using EstusShots.Shared.Models.Parameters;
+
+namespace EstusShots.Client.Routes
+{
+ public class Players : IPlayersController
+ {
+ private readonly EstusShotsClient _client;
+
+ public Players(EstusShotsClient client)
+ {
+ _client = client;
+ }
+ private string ActionUrl([CallerMemberName]string caller = "") =>
+ $"{_client.ApiUrl}{GetType().Name}/{caller}";
+
+ public async Task> GetPlayers(GetPlayersParameter parameter)
+ => await _client.PostToApi(ActionUrl(), parameter);
+
+ public async Task> GetPlayerDetails(GetPlayerDetailsParameter parameter)
+ => await _client.PostToApi(ActionUrl(), parameter);
+
+ public async Task> SavePlayer(SavePlayerParameter parameter)
+ => await _client.PostToApi(ActionUrl(), parameter);
+
+ public async Task> DeletePlayers(DeletePlayerParameter parameter)
+ => await _client.PostToApi(ActionUrl(), parameter);
+ }
+}
\ No newline at end of file
diff --git a/EstusShots.Server/Controllers/PlayersController.cs b/EstusShots.Server/Controllers/PlayersController.cs
new file mode 100644
index 0000000..902137b
--- /dev/null
+++ b/EstusShots.Server/Controllers/PlayersController.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Threading.Tasks;
+using EstusShots.Server.Services;
+using EstusShots.Shared.Interfaces;
+using EstusShots.Shared.Models;
+using EstusShots.Shared.Models.Parameters;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace EstusShots.Server.Controllers
+{
+ [ApiController]
+ [Route("/api/[controller]/[action]")]
+ public class PlayersController : ControllerBase, IPlayersController
+ {
+ private readonly ILogger _logger;
+ private readonly PlayersService _service;
+
+ public PlayersController(ILogger logger, PlayersService service)
+ {
+ _logger = logger;
+ _service = service;
+ }
+
+ private async Task> ServiceCall(Func>> serviceCall)
+ where T : class, IApiResponse, new()
+ {
+ try
+ {
+ if (!ModelState.IsValid)
+ {
+ _logger.LogError($"Model invalid");
+
+ }
+ _logger.LogInformation($"Request received from client '{Request.HttpContext.Connection.RemoteIpAddress}'");
+ return await serviceCall();
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "Exception Occured");
+ return new ApiResponse(new OperationResult(e));
+ }
+ }
+
+ [HttpPost]
+ public async Task> GetPlayers(GetPlayersParameter parameter)
+ => await ServiceCall(() => _service.GetPlayers(parameter));
+
+ [HttpPost]
+ public async Task> GetPlayerDetails(GetPlayerDetailsParameter parameter)
+ => await ServiceCall(() => _service.GetPlayerDetails(parameter));
+
+ [HttpPost]
+ public async Task> SavePlayer(SavePlayerParameter parameter)
+ => await ServiceCall(() => _service.SavePlayer(parameter));
+
+ [HttpPost]
+ public async Task> DeletePlayers(DeletePlayerParameter parameter)
+ => await ServiceCall(() => _service.DeletePlayers(parameter));
+ }
+}
\ No newline at end of file
diff --git a/EstusShots.Server/Program.cs b/EstusShots.Server/Program.cs
index db7d953..e187dd0 100644
--- a/EstusShots.Server/Program.cs
+++ b/EstusShots.Server/Program.cs
@@ -16,9 +16,11 @@ namespace EstusShots.Server
CreateHostBuilder(args).Build().Run();
}
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
+ public static IHostBuilder CreateHostBuilder(string[] args)
+ {
+ return Host.CreateDefaultBuilder(args)
.ConfigureLogging(builder => { builder.AddConsole(); })
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); });
+ }
}
}
\ No newline at end of file
diff --git a/EstusShots.Server/Services/PlayersService.cs b/EstusShots.Server/Services/PlayersService.cs
new file mode 100644
index 0000000..8f813f0
--- /dev/null
+++ b/EstusShots.Server/Services/PlayersService.cs
@@ -0,0 +1,38 @@
+using System.Threading.Tasks;
+using EstusShots.Shared.Interfaces;
+using EstusShots.Shared.Models;
+using EstusShots.Shared.Models.Parameters;
+using Microsoft.Extensions.Logging;
+
+namespace EstusShots.Server.Services
+{
+ public class PlayersService : IPlayersController
+ {
+ private readonly ILogger _logger;
+
+ public PlayersService(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public Task> GetPlayers(GetPlayersParameter parameter)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public Task> GetPlayerDetails(GetPlayerDetailsParameter parameter)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public Task> SavePlayer(SavePlayerParameter parameter)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public Task> DeletePlayers(DeletePlayerParameter parameter)
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/EstusShots.Server/Startup.cs b/EstusShots.Server/Startup.cs
index 3772acd..9af3405 100644
--- a/EstusShots.Server/Startup.cs
+++ b/EstusShots.Server/Startup.cs
@@ -15,7 +15,7 @@ namespace EstusShots.Server
public IConfiguration Configuration { get; }
private bool IsDevelopment { get; set; }
-
+
public Startup(IConfiguration configuration)
{
Configuration = configuration;
@@ -34,19 +34,17 @@ namespace EstusShots.Server
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
- if (IsDevelopment)
- {
- options.JsonSerializerOptions.WriteIndented = true;
- }
+ if (IsDevelopment) options.JsonSerializerOptions.WriteIndented = true;
});
services.AddSwaggerGen(options =>
{
- options.SwaggerDoc("v1", new OpenApiInfo { Title = "Estus Shots API", Version = "v1" });
+ options.SwaggerDoc("v1", new OpenApiInfo {Title = "Estus Shots API", Version = "v1"});
});
// Register business logic services
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -54,23 +52,16 @@ namespace EstusShots.Server
{
IsDevelopment = env.IsDevelopment();
if (IsDevelopment)
- {
app.UseDeveloperExceptionPage();
- }
else
- {
app.UseHttpsRedirection();
- }
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "Estus Shots API V1");
- });
+ app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Estus Shots API V1"); });
app.UseRouting();
app.UseAuthorization();