diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a94f4141fa8e0d057bf58b600bcedfb068739a07..f92cd753a9dfde40b8012c20de6b0987b767a4d1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -38,6 +38,7 @@ jobs: dotnet pack src/NebulaBus/NebulaBus.csproj /p:FileVersion=${{ steps.gitversion.outputs.version }} /p:Version=${{ steps.gitversion.outputs.version }} -p:PackageVersion=${{ steps.gitversion.outputs.version }} --output nupkgs dotnet pack src/NebulaBus.Store.Memory/NebulaBus.Store.Memory.csproj /p:FileVersion=${{ steps.gitversion.outputs.version }} /p:Version=${{ steps.gitversion.outputs.version }} -p:PackageVersion=${{ steps.gitversion.outputs.version }} --output nupkgs dotnet pack src/NebulaBus.Store.Redis/NebulaBus.Store.Redis.csproj /p:FileVersion=${{ steps.gitversion.outputs.version }} /p:Version=${{ steps.gitversion.outputs.version }} -p:PackageVersion=${{ steps.gitversion.outputs.version }} --output nupkgs + dotnet pack src/NebulaBus.Store.Sql/NebulaBus.Store.Sql.csproj /p:FileVersion=${{ steps.gitversion.outputs.version }} /p:Version=${{ steps.gitversion.outputs.version }} -p:PackageVersion=${{ steps.gitversion.outputs.version }} --output nupkgs dotnet pack src/NebulaBus.Transport.Memory/NebulaBus.Transport.Memory.csproj /p:FileVersion=${{ steps.gitversion.outputs.version }} /p:Version=${{ steps.gitversion.outputs.version }} -p:PackageVersion=${{ steps.gitversion.outputs.version }} --output nupkgs dotnet pack src/NebulaBus.Transport.Rabbitmq/NebulaBus.Transport.Rabbitmq.csproj /p:FileVersion=${{ steps.gitversion.outputs.version }} /p:Version=${{ steps.gitversion.outputs.version }} -p:PackageVersion=${{ steps.gitversion.outputs.version }} --output nupkgs diff --git a/.gitignore b/.gitignore index c599bb4901b7ae36d907399db2983f8320c3d937..240f48b6859db4ef3ca53787a4b8a2af98cf5e49 100644 --- a/.gitignore +++ b/.gitignore @@ -399,4 +399,4 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml -/src/WebApplicationSample/appsettings.Local.json +appsettings.Local.json diff --git a/README.md b/README.md index 9d1d7bb41b8f12102830b10bfe56de7b13aa07f5..c6b11ae18a44bdf6be6181ff4a45a6ff337e4d9b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ | ![NuGet Version](https://img.shields.io/nuget/v/NebulaBus?style=plastic&label=NebulaBus&color=blue&link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FNebulaBus%2F) | NebulaBus's Core | | ![NuGet Version](https://img.shields.io/nuget/v/NebulaBus.Store.Memory?style=plastic&label=NebulaBus.Store.Memory&color=blue&link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FNebulaBus.Store.Memory%2F) | NebulaBus Memory Store Provider | | ![NuGet Version](https://img.shields.io/nuget/v/NebulaBus.Store.Redis?style=plastic&label=NebulaBus.Store.Redis&color=blue&link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FNebulaBus.Store.Redis%2F) | NebulaBus Redis Store Provider | +| ![NuGet Version](https://img.shields.io/nuget/v/NebulaBus.Store.Sql?style=plastic&label=NebulaBus.Store.Sql&color=blue&link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FNebulaBus.Store.Sql%2F) | NebulaBus Sql Store Provider | | ![NuGet Version](https://img.shields.io/nuget/v/NebulaBus.Transport.Memory?style=plastic&label=NebulaBus.Transport.Memory&color=blue&link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FNebulaBus.Transport.Memory%2F) | NebulaBus Memory Transport Provider | | ![NuGet Version](https://img.shields.io/nuget/v/NebulaBus.Transport.Rabbitmq?style=plastic&label=NebulaBus.Transport.Rabbitmq&color=blue&link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FNebulaBus.Transport.Rabbitmq%2F) | NebulaBus Rabbitmq Transport Provider | @@ -37,8 +38,8 @@ 安装 https://www.nuget.org/packages/NebulaBus/ ``` -dotnet add package NebulaBus - +dotnet add package NebulaBus.Store.Redis +dotnet add package NebulaBus.Transport.Rabbitmq ``` 注入 @@ -48,7 +49,7 @@ builder.Services.AddNebulaBus(options => { options.ClusterName = "TestCluster"; options.UseRedisStore("localhost:6379,password=****,defaultDatabase=0,prefix=prefix_"); - options.UseRabbitmq(rabbitmq => + options.UseRabbitmqTransport(rabbitmq => { rabbitmq.HostName = “localhost”; rabbitmq.UserName = “guest”; diff --git a/src/NebulaBus.Store.Sql/LockEntity.cs b/src/NebulaBus.Store.Sql/LockEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..c0cb3f90576f418e8d1eed112903f61dd6c44d1a --- /dev/null +++ b/src/NebulaBus.Store.Sql/LockEntity.cs @@ -0,0 +1,10 @@ +namespace NebulaBus.Store.Sql +{ + internal class LockEntity + { + [SqlSugar.SugarColumn(IsPrimaryKey = true)] + public string Id { get; set; } + public string Value { get; set; } + public long ExpireTime { get; set; } + } +} diff --git a/src/NebulaBus.Store.Sql/NebulaBus.Store.Sql.csproj b/src/NebulaBus.Store.Sql/NebulaBus.Store.Sql.csproj new file mode 100644 index 0000000000000000000000000000000000000000..cbf64615549e27a458c85981bf905505bf8442d9 --- /dev/null +++ b/src/NebulaBus.Store.Sql/NebulaBus.Store.Sql.csproj @@ -0,0 +1,28 @@ + + + javen liu + JiewitTech + https://github.com/JiewitTech/NebulaBus.git + https://github.com/JiewitTech/NebulaBus + NebulaBus - Future oriented NET distributed event bus framework, allowing developers to focus on development + NebulaBus enventbus Bus Event Publish + MIT + README.md + $(PackageVersion) + + + + netstandard2.1 + enable + + + + + + + + + + + + diff --git a/src/NebulaBus.Store.Sql/NebulaSqlStoreExtension.cs b/src/NebulaBus.Store.Sql/NebulaSqlStoreExtension.cs new file mode 100644 index 0000000000000000000000000000000000000000..578f41d3e601a0c45dee08b792ac21a44cb30548 --- /dev/null +++ b/src/NebulaBus.Store.Sql/NebulaSqlStoreExtension.cs @@ -0,0 +1,14 @@ +using NebulaBus; +using NebulaBus.Store.Sql; +using SqlSugar; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class NebulaSqlStoreExtension + { + public static void UseSqlStore(this NebulaOptions options, ConnectionConfig connectionConfig) + { + options.AddNebulaServiceProvider(new NebulaSqlStoreServiceProvider(connectionConfig)); + } + } +} diff --git a/src/NebulaBus.Store.Sql/NebulaSqlStoreServiceProvider.cs b/src/NebulaBus.Store.Sql/NebulaSqlStoreServiceProvider.cs new file mode 100644 index 0000000000000000000000000000000000000000..00b65cf5b7458500333b3b1e307c3ea0cee4a376 --- /dev/null +++ b/src/NebulaBus.Store.Sql/NebulaSqlStoreServiceProvider.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using SqlSugar; + +namespace NebulaBus.Store.Sql +{ + internal class NebulaSqlStoreServiceProvider : INebulaServiceProvider + { + private readonly ConnectionConfig _connectionConfig; + + public NebulaSqlStoreServiceProvider(ConnectionConfig connectionConfig) + { + _connectionConfig = connectionConfig; + } + + public void ProvideServices(IServiceCollection services, NebulaOptions options) + { + _connectionConfig.IsAutoCloseConnection = true; + services.AddKeyedSingleton("NebulaBusSqlClient", new SqlSugarScope(_connectionConfig)); + services.TryAddSingleton(); + } + } +} diff --git a/src/NebulaBus.Store.Sql/SqlStore.cs b/src/NebulaBus.Store.Sql/SqlStore.cs new file mode 100644 index 0000000000000000000000000000000000000000..4c8ec7386ed5c132521418552d84ca683bcfc197 --- /dev/null +++ b/src/NebulaBus.Store.Sql/SqlStore.cs @@ -0,0 +1,98 @@ +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; +using System; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; + +namespace NebulaBus.Store.Sql +{ + internal class SqlStore : IStore + { + private string LockKey => $"NebulaBus:{_nebulaOptions.ClusterName}.Lock"; + private readonly SqlSugarScope _sqlClient; + private readonly JsonSerializerOptions _jsonSerializerOptions; + private readonly NebulaOptions _nebulaOptions; + public SqlStore(IServiceProvider serviceProvider, NebulaOptions nebulaOptions) + { + _sqlClient = serviceProvider.GetRequiredKeyedService("NebulaBusSqlClient"); + _jsonSerializerOptions = nebulaOptions.JsonSerializerOptions; + _nebulaOptions = nebulaOptions; + } + + public void Add(NebulaStoreMessage nebulaStoreMessage) + { + _sqlClient.Insertable(new StoreEntity() + { + Id = nebulaStoreMessage.GetKey(), + Content = JsonSerializer.Serialize(nebulaStoreMessage, _jsonSerializerOptions), + TimeStamp = nebulaStoreMessage.TriggerTime + }).ExecuteCommand(); + } + + public void Delete(NebulaStoreMessage nebulaStoreMessage) + { + _sqlClient.Deleteable().Where(x => x.Id == nebulaStoreMessage.GetKey()).ExecuteCommand(); + } + + public void Dispose() + { + _sqlClient?.Dispose(); + } + + public async Task Get(long beforeTimestamp) + { + var entities = await _sqlClient.Queryable().Where(x => x.TimeStamp <= beforeTimestamp).ToListAsync(); + if (entities == null) return null; + var result = entities.Select(x => JsonSerializer.Deserialize(x.Content, _jsonSerializerOptions)).ToArray(); + return result!; + } + + public bool Lock(string value) + { + try + { + var now = DateTimeOffset.Now.ToUnixTimeSeconds(); + var x = _sqlClient.Storageable(new LockEntity() + { + Id = LockKey, + Value = value, + ExpireTime = now + 3 + }).ToStorage(); + + //不存在插入表示拿到锁 + var result = x.AsInsertable.ExecuteCommand(); + if (result == 1) return true; + + //存在但锁过期,更新锁并拿到锁 + result = x.AsUpdateable.Where(x => x.Id == LockKey && x.ExpireTime < now).ExecuteCommand(); + if (result == 1) return true; + return false; + } + catch + { + return false; + } + } + + public void RefreshLock() + { + var expire = DateTimeOffset.Now.ToUnixTimeSeconds() + 3; + _sqlClient.Updateable().Where(x => x.Id == LockKey).SetColumns(x => new LockEntity() + { + ExpireTime = expire + }).ExecuteCommand(); + } + + public void UnLock(string value) + { + _sqlClient.Deleteable().Where(x => x.Id == LockKey && x.Value == value).ExecuteCommand(); + } + + public void Init() + { + _sqlClient.CodeFirst.InitTables(typeof(LockEntity)); + _sqlClient.CodeFirst.InitTables(typeof(StoreEntity)); + } + } +} diff --git a/src/NebulaBus.Store.Sql/StoreEntity.cs b/src/NebulaBus.Store.Sql/StoreEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..aa986f6031858015ca50067c0a0fc29358fabaee --- /dev/null +++ b/src/NebulaBus.Store.Sql/StoreEntity.cs @@ -0,0 +1,14 @@ +using SqlSugar; + +namespace NebulaBus.Store.Sql +{ + [SugarIndex("index_timestamp", nameof(TimeStamp), OrderByType.Asc)] + internal class StoreEntity + { + [SugarColumn(IsPrimaryKey = true)] + public string Id { get; set; } + [SugarColumn(ColumnDataType = "longtext")] + public string Content { get; set; } + public long TimeStamp { get; set; } + } +} \ No newline at end of file diff --git a/src/NebulaBus.sln b/src/NebulaBus.sln index 036f078d3efdfc1d68593d80a8fb4336d206e4ee..a223c9e95df773cbf7c216a108c2b70745cbf2fe 100644 --- a/src/NebulaBus.sln +++ b/src/NebulaBus.sln @@ -27,6 +27,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogicSamples", "LogicSample EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RabbitmqWithRedisStoreWebApiSample", "RabbitmqWithRedisStoreWebApiSample\RabbitmqWithRedisStoreWebApiSample.csproj", "{821FE282-43EE-480D-B395-547A8813EB25}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NebulaBus.Store.Sql", "NebulaBus.Store.Sql\NebulaBus.Store.Sql.csproj", "{4A4309BF-26C8-4BA6-9ADA-DD84FF8ADD61}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RabbitmqWithSqlStoreWebApiSample", "RabbitmqWithSqlStoreWebApiSample\RabbitmqWithSqlStoreWebApiSample.csproj", "{87A888DB-2E89-4205-B3A3-32F38CE946BF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -77,6 +81,14 @@ Global {821FE282-43EE-480D-B395-547A8813EB25}.Debug|Any CPU.Build.0 = Debug|Any CPU {821FE282-43EE-480D-B395-547A8813EB25}.Release|Any CPU.ActiveCfg = Release|Any CPU {821FE282-43EE-480D-B395-547A8813EB25}.Release|Any CPU.Build.0 = Release|Any CPU + {4A4309BF-26C8-4BA6-9ADA-DD84FF8ADD61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A4309BF-26C8-4BA6-9ADA-DD84FF8ADD61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A4309BF-26C8-4BA6-9ADA-DD84FF8ADD61}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A4309BF-26C8-4BA6-9ADA-DD84FF8ADD61}.Release|Any CPU.Build.0 = Release|Any CPU + {87A888DB-2E89-4205-B3A3-32F38CE946BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87A888DB-2E89-4205-B3A3-32F38CE946BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87A888DB-2E89-4205-B3A3-32F38CE946BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87A888DB-2E89-4205-B3A3-32F38CE946BF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -87,6 +99,7 @@ Global {9CC09AB1-0589-4A44-895F-4F0F7CD17E2E} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {43607D99-9A7F-4A8C-8539-07C1424022C7} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {821FE282-43EE-480D-B395-547A8813EB25} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} + {87A888DB-2E89-4205-B3A3-32F38CE946BF} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {855D751D-7811-4D9B-87C9-F628E17E3A56} diff --git a/src/NebulaBus/Scheduler/DelayMessageScheduler.cs b/src/NebulaBus/Scheduler/DelayMessageScheduler.cs index b86014547eb64d55603639e5f6926b5d6edce0b4..27a06f25e4637f1dbde6024a5fd4fca1fbfbc8a1 100644 --- a/src/NebulaBus/Scheduler/DelayMessageScheduler.cs +++ b/src/NebulaBus/Scheduler/DelayMessageScheduler.cs @@ -48,6 +48,8 @@ namespace NebulaBus.Scheduler timer.Elapsed += Timer_Elapsed; var lockValue = Guid.NewGuid().ToString(); + _store.Init(); + cts.Token.Register(() => { _scheduler.Clear(); diff --git a/src/NebulaBus/Store/IStore.cs b/src/NebulaBus/Store/IStore.cs index 5db8f10c8284808e53537b92101877d3be888e27..fcec4206bfbcd310ce6f8302075ad14237059a86 100644 --- a/src/NebulaBus/Store/IStore.cs +++ b/src/NebulaBus/Store/IStore.cs @@ -11,5 +11,7 @@ namespace NebulaBus.Store void RefreshLock(); bool Lock(string value); void UnLock(string value); + void Init() + { } } } \ No newline at end of file diff --git a/src/NebulaBus/Store/NebulaStoreMessage.cs b/src/NebulaBus/Store/NebulaStoreMessage.cs index ef068bd58912352d490fa2ce3c69422175e4f52d..a6f8017a9e5c35c606e66fb2baa379d91bb61bd2 100644 --- a/src/NebulaBus/Store/NebulaStoreMessage.cs +++ b/src/NebulaBus/Store/NebulaStoreMessage.cs @@ -1,6 +1,4 @@ -using System; - -namespace NebulaBus.Store +namespace NebulaBus.Store { public class NebulaStoreMessage { diff --git a/src/RabbitmqWithRedisStoreWebApiSample/Program.cs b/src/RabbitmqWithRedisStoreWebApiSample/Program.cs index 2734e89f3db77e32492ee6d39a4eb7e6d2c05571..898800b85b6a5e280b4d5743d9cd06884ad002f2 100644 --- a/src/RabbitmqWithRedisStoreWebApiSample/Program.cs +++ b/src/RabbitmqWithRedisStoreWebApiSample/Program.cs @@ -8,7 +8,7 @@ public class Program public static void Main(string[] args) { var builder = Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(args); - builder.WebHost.UseUrls("http://*:55896"); + builder.WebHost.UseUrls("http://*:0"); builder.Logging.AddConsole(); var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); diff --git a/src/RabbitmqWithSqlStoreWebApiSample/Program.cs b/src/RabbitmqWithSqlStoreWebApiSample/Program.cs new file mode 100644 index 0000000000000000000000000000000000000000..a30a85d8172700c9b515e159e6fef431dae0f909 --- /dev/null +++ b/src/RabbitmqWithSqlStoreWebApiSample/Program.cs @@ -0,0 +1,61 @@ +using LogicSamples; +using LogicSamples.Handlers; + +namespace RabbitmqWithRedisStoreWebApiSample; + +public class Program +{ + public static void Main(string[] args) + { + var builder = Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(args); + builder.WebHost.UseUrls("http://*:0"); + builder.Logging.AddConsole(); + var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + + builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", false, reloadOnChange: true) + .AddJsonFile($"appsettings.{environment}.json", true, reloadOnChange: true); + var configuration = builder.Configuration; + + // 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(); + builder.Services.AddNebulaBus(options => + { + options.ClusterName = "TestCluster"; + options.UseSqlStore(new SqlSugar.ConnectionConfig() + { + ConnectionString = configuration!.GetConnectionString("SqlConn"), + }); + options.UseRabbitmqTransport(rabbitmq => + { + rabbitmq.HostName = configuration!.GetValue("RabbitMq:HostName"); + rabbitmq.UserName = configuration!.GetValue("RabbitMq:UserName"); + rabbitmq.Password = configuration!.GetValue("RabbitMq:Password"); + rabbitmq.VirtualHost = configuration!.GetValue("RabbitMq:VirtualHost"); + }); + }); + builder.Services.AddNebulaBusHandler(typeof(TestHandlerV1).Assembly); + //builder.Services.AddNebulaBusHandler(); + //builder.Services.AddNebulaBusHandler(); + //Add Global Handler Filter + builder.Services.AddNebulaBusFilter(); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment() || environment == "Local") + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); + } +} \ No newline at end of file diff --git a/src/RabbitmqWithSqlStoreWebApiSample/Properties/launchSettings.json b/src/RabbitmqWithSqlStoreWebApiSample/Properties/launchSettings.json new file mode 100644 index 0000000000000000000000000000000000000000..b0f187f1e7081482c78152f65bc16a5173a4dc55 --- /dev/null +++ b/src/RabbitmqWithSqlStoreWebApiSample/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5262", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Local" + } + } + } +} diff --git a/src/RabbitmqWithSqlStoreWebApiSample/RabbitmqWithSqlStoreWebApiSample.csproj b/src/RabbitmqWithSqlStoreWebApiSample/RabbitmqWithSqlStoreWebApiSample.csproj new file mode 100644 index 0000000000000000000000000000000000000000..7ca634efb09be321ccd64e0c5bba0b009e9a0fe8 --- /dev/null +++ b/src/RabbitmqWithSqlStoreWebApiSample/RabbitmqWithSqlStoreWebApiSample.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + diff --git a/src/RabbitmqWithSqlStoreWebApiSample/appsettings.Development.json b/src/RabbitmqWithSqlStoreWebApiSample/appsettings.Development.json new file mode 100644 index 0000000000000000000000000000000000000000..0c208ae9181e5e5717e47ec1bd59368aebc6066e --- /dev/null +++ b/src/RabbitmqWithSqlStoreWebApiSample/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/RabbitmqWithSqlStoreWebApiSample/appsettings.json b/src/RabbitmqWithSqlStoreWebApiSample/appsettings.json new file mode 100644 index 0000000000000000000000000000000000000000..10f68b8c8b4f796baf8ddeee7551b6a52b9437cc --- /dev/null +++ b/src/RabbitmqWithSqlStoreWebApiSample/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}