diff --git a/.github/workflows/build-arm64.yml b/.github/workflows/build-arm64.yml index d0940add9..e79cf0217 100644 --- a/.github/workflows/build-arm64.yml +++ b/.github/workflows/build-arm64.yml @@ -25,7 +25,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Build Reason env: diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f21407f00..dd2cd039a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -38,7 +38,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Version @@ -62,7 +62,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Start Services diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index f1161cee5..f5a2e1df2 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -25,7 +25,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Start Services diff --git a/.github/workflows/elasticsearch-docker-7.yml b/.github/workflows/elasticsearch-docker-7.yml index 642b645f8..964cba1de 100644 --- a/.github/workflows/elasticsearch-docker-7.yml +++ b/.github/workflows/elasticsearch-docker-7.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Build Reason env: diff --git a/.github/workflows/elasticsearch-docker-8.yml b/.github/workflows/elasticsearch-docker-8.yml index af64a4217..43f0f1dbf 100644 --- a/.github/workflows/elasticsearch-docker-8.yml +++ b/.github/workflows/elasticsearch-docker-8.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.* + dotnet-version: 10.0.* dotnet-quality: ga - name: Build Reason env: diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c30d935b2..a8d2e79ec 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,11 +4,12 @@ "streetsidesoftware.code-spell-checker", "tintoy.msbuild-project-tools", "humao.rest-client", - "ms-kubernetes-tools.vscode-kubernetes-tools", "svelte.svelte-vscode", "bradlc.vscode-tailwindcss", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", + "microsoft-aspire.aspire-vscode", + "ms-kubernetes-tools.vscode-kubernetes-tools", "ms-playwright.playwright", "selemondev.vscode-shadcn-svelte", "vitest.explorer" diff --git a/.vscode/launch.json b/.vscode/launch.json index dd21f3400..90a926b9f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,120 +1,109 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Aspire", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.AppHost/bin/Debug/net9.0/Exceptionless.AppHost.dll", - "args": [], - "cwd": "${workspaceFolder}/src/Exceptionless.AppHost", - "stopAtEntry": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "AppMode": "Development" - } - }, - { - "name": "Web", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.Web/bin/Debug/net9.0/Exceptionless.Web.dll", - "args": [], - "cwd": "${workspaceFolder}/src/Exceptionless.Web", - "stopAtEntry": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "AppMode": "Development" - } - }, - { - "name": "Job", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/src/Exceptionless.Job/bin/Debug/net9.0/Exceptionless.Job.dll", - "args": [], - "cwd": "${workspaceFolder}", - "stopAtEntry": false, - "console": "internalConsole", - "env": { - "AppMode": "Development" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - }, - { - "name": "frontend: Attach to Chrome", - "port": 9222, - "request": "attach", - "type": "chrome", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" - }, - { - "name": "frontend: Attach to Edge", - "port": 9222, - "request": "attach", - "type": "msedge", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" - }, - { - "type": "msedge", - "request": "launch", - "name": "frontend: Web (Edge)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev" - }, - { - "type": "msedge", - "request": "launch", - "name": "frontend: Web Dev Api (Edge)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev:api" - }, - { - "type": "msedge", - "request": "launch", - "name": "frontend: Storybook (Edge)", - "url": "http://localhost:6006", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run storybook" - }, - { - "type": "chrome", - "request": "launch", - "name": "frontend: Web (Chrome)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev" - }, - { - "type": "chrome", - "request": "launch", - "name": "frontend: Web Dev Api (Chrome)", - "url": "http://localhost:5173/next", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run dev:api" - }, - { - "type": "chrome", - "request": "launch", - "name": "frontend: Storybook (Chrome)", - "url": "http://localhost:6006", - "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", - "preLaunchTask": "npm run storybook" - } - ] + "version": "0.2.0", + "configurations": [ + { + "type": "aspire", + "request": "launch", + "name": "Aspire", + "program": "${workspaceFolder}/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj" + }, + { + "name": "Web", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/src/Exceptionless.Web/bin/Debug/net10.0/Exceptionless.Web.dll", + "args": [], + "cwd": "${workspaceFolder}/src/Exceptionless.Web", + "stopAtEntry": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "AppMode": "Development" + } + }, + { + "name": "Job", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/src/Exceptionless.Job/bin/Debug/net10.0/Exceptionless.Job.dll", + "args": [], + "cwd": "${workspaceFolder}", + "stopAtEntry": false, + "console": "internalConsole", + "env": { + "AppMode": "Development" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + }, + { + "name": "frontend: Attach to Chrome", + "port": 9222, + "request": "attach", + "type": "chrome", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" + }, + { + "name": "frontend: Attach to Edge", + "port": 9222, + "request": "attach", + "type": "msedge", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp" + }, + { + "type": "msedge", + "request": "launch", + "name": "frontend: Web (Edge)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev" + }, + { + "type": "msedge", + "request": "launch", + "name": "frontend: Web Dev Api (Edge)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev:api" + }, + { + "type": "msedge", + "request": "launch", + "name": "frontend: Storybook (Edge)", + "url": "http://localhost:6006", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run storybook" + }, + { + "type": "chrome", + "request": "launch", + "name": "frontend: Web (Chrome)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev" + }, + { + "type": "chrome", + "request": "launch", + "name": "frontend: Web Dev Api (Chrome)", + "url": "http://localhost:5173/next", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run dev:api" + }, + { + "type": "chrome", + "request": "launch", + "name": "frontend: Storybook (Chrome)", + "url": "http://localhost:6006", + "webRoot": "${workspaceFolder}/src/Exceptionless.Web/ClientApp", + "preLaunchTask": "npm run storybook" + } + ] } diff --git a/Dockerfile b/Dockerfile index cef8c1ef3..5b174756d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /app COPY ./*.slnx ./NuGet.Config ./ @@ -35,7 +35,7 @@ RUN dotnet publish -c Release -o out # job -FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS job +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS job WORKDIR /app COPY --from=job-publish /app/src/Exceptionless.Job/out ./ @@ -52,7 +52,7 @@ RUN dotnet publish -c Release -o out /p:SkipSpaPublish=true # api -FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS api +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS api WORKDIR /app COPY --from=api-publish /app/src/Exceptionless.Web/out ./ @@ -72,7 +72,7 @@ RUN dotnet publish -c Release -o out # app -FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS app +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS app WORKDIR /app COPY --from=app-publish /app/src/Exceptionless.Web/out ./ @@ -146,7 +146,7 @@ USER elasticsearch RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \ chmod +x dotnet-install.sh && \ - ./dotnet-install.sh --channel 9.0 --runtime aspnetcore && \ + ./dotnet-install.sh --channel 10.0 --runtime aspnetcore && \ rm dotnet-install.sh EXPOSE 8080 9200 @@ -206,7 +206,7 @@ USER elasticsearch RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \ chmod +x dotnet-install.sh && \ - ./dotnet-install.sh --channel 9.0 --runtime aspnetcore && \ + ./dotnet-install.sh --channel 10.0 --runtime aspnetcore && \ rm dotnet-install.sh EXPOSE 8080 9200 diff --git a/global.json b/global.json index 7f873f4e9..1e7fdfa95 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.100-rc*", + "version": "10.0.100", "rollForward": "latestMinor" } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 8e86c5e5b..0ee873a67 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,6 +1,6 @@ - net9.0 + net10.0 enable Exceptionless true diff --git a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj index 8313740fc..e3f7cfe7e 100644 --- a/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj +++ b/src/Exceptionless.AppHost/Exceptionless.AppHost.csproj @@ -1,16 +1,14 @@ - - + Exe - net9.0 + net10.0 enable enable a9c2ddcc-e51d-4cd1-9782-96e1d74eec87 - - - + + @@ -20,4 +18,4 @@ - \ No newline at end of file + diff --git a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs index a8d8c87e7..59aa12a2a 100644 --- a/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs +++ b/src/Exceptionless.AppHost/Extensions/ElasticsearchExtensions.cs @@ -80,7 +80,7 @@ public static IResourceBuilder WithKibana(this IResourceB { containerName ??= $"{builder.Resource.Name}-kibana"; - builder.ApplicationBuilder.Services.TryAddLifecycleHook(); + builder.ApplicationBuilder.Services.TryAddEventingSubscriber(); var resource = new KibanaResource(containerName); var resourceBuilder = builder.ApplicationBuilder.AddResource(resource) diff --git a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs index f5a338048..005504ad7 100644 --- a/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs +++ b/src/Exceptionless.AppHost/Extensions/KibanaConfigWriterHook.cs @@ -1,36 +1,52 @@ using System.Text; +using Aspire.Hosting.Eventing; using Aspire.Hosting.Lifecycle; namespace Aspire.Hosting; -internal class KibanaConfigWriterHook : IDistributedApplicationLifecycleHook +internal class KibanaConfigWriterHook : IDistributedApplicationEventingSubscriber { - public async Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken) + public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken) { - if (appModel.Resources.OfType().SingleOrDefault() is not { } kibanaResource) - return; + var elasticsearchResources = new List(); - var elasticsearchInstances = appModel.Resources.OfType(); - - if (!elasticsearchInstances.Any()) - return; + eventing.Subscribe((evt, _) => + { + switch (evt.Resource) + { + case ElasticsearchResource elastic: + elasticsearchResources.Add(elastic); + break; + } - var hostsVariableBuilder = new StringBuilder(); + return Task.CompletedTask; + }); - foreach (var elasticsearchInstance in elasticsearchInstances) + eventing.Subscribe((evt, _) => { - if (elasticsearchInstance.PrimaryEndpoint.IsAllocated) + if (evt.Resource is not KibanaResource kibanaResource) + return Task.CompletedTask; + + if (elasticsearchResources.Count is 0) + return Task.CompletedTask; + + var sb = new StringBuilder(); + foreach (var resource in elasticsearchResources.Where(elasticsearchInstance => elasticsearchInstance.PrimaryEndpoint.IsAllocated)) { - var connectionString = await elasticsearchInstance.GetConnectionStringAsync(); - if (hostsVariableBuilder.Length > 0) - hostsVariableBuilder.Append(","); - hostsVariableBuilder.Append(elasticsearchInstance.PrimaryEndpoint.Scheme).Append("://").Append(elasticsearchInstance.PrimaryEndpoint.ContainerHost).Append(":").Append(elasticsearchInstance.PrimaryEndpoint.Port); + if (sb.Length > 0) + sb.Append(','); + + sb.Append($"{resource.PrimaryEndpoint.Scheme}://{resource.PrimaryEndpoint.Host}:{resource.PrimaryEndpoint.Port}"); } - } - kibanaResource.Annotations.Add(new EnvironmentCallbackAnnotation(context => - { - context.EnvironmentVariables.Add("ELASTICSEARCH_HOSTS", hostsVariableBuilder.ToString()); - })); + kibanaResource.Annotations.Add(new EnvironmentCallbackAnnotation(context => + { + context.EnvironmentVariables.Add("ELASTICSEARCH_HOSTS", sb.ToString()); + })); + + return Task.CompletedTask; + }); + + return Task.CompletedTask; } } diff --git a/src/Exceptionless.AppHost/Program.cs b/src/Exceptionless.AppHost/Program.cs index 561ae1856..e12fed404 100644 --- a/src/Exceptionless.AppHost/Program.cs +++ b/src/Exceptionless.AppHost/Program.cs @@ -21,7 +21,7 @@ .WithImageTag("v1.27.10") .WithLifetime(ContainerLifetime.Persistent) .WithContainerName("Exceptionless-Mail") - .WithEndpoint(8025, 8025, "http") + .WithHttpEndpoint(8025, 8025, "http") .WithUrlForEndpoint("http", u => u.DisplayText = "Mail") .WithEndpoint(1025, 1025); @@ -48,16 +48,16 @@ .WithUrlForEndpoint("http", u => u.DisplayText = "Api") .WithHttpHealthCheck("/health"); -builder.AddNpmApp("Web", "../../src/Exceptionless.Web/ClientApp", "dev") +builder.AddViteApp("Web", "../../src/Exceptionless.Web/ClientApp") .WithReference(api) .WithEnvironment("ASPNETCORE_URLS", "http://localhost:5200") - .WithUrlForEndpoint("http", u => u.DisplayText = "Web") - .WithEndpoint(port: 5173, targetPort: 5173, scheme: "http", env: "PORT", isProxied: false); + .WithUrlForEndpoint("Web", u => u.DisplayText = "Web") + .WithHttpEndpoint(port: 5173, targetPort: 5173, name: "Web", env: "PORT", isProxied: false); -builder.AddNpmApp("AngularWeb", "../../src/Exceptionless.Web/ClientApp.angular", "serve") +builder.AddJavaScriptApp("AngularWeb", "../../src/Exceptionless.Web/ClientApp.angular", "serve") .WithReference(api) .WithEnvironment("ASPNETCORE_URLS", "http://localhost:5200") - .WithUrlForEndpoint("http", u => u.DisplayText = "Angular Web") - .WithEndpoint(port: 5100, targetPort: 5100, scheme: "http", env: "PORT", isProxied: false); + .WithUrlForEndpoint("AngularWeb", u => u.DisplayText = "Angular Web") + .WithHttpEndpoint(port: 5100, targetPort: 5100, name: "AngularWeb", env: "PORT", isProxied: false); builder.Build().Run(); diff --git a/src/Exceptionless.Core/Exceptionless.Core.csproj b/src/Exceptionless.Core/Exceptionless.Core.csproj index c2328fe95..e42893e95 100644 --- a/src/Exceptionless.Core/Exceptionless.Core.csproj +++ b/src/Exceptionless.Core/Exceptionless.Core.csproj @@ -22,18 +22,18 @@ - + - - - + + + - + diff --git a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj index c690f0385..9ee1cf456 100644 --- a/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj +++ b/src/Exceptionless.Insulation/Exceptionless.Insulation.csproj @@ -8,17 +8,17 @@ - - - - - - + + + + + + - + diff --git a/src/Exceptionless.Job/Exceptionless.Job.csproj b/src/Exceptionless.Job/Exceptionless.Job.csproj index 0434e1892..244ad5839 100644 --- a/src/Exceptionless.Job/Exceptionless.Job.csproj +++ b/src/Exceptionless.Job/Exceptionless.Job.csproj @@ -5,28 +5,23 @@ - - - - - - - + + + + + + - - - - diff --git a/src/Exceptionless.Web/Exceptionless.Web.csproj b/src/Exceptionless.Web/Exceptionless.Web.csproj index 6bce409dd..af79fd146 100644 --- a/src/Exceptionless.Web/Exceptionless.Web.csproj +++ b/src/Exceptionless.Web/Exceptionless.Web.csproj @@ -15,32 +15,28 @@ - - + - + - - - - - - + + + + + + - + - - - diff --git a/src/Exceptionless.Web/Startup.cs b/src/Exceptionless.Web/Startup.cs index c20655cd0..41885463e 100644 --- a/src/Exceptionless.Web/Startup.cs +++ b/src/Exceptionless.Web/Startup.cs @@ -22,7 +22,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.NewtonsoftJson; using Microsoft.Net.Http.Headers; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Newtonsoft.Json; using Serilog; using Serilog.Events; @@ -53,7 +53,7 @@ public void ConfigureServices(IServiceCollection services) { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.RequireHeaderSymmetry = false; - options.KnownNetworks.Clear(); + options.KnownIPNetworks.Clear(); options.KnownProxies.Clear(); }); @@ -135,26 +135,12 @@ public void ConfigureServices(IServiceCollection services) Type = SecuritySchemeType.ApiKey }); - c.AddSecurityRequirement(new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Basic" } - }, - Array.Empty() - }, - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } - }, - Array.Empty() - }, - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Token" } - }, - Array.Empty() - } - }); + c.AddSecurityRequirement(document => new OpenApiSecurityRequirement + { + { new OpenApiSecuritySchemeReference("Basic", document), [] }, + { new OpenApiSecuritySchemeReference("Bearer", document), [] }, + { new OpenApiSecuritySchemeReference("Token", document), [] } + }); string xmlDocPath = Path.Combine(AppContext.BaseDirectory, "Exceptionless.Web.xml"); if (File.Exists(xmlDocPath)) @@ -236,7 +222,7 @@ ApplicationException applicationException when applicationException.Message.Cont Predicate = hcr => hcr.Tags.Contains("Critical") || (options.RunJobsInProcess && hcr.Tags.Contains("AllJobs")) }); - var readyTags = new List { "Critical" }; + List readyTags = ["Critical"]; if (!options.EventSubmissionDisabled) readyTags.Add("Storage"); app.UseReadyHealthChecks(readyTags.ToArray()); diff --git a/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs b/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs index 1c73e36bb..329848062 100644 --- a/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs +++ b/src/Exceptionless.Web/Utility/RequestBodyOperationFilter.cs @@ -1,9 +1,11 @@ +using System.Text.Json.Nodes; using Microsoft.AspNetCore.Mvc; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; -public class RequestBodyContentAttribute : Attribute { } +public class RequestBodyContentAttribute : Attribute +{ +} public class RequestBodyOperationFilter : IOperationFilter { @@ -17,12 +19,17 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) if (consumesAttribute is null) return; - operation.RequestBody = new OpenApiRequestBody { Required = true }; + operation.RequestBody = new OpenApiRequestBody + { + Required = true, + Content = new Dictionary() + }; + foreach (string contentType in consumesAttribute.ContentTypes) { - operation.RequestBody.Content.Add(contentType, new OpenApiMediaType + operation.RequestBody.Content!.Add(contentType, new OpenApiMediaType { - Schema = new OpenApiSchema { Type = "string", Example = new OpenApiString(String.Empty) } + Schema = new OpenApiSchema { Type = JsonSchemaType.String, Example = JsonValue.Create(String.Empty) } }); } } diff --git a/tests/Exceptionless.Tests/AppWebHostFactory.cs b/tests/Exceptionless.Tests/AppWebHostFactory.cs index 1c19b8382..dda75b7c8 100644 --- a/tests/Exceptionless.Tests/AppWebHostFactory.cs +++ b/tests/Exceptionless.Tests/AppWebHostFactory.cs @@ -43,7 +43,7 @@ protected override IHostBuilder CreateHostBuilder() .AddYamlFile("appsettings.yml", optional: false, reloadOnChange: false) .Build(); - return Program.CreateHostBuilder(config, Environments.Development); + return Web.Program.CreateHostBuilder(config, Environments.Development); } async Task IAsyncLifetime.DisposeAsync() diff --git a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj index aff7daf6b..0305fe17d 100644 --- a/tests/Exceptionless.Tests/Exceptionless.Tests.csproj +++ b/tests/Exceptionless.Tests/Exceptionless.Tests.csproj @@ -7,12 +7,12 @@ - + - - - - + + + +