From 0c41eda09d10e70c5b9c3b5781abb61cc5980c73 Mon Sep 17 00:00:00 2001 From: pedro-camargo-MSFT Date: Tue, 26 Jul 2022 13:33:35 -0700 Subject: [PATCH 1/5] Add analyzer to suggest top level route registration --- .../src/Analyzers/DiagnosticDescriptors.cs | 9 + .../WebApplicationBuilderAnalyzer.cs | 26 ++- .../WebApplicationBuilder/WellKnownTypes.cs | 18 +- ...teRegistrationInsteadOfUseEndpointsTest.cs | 174 ++++++++++++++++++ 4 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs index 08f0860ad7be..c00888c3df4f 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs @@ -106,4 +106,13 @@ internal static class DiagnosticDescriptors DiagnosticSeverity.Warning, isEnabledByDefault: true, helpLinkUri: "https://aka.ms/aspnet/analyzers"); + + internal static readonly DiagnosticDescriptor UseTopLevelRouteRegistrationsInsteadOfUseEndpoints = new( + "ASP0014", + "Suggest using app.MapGet over of using app.UseEndpoints", + "Suggest using app.MapGet instead of {0}", + "Usage", + DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://aka.ms/aspnet/analyzers"); } diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs index e920d5841d2c..601a96835b5c 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs @@ -23,7 +23,8 @@ public class WebApplicationBuilderAnalyzer : DiagnosticAnalyzer DiagnosticDescriptors.DoNotUseUseStartupWithConfigureWebHostBuilder, DiagnosticDescriptors.DoNotUseHostConfigureLogging, DiagnosticDescriptors.DoNotUseHostConfigureServices, - DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder + DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, + DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints }); public override void Initialize(AnalysisContext context) @@ -65,6 +66,11 @@ public override void Initialize(AnalysisContext context) wellKnownTypes.HostingHostBuilderExtensions, }; INamedTypeSymbol[] configureHostTypes = { wellKnownTypes.ConfigureHostBuilder }; + INamedTypeSymbol[] useEndpointTypes = + { + wellKnownTypes.EndpointRoutingApplicationBuilderExtensions, + wellKnownTypes.WebApplicationBuilder + }; compilationStartAnalysisContext.RegisterOperationAction(operationAnalysisContext => { @@ -231,6 +237,24 @@ public override void Initialize(AnalysisContext context) invocation)); } + //var builder = WebApplication.CreateBuilder(args); + //var app= builder.Build(); + //app.UseRouting(); + //app.UseEndpoints(x => {}) + if (IsDisallowedMethod( + operationAnalysisContext, + invocation, + targetMethod, + wellKnownTypes.WebApplicationBuilder, + "UseEndpoints", + useEndpointTypes)) + { + operationAnalysisContext.ReportDiagnostic( + CreateDiagnostic( + DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, + invocation)); + } + static Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, IInvocationOperation operation) { // Take the location for the whole invocation operation as a starting point. diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WellKnownTypes.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WellKnownTypes.cs index 0e2f1102d4d1..552122334953 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WellKnownTypes.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WellKnownTypes.cs @@ -48,6 +48,18 @@ public static bool TryCreate(Compilation compilation, [NotNullWhen(true)] out We return false; } + const string EndpointRoutingApplicationBuilderExtensions = "Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions"; + if (compilation.GetTypeByMetadataName(EndpointRoutingApplicationBuilderExtensions) is not { } endpointRoutingApplicationBuilderExtensions) + { + return false; + } + + const string WebApplicationBuilder = "Microsoft.AspNetCore.Builder.WebApplication"; + if (compilation.GetTypeByMetadataName(WebApplicationBuilder) is not { } webApplicationBuilder) + { + return false; + } + wellKnownTypes = new WellKnownTypes { ConfigureHostBuilder = configureHostBuilder, @@ -55,7 +67,9 @@ public static bool TryCreate(Compilation compilation, [NotNullWhen(true)] out We GenericHostWebHostBuilderExtensions = genericHostWebHostBuilderExtensions, HostingAbstractionsWebHostBuilderExtensions = hostingAbstractionsWebHostBuilderExtensions, WebHostBuilderExtensions = webHostBuilderExtensions, - HostingHostBuilderExtensions = hostingHostBuilderExtensions + HostingHostBuilderExtensions = hostingHostBuilderExtensions, + EndpointRoutingApplicationBuilderExtensions = endpointRoutingApplicationBuilderExtensions, + WebApplicationBuilder = webApplicationBuilder }; return true; @@ -67,4 +81,6 @@ public static bool TryCreate(Compilation compilation, [NotNullWhen(true)] out We public INamedTypeSymbol HostingAbstractionsWebHostBuilderExtensions { get; private init; } public INamedTypeSymbol WebHostBuilderExtensions { get; private init; } public INamedTypeSymbol HostingHostBuilderExtensions { get; private init; } + public INamedTypeSymbol EndpointRoutingApplicationBuilderExtensions { get; private init; } + public INamedTypeSymbol WebApplicationBuilder { get; private init; } } diff --git a/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs b/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs new file mode 100644 index 000000000000..c9e2e38ab302 --- /dev/null +++ b/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Analyzer.Testing; +using Microsoft.CodeAnalysis; + +namespace Microsoft.AspNetCore.Analyzers.WebApplicationBuilder; +public partial class UseTopLevelRouteRegistrationsInsteadOfUseEndpointsTest +{ + private TestDiagnosticAnalyzerRunner Runner { get; } = new(new WebApplicationBuilderAnalyzer()); + + [Fact] + public async Task DoesNotWarnWhenEndpointRegistrationIsTopLevel() + { + //arrange + var source = @" +using Microsoft.AspNetCore.Builder; +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +app.UseRouting(); +app.MapGet(""/"", () => ""Hello World!""); +"; + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source); + + //assert + Assert.Empty(diagnostics); + } + + [Fact] + public async Task DoesNotWarnWhenEnpointRegistrationIsTopLevel_InMain() + { + //arrange + var source = @" +using Microsoft.AspNetCore.Builder; +public static class Program +{ + public static void Main (string[] args) + { + var builder = WebApplication.CreateBuilder(args); + var app = builder.Build(); + app.UseRouting(); + app.MapGet(""/"", () => ""Hello World!""); + } +} +"; + + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source); + + //assert + Assert.Empty(diagnostics); + } + + [Fact] + public async Task WarnsWhenEndpointRegistrationIsNotTopLevel() + { + //arrange + var source = TestSource.Read(@" +using Microsoft.AspNetCore.Builder; +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +app.UseRouting(); +app./*MM*/UseEndpoints(endpoints => +{ + endpoints.MapGet(""/"", () => ""Hello World!""); +}); +"); + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + + //assert + var diagnostic = Assert.Single(diagnostics); + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); + Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + } + + [Fact] + public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_InMain() + { + //arrange + var source = TestSource.Read(@" +using Microsoft.AspNetCore.Builder; +public static class Program +{ + public static void Main (string[] args) + { + var builder = WebApplication.CreateBuilder(args); + var app = builder.Build(); + app.UseRouting(); + app./*MM*/UseEndpoints(endpoints => + { + endpoints.MapGet(""/"", () => ""Hello World!""); + }); + } +} +"); + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + + //assert + var diagnostic = Assert.Single(diagnostics); + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); + Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + } + + [Fact] + public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OnDifferentLine() + { + //arrange + var source = TestSource.Read(@" +using Microsoft.AspNetCore.Builder; +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +app.UseRouting(); +app. + /*MM*/UseEndpoints(endpoints => +{ + endpoints.MapGet(""/"", () => ""Hello World!""); +}); +"); + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + + //assert + var diagnostic = Assert.Single(diagnostics); + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); + Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + } + + [Fact] + public async Task WarnsTwiceWhenEndpointRegistrationIsNotTopLevel_OnDifferentLine() + { + //arrange + var source = TestSource.Read(@" +using Microsoft.AspNetCore.Builder; +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +app.UseRouting(); +app./*MM1*/UseEndpoints(endpoints => +{ + endpoints.MapGet(""/"", () => ""Hello World!""); +}); +app./*MM2*/UseEndpoints(endpoints => +{ + endpoints.MapGet(""/"", () => ""Hello World!""); +}); +"); + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + //assert + Assert.Equal(2, diagnostics.Length); + var diagnostic1 = diagnostics[0]; + var diagnostic2 = diagnostics[1]; + + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic1.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic1.Location); + Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic1.GetMessage(CultureInfo.InvariantCulture)); + + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic2.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM2"], diagnostic2.Location); + Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic2.GetMessage(CultureInfo.InvariantCulture)); + + } +} From 701a99e3bd67d7ec39a440633cdc2f8d013c8d48 Mon Sep 17 00:00:00 2001 From: pedro-camargo-MSFT Date: Wed, 27 Jul 2022 11:44:00 -0700 Subject: [PATCH 2/5] Add tests for other map methods and make the diagnostic descriptor more general --- .../src/Analyzers/DiagnosticDescriptors.cs | 4 +- ...teRegistrationInsteadOfUseEndpointsTest.cs | 66 +++++++++++++++++-- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs index c00888c3df4f..f36338eaf879 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs @@ -109,8 +109,8 @@ internal static class DiagnosticDescriptors internal static readonly DiagnosticDescriptor UseTopLevelRouteRegistrationsInsteadOfUseEndpoints = new( "ASP0014", - "Suggest using app.MapGet over of using app.UseEndpoints", - "Suggest using app.MapGet instead of {0}", + "Suggest using top level route registrations", + "Suggest using top level route registrations instead of {0}", "Usage", DiagnosticSeverity.Warning, isEnabledByDefault: true, diff --git a/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs b/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs index c9e2e38ab302..1aefd52fe1c8 100644 --- a/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs +++ b/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Analyzer.Testing; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.AspNetCore.Analyzers.WebApplicationBuilder; public partial class UseTopLevelRouteRegistrationsInsteadOfUseEndpointsTest @@ -50,7 +51,6 @@ public static void Main (string[] args) } } "; - //act var diagnostics = await Runner.GetDiagnosticsAsync(source); @@ -79,7 +79,60 @@ public async Task WarnsWhenEndpointRegistrationIsNotTopLevel() var diagnostic = Assert.Single(diagnostics); Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic.Descriptor); AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); - Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + } + + [Fact] + public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OtherMapMethods() + { + //arrange + var source = TestSource.Read(@" +using Microsoft.AspNetCore.Builder; +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +app.UseRouting(); +app./*MM1*/UseEndpoints(endpoints => +{ + endpoints.MapGet(""/"", () => ""This is a GET""); +}); +app./*MM2*/UseEndpoints(endpoints => +{ + endpoints.MapPost(""/"", () => ""This is a POST""); +}); +app./*MM3*/UseEndpoints(endpoints => +{ + endpoints.MapPut(""/"", () => ""This is a PUT""); +}); +app./*MM4*/UseEndpoints(endpoints => +{ + endpoints.MapDelete(""/"", () => ""This is a DELETE""); +}); +"); + //act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + + //assert + Assert.Equal(4, diagnostics.Length); + var diagnostic1 = diagnostics[0]; + var diagnostic2 = diagnostics[1]; + var diagnostic3 = diagnostics[2]; + var diagnostic4 = diagnostics[3]; + + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic1.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic1.Location); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic1.GetMessage(CultureInfo.InvariantCulture)); + + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic2.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM2"], diagnostic2.Location); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic2.GetMessage(CultureInfo.InvariantCulture)); + + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic3.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM3"], diagnostic3.Location); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic3.GetMessage(CultureInfo.InvariantCulture)); + + Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic2.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM4"], diagnostic4.Location); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic2.GetMessage(CultureInfo.InvariantCulture)); } [Fact] @@ -109,7 +162,7 @@ public static void Main (string[] args) var diagnostic = Assert.Single(diagnostics); Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic.Descriptor); AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); - Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); } [Fact] @@ -134,7 +187,7 @@ public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OnDifferentLine() var diagnostic = Assert.Single(diagnostics); Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic.Descriptor); AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); - Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic.GetMessage(CultureInfo.InvariantCulture)); } [Fact] @@ -164,11 +217,10 @@ public async Task WarnsTwiceWhenEndpointRegistrationIsNotTopLevel_OnDifferentLin Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic1.Descriptor); AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic1.Location); - Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic1.GetMessage(CultureInfo.InvariantCulture)); + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic1.GetMessage(CultureInfo.InvariantCulture)); Assert.Same(DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, diagnostic2.Descriptor); AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM2"], diagnostic2.Location); - Assert.Equal("Suggest using app.MapGet instead of UseEndpoints", diagnostic2.GetMessage(CultureInfo.InvariantCulture)); - + Assert.Equal("Suggest using top level route registrations instead of UseEndpoints", diagnostic2.GetMessage(CultureInfo.InvariantCulture)); } } From 5b00a0d93c970be8dd7f93b1b691c7dff072214c Mon Sep 17 00:00:00 2001 From: pedro-camargo-MSFT Date: Thu, 28 Jul 2022 11:30:23 -0700 Subject: [PATCH 3/5] Minor changes to the tests --- ...LevelRouteRegistrationInsteadOfUseEndpointsTest.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs b/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs index 1aefd52fe1c8..791cfc9b37c0 100644 --- a/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs +++ b/src/Framework/AspNetCoreAnalyzers/test/WebApplicationBuilder/UseTopLevelRouteRegistrationInsteadOfUseEndpointsTest.cs @@ -136,21 +136,23 @@ public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OtherMapMethods() } [Fact] - public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_InMain() + public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_InMain_MapControllers() { //arrange var source = TestSource.Read(@" using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; public static class Program { public static void Main (string[] args) { var builder = WebApplication.CreateBuilder(args); + builder.Services.AddControllers(); var app = builder.Build(); app.UseRouting(); app./*MM*/UseEndpoints(endpoints => { - endpoints.MapGet(""/"", () => ""Hello World!""); + endpoints.MapControllers(); }); } } @@ -166,7 +168,7 @@ public static void Main (string[] args) } [Fact] - public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OnDifferentLine() + public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OnDifferentLine_WithRouteParameters() { //arrange var source = TestSource.Read(@" @@ -177,7 +179,8 @@ public async Task WarnsWhenEndpointRegistrationIsNotTopLevel_OnDifferentLine() app. /*MM*/UseEndpoints(endpoints => { - endpoints.MapGet(""/"", () => ""Hello World!""); + endpoints.MapGet(""/users/{userId}/books/{bookId}"", + (int userId, int bookId) => $""The user id is {userId} and book id is {bookId}""); }); "); //act From 4aea6d6658704f692c4f5641eb0459ee83edd3d9 Mon Sep 17 00:00:00 2001 From: pedro-camargo-MSFT <106186580+pedro-camargo-MSFT@users.noreply.github.com> Date: Mon, 8 Aug 2022 10:26:27 -0700 Subject: [PATCH 4/5] Update WebApplicationBuilderAnalyzer.cs --- .../WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs index 2d00da53daca..5b22db488ce3 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs @@ -24,7 +24,7 @@ public class WebApplicationBuilderAnalyzer : DiagnosticAnalyzer DiagnosticDescriptors.DoNotUseHostConfigureServices, DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints - }); + ); public override void Initialize(AnalysisContext context) { From 90e87a39c7961104a3aab6eed71ecb51e6441543 Mon Sep 17 00:00:00 2001 From: pedro-camargo-MSFT <106186580+pedro-camargo-MSFT@users.noreply.github.com> Date: Mon, 8 Aug 2022 10:43:43 -0700 Subject: [PATCH 5/5] Change operationAnalysisContext to context to match the other updated Analyzers. --- .../WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs index 5b22db488ce3..df599d22c6b7 100644 --- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs +++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/WebApplicationBuilder/WebApplicationBuilderAnalyzer.cs @@ -241,14 +241,14 @@ public override void Initialize(AnalysisContext context) //app.UseRouting(); //app.UseEndpoints(x => {}) if (IsDisallowedMethod( - operationAnalysisContext, + context, invocation, targetMethod, wellKnownTypes.WebApplicationBuilder, "UseEndpoints", useEndpointTypes)) { - operationAnalysisContext.ReportDiagnostic( + context.ReportDiagnostic( CreateDiagnostic( DiagnosticDescriptors.UseTopLevelRouteRegistrationsInsteadOfUseEndpoints, invocation));