Initial commit
This commit is contained in:
commit
3abc7ec6d1
48 files changed
+9873
No files matched your search
@@ -0,0 +1,17 @@
|
||||
FROM mcr.microsoft.com/devcontainers/base:ubuntu24.04
|
||||
|
||||
USER root
|
||||
|
||||
ENV DOTNET_ROOT=/usr/share/dotnet \
|
||||
PATH=/usr/share/dotnet:$PATH
|
||||
|
||||
ARG DOTNET_SDK_TOOLING_CHANNEL=10.0.3xx
|
||||
|
||||
RUN set -eux; \
|
||||
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh; \
|
||||
chmod +x /tmp/dotnet-install.sh; \
|
||||
/tmp/dotnet-install.sh --channel "$DOTNET_SDK_TOOLING_CHANNEL" --quality GA --install-dir /usr/share/dotnet; \
|
||||
rm -f /tmp/dotnet-install.sh
|
||||
|
||||
USER vscode
|
||||
WORKDIR /workspaces
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Backend",
|
||||
"dockerComposeFile": ["../../docker-compose.yml"],
|
||||
"service": "backend",
|
||||
"workspaceFolder": "/workspaces/backend",
|
||||
"updateRemoteUserUID": false,
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": ["esbenp.prettier-vscode", "mikeburgh.xml-format", "ms-dotnettools.csdevkit@3.10.14"],
|
||||
"settings": {
|
||||
"dotnetAcquisitionExtension.sharedExistingDotnetPath": "/usr/share/dotnet/dotnet",
|
||||
"remote.autoForwardPorts": false,
|
||||
"[csharp]": {
|
||||
"editor.defaultFormatter": "ms-dotnettools.csharp"
|
||||
},
|
||||
"[xml]": {
|
||||
"editor.defaultFormatter": "mikeburgh.xml-format"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"forwardPorts": [5000, 5001],
|
||||
"portsAttributes": {
|
||||
"5001": {
|
||||
"protocol": "https"
|
||||
}
|
||||
},
|
||||
"remoteUser": "vscode"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
root = true
|
||||
[*]
|
||||
end_of_line = lf
|
||||
@@ -0,0 +1 @@
|
||||
* text=auto
|
||||
@@ -0,0 +1,51 @@
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# Certificates
|
||||
[.]certs/
|
||||
|
||||
# Others
|
||||
~$*
|
||||
*~
|
||||
CodeCoverage/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostNordLotteriet.WebAPI", "src\PostNordLotteriet.WebAPI\PostNordLotteriet.WebAPI.csproj", "{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{AE85FFEC-CD86-4C18-8880-F56D01C1D44C} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using PostNordLotteriet.WebAPI.Services;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI.Controllers
|
||||
{
|
||||
[ApiVersion("1.0")]
|
||||
[Route("rest/[controller]/v{v:apiVersion}")]
|
||||
[ApiController]
|
||||
[EnableRateLimiting("fixed")]
|
||||
public class ShipmentController : ControllerBase
|
||||
{
|
||||
private readonly IWorkDayService _workDayService;
|
||||
|
||||
public ShipmentController(IWorkDayService workDayService)
|
||||
{
|
||||
_workDayService = workDayService;
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("trackandtrace")]
|
||||
public IActionResult Get()
|
||||
{
|
||||
DateTime currentDate = DateTime.Now;
|
||||
|
||||
if (_workDayService.IsNonWorkDay(currentDate))
|
||||
{
|
||||
DateTime nextWorkDay = _workDayService.GetNextWorkDay(currentDate);
|
||||
|
||||
Response.Headers.RetryAfter = nextWorkDay
|
||||
.ToUniversalTime()
|
||||
.ToString("R", CultureInfo.InvariantCulture);
|
||||
|
||||
return StatusCode(
|
||||
StatusCodes.Status503ServiceUnavailable,
|
||||
new { message = "Ingen postutdelning på arbetsfria dagar." });
|
||||
}
|
||||
|
||||
return Random.Shared.NextDouble() < 0.4
|
||||
? Ok(new { message = "Grattis! Försändelsen finns snart i en brevlåda nära dig." })
|
||||
: BadRequest(new { message = "Tyvärr, ingen post idag." });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI.Extensions
|
||||
{
|
||||
public static class ApiVersioningExtensions
|
||||
{
|
||||
public static IServiceCollection AddUrlSegmentApiVersioning(this IServiceCollection services)
|
||||
{
|
||||
services.AddApiVersioning(options =>
|
||||
{
|
||||
options.DefaultApiVersion = new ApiVersion(1, 0);
|
||||
options.ReportApiVersions = true;
|
||||
options.AssumeDefaultVersionWhenUnspecified = true;
|
||||
options.ApiVersionReader = new UrlSegmentApiVersionReader();
|
||||
})
|
||||
.AddMvc()
|
||||
.AddApiExplorer(options =>
|
||||
{
|
||||
options.GroupNameFormat = "'v'V";
|
||||
options.SubstituteApiVersionInUrl = true;
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Threading.RateLimiting;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using PostNordLotteriet.WebAPI.Services;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI.Extensions
|
||||
{
|
||||
public static class RateLimiterExtensions
|
||||
{
|
||||
// Adds a rate limiter with a custom error message in JSON format.
|
||||
public static IServiceCollection AddPostNordLotterietRateLimiter(this IServiceCollection services)
|
||||
{
|
||||
services.AddRateLimiter(options =>
|
||||
{
|
||||
options.AddPolicy(policyName: "fixed", httpContext =>
|
||||
{
|
||||
// Disable rate limiter if today is a non-work day.
|
||||
if (httpContext.RequestServices.GetRequiredService<IWorkDayService>().IsNonWorkDay(DateTime.Now))
|
||||
{
|
||||
return RateLimitPartition.GetNoLimiter("NoLimiter");
|
||||
}
|
||||
else
|
||||
{
|
||||
return RateLimitPartition.GetFixedWindowLimiter(partitionKey: httpContext.Connection.RemoteIpAddress?.ToString()
|
||||
?? "Unknown",
|
||||
factory: _ => new FixedWindowRateLimiterOptions
|
||||
{
|
||||
Window = TimeSpan.FromDays(1),
|
||||
PermitLimit = 1
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
||||
|
||||
options.OnRejected = async (context, cancellationToken) =>
|
||||
{
|
||||
HttpContext httpContext = context.HttpContext;
|
||||
|
||||
IWorkDayService workDayService =
|
||||
httpContext.RequestServices.GetRequiredService<IWorkDayService>();
|
||||
|
||||
DateTimeOffset now = DateTimeOffset.Now;
|
||||
|
||||
DateTime nextWorkDay = workDayService.GetNextWorkDay(now.DateTime);
|
||||
|
||||
// The next workday starts at midnight in the server's local time zone.
|
||||
DateTimeOffset nextWorkDayStart = new(
|
||||
nextWorkDay,
|
||||
now.Offset);
|
||||
|
||||
DateTimeOffset nextAttempt = nextWorkDayStart;
|
||||
|
||||
// Get the rate limiter's actual remaining lockout duration.
|
||||
if (context.Lease.TryGetMetadata(
|
||||
MetadataName.RetryAfter,
|
||||
out TimeSpan retryAfter))
|
||||
{
|
||||
DateTimeOffset limiterReset = now.Add(retryAfter);
|
||||
|
||||
if (limiterReset > nextAttempt)
|
||||
{
|
||||
nextAttempt = limiterReset;
|
||||
}
|
||||
}
|
||||
|
||||
string formattedNextAttempt = nextAttempt.ToString(
|
||||
"dddd d MMMM 'klockan' HH:mm",
|
||||
CultureInfo.GetCultureInfo("sv-SE"));
|
||||
|
||||
httpContext.Response.ContentType = "application/json";
|
||||
|
||||
httpContext.Response.Headers.RetryAfter = nextAttempt
|
||||
.ToUniversalTime()
|
||||
.ToString("R", CultureInfo.InvariantCulture);
|
||||
|
||||
await httpContext.Response.WriteAsync(
|
||||
JsonSerializer.Serialize(new
|
||||
{
|
||||
message = $"Posten delas ut en gång per arbetsdag. Gör ett nytt försök {formattedNextAttempt}."
|
||||
}),
|
||||
cancellationToken);
|
||||
};
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers/" />
|
||||
<Folder Include="Extensions/" />
|
||||
<Folder Include="Services/" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Asp.Versioning.Mvc" Version="10.0.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="10.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,20 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://0.0.0.0:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://0.0.0.0:5001;http://0.0.0.0:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI.Services
|
||||
{
|
||||
public interface IWorkDayService
|
||||
{
|
||||
bool IsNonWorkDay(DateTime date);
|
||||
DateTime GetNextWorkDay(DateTime date);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI.Services
|
||||
{
|
||||
public class WorkDayService : IWorkDayService
|
||||
{
|
||||
private static readonly ConcurrentDictionary<int, HashSet<DateTime>> _nonWorkDayCache = new ConcurrentDictionary<int, HashSet<DateTime>>();
|
||||
|
||||
private static readonly object _cacheLock = new object();
|
||||
private static int _cacheYear = DateTime.Today.Year;
|
||||
|
||||
// Method to check if a given date is a non-working day.
|
||||
public bool IsNonWorkDay(DateTime date)
|
||||
{
|
||||
if (date.DayOfWeek == DayOfWeek.Saturday ||
|
||||
date.DayOfWeek == DayOfWeek.Sunday)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ClearCacheIfOutdated();
|
||||
|
||||
// Check if the date matches any fixed or moveable non-working days.
|
||||
return _nonWorkDayCache.GetOrAdd(
|
||||
date.Year,
|
||||
year => GetFixedNonWorkDays(year)
|
||||
.Concat(GetMoveableNonWorkDays(year))
|
||||
.Select(d => d.Date)
|
||||
.ToHashSet())
|
||||
.Contains(date.Date);
|
||||
}
|
||||
|
||||
// Computes and returns the next working day after the given date.
|
||||
public DateTime GetNextWorkDay(DateTime date)
|
||||
{
|
||||
DateTime nextDate = date.Date.AddDays(1);
|
||||
|
||||
while (IsNonWorkDay(nextDate))
|
||||
{
|
||||
nextDate = nextDate.AddDays(1);
|
||||
}
|
||||
|
||||
return nextDate;
|
||||
}
|
||||
|
||||
// Returns fixed non-working days for the given year.
|
||||
private static IEnumerable<DateTime> GetFixedNonWorkDays(int year)
|
||||
{
|
||||
return new DateTime[]
|
||||
{
|
||||
new DateTime(year, 1, 1),
|
||||
new DateTime(year, 1, 6),
|
||||
new DateTime(year, 5, 1),
|
||||
new DateTime(year, 6, 6)
|
||||
}
|
||||
.Concat(
|
||||
new int[] { 24, 25, 26, 31 }
|
||||
.Select(day => new DateTime(year, 12, day)));
|
||||
}
|
||||
|
||||
// Returns moveable non-working days for the given year.
|
||||
private static DateTime[] GetMoveableNonWorkDays(int year)
|
||||
{
|
||||
DateTime easterSunday = GetEasterDate(year);
|
||||
|
||||
return new DateTime[]
|
||||
{
|
||||
easterSunday.AddDays(-2), // Good Friday
|
||||
easterSunday.AddDays(1), // Easter Monday
|
||||
easterSunday.AddDays(39), // Ascension Day
|
||||
GetMidsummerEve(year) // Midsummer Eve
|
||||
};
|
||||
}
|
||||
|
||||
private static DateTime GetMidsummerEve(int year)
|
||||
{
|
||||
return Enumerable.Range(19, 7)
|
||||
.Select(day => new DateTime(year, 6, day))
|
||||
.First(date => date.DayOfWeek == DayOfWeek.Friday);
|
||||
}
|
||||
|
||||
// Computes and returns the date of Easter Sunday for the given year.
|
||||
private static DateTime GetEasterDate(int year)
|
||||
{
|
||||
int a = year % 19;
|
||||
int b = year / 100;
|
||||
int c = year % 100;
|
||||
int d = b / 4;
|
||||
int e = b % 4;
|
||||
int f = (b + 8) / 25;
|
||||
int g = (b - f + 1) / 3;
|
||||
int h = (19 * a + b - d - g + 15) % 30;
|
||||
int i = c / 4;
|
||||
int k = c % 4;
|
||||
int l = (32 + 2 * e + 2 * i - h - k) % 7;
|
||||
int m = (a + 11 * h + 22 * l) / 451;
|
||||
|
||||
int value = h + l - 7 * m + 114;
|
||||
int month = value / 31;
|
||||
int day = value % 31 + 1;
|
||||
|
||||
return new DateTime(year, month, day);
|
||||
}
|
||||
|
||||
private static void ClearCacheIfOutdated()
|
||||
{
|
||||
int currentYear = DateTime.Today.Year;
|
||||
|
||||
if (Volatile.Read(ref _cacheYear) == currentYear)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_cacheLock)
|
||||
{
|
||||
if (_cacheYear == currentYear)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_nonWorkDayCache.Clear();
|
||||
Volatile.Write(ref _cacheYear, currentYear);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using PostNordLotteriet.WebAPI.Extensions;
|
||||
using PostNordLotteriet.WebAPI.Services;
|
||||
|
||||
namespace PostNordLotteriet.WebAPI
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IWorkDayService, WorkDayService>();
|
||||
|
||||
services.AddControllers();
|
||||
|
||||
services.AddUrlSegmentApiVersioning();
|
||||
|
||||
// Configures routing options to enforce lowercase formatting.
|
||||
services.Configure<RouteOptions>(options =>
|
||||
{
|
||||
options.LowercaseUrls = true;
|
||||
options.LowercaseQueryStrings = true;
|
||||
});
|
||||
|
||||
services.AddPostNordLotterietRateLimiter();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseRateLimiter();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
Reference in new issue
Block a user