diff --git a/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/Diagnostics.cs b/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/Diagnostics.cs index e762f20..739fd5d 100644 --- a/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/Diagnostics.cs +++ b/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/Diagnostics.cs @@ -27,7 +27,7 @@ public IActionResult Get() } } }"; - var message = "The route template has parameter id that does not have a corresponding method parameter."; + var message = "The route template has parameter 'id' that does not have a corresponding method parameter."; AnalyzerAssert.Diagnostics(Analyzer, ExpectedDiagnostic.WithMessage(message), code); } @@ -83,7 +83,7 @@ public IActionResult Get(int orderId) } } }"; - var message = "The route template has parameter itemId that does not have a corresponding method parameter."; + var message = "The route template has parameter 'itemId' that does not have a corresponding method parameter."; AnalyzerAssert.Diagnostics(Analyzer, ExpectedDiagnostic.WithMessage(message), order, db, code); } @@ -195,8 +195,8 @@ namespace AspBox { using Microsoft.AspNetCore.Mvc; - [Route(""api/values/{↓valueId}/items"")] - [Route(""api/values/{↓valueId}/items/{itemId}"")] + [Route(""api/values"")] + [Route(""api/values/{↓id}"")] [ApiController] public class OrdersController : Controller { @@ -207,6 +207,30 @@ public IActionResult Get() } } }"; + var message = "The route template has parameter 'id' that does not have a corresponding method parameter."; + AnalyzerAssert.Diagnostics(Analyzer, ExpectedDiagnostic.WithMessage(message), code); + } + + [Test] + public void WhenMultipleRouteAttributesMissingActionWithParameter() + { + var code = @" +namespace AspBox +{ + using Microsoft.AspNetCore.Mvc; + + [Route(""api/values"")] + [Route(""api/values/{↓id}"")] + [ApiController] + public class ValuesController : Controller + { + [HttpGet] + public IActionResult Get() + { + return this.Ok(); + } + } +}"; AnalyzerAssert.Diagnostics(Analyzer, ExpectedDiagnostic, code); } diff --git a/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/ValidCode.cs b/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/ValidCode.cs index 6fbb01b..4e8bcce 100644 --- a/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/ValidCode.cs +++ b/AspNetCoreAnalyzers.Tests/ASP007MissingParameterTests/ValidCode.cs @@ -50,10 +50,16 @@ namespace AspBox public class OrdersController : Controller { [HttpGet] - public IActionResult GetValue() + public IActionResult Get() { return this.Ok(); } + + [HttpGet] + public IActionResult Get(int id) + { + return this.Ok(id); + } } }"; diff --git a/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/Diagnostics.cs b/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/Diagnostics.cs index 7ba93d5..a58c0bb 100644 --- a/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/Diagnostics.cs +++ b/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/Diagnostics.cs @@ -1,4 +1,4 @@ -namespace AspNetCoreAnalyzers.Tests.ASP011RouteParameterNotUniqueTests +namespace AspNetCoreAnalyzers.Tests.ASP011RouteParameterNameMustBeUniqueTests { using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/ValidCode.cs b/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/ValidCode.cs index 9585de2..640a7c3 100644 --- a/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/ValidCode.cs +++ b/AspNetCoreAnalyzers.Tests/ASP011RouteParameterNameMustBeUniqueTests/ValidCode.cs @@ -1,4 +1,4 @@ -namespace AspNetCoreAnalyzers.Tests.ASP011RouteParameterNotUniqueTests +namespace AspNetCoreAnalyzers.Tests.ASP011RouteParameterNameMustBeUniqueTests { using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/AspNetCoreAnalyzers/ASP007MissingParameter.cs b/AspNetCoreAnalyzers/ASP007MissingParameter.cs index 0df781e..2e646db 100644 --- a/AspNetCoreAnalyzers/ASP007MissingParameter.cs +++ b/AspNetCoreAnalyzers/ASP007MissingParameter.cs @@ -9,7 +9,7 @@ internal static class ASP007MissingParameter internal static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor( id: DiagnosticId, title: "The method has no corresponding parameter.", - messageFormat: "The route template has parameter {0} that does not have a corresponding method parameter.", + messageFormat: "The route template has parameter '{0}' that does not have a corresponding method parameter.", category: AnalyzerCategory.Routing, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, diff --git a/AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs b/AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs index d40bc9f..1bbf466 100644 --- a/AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs +++ b/AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs @@ -3,7 +3,6 @@ namespace AspNetCoreAnalyzers using System; using System.Collections.Generic; using System.Collections.Immutable; - using System.Linq; using Gu.Roslyn.AnalyzerExtensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -583,41 +582,21 @@ private static bool HasMissingMethodParameter(PathSegment segment, SyntaxNodeAna context.Node.TryFirstAncestor(out ClassDeclarationSyntax classDeclaration) && !classDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword)) { - foreach (var attributeList in classDeclaration.AttributeLists) - { - foreach (var attribute in attributeList.Attributes) - { - if (UrlAttribute.TryCreate(attribute, context, out var urlAttribute)) - { - if (urlAttribute.UrlTemplate == null) - { - location = null; - name = null; - return false; - } - - if (urlAttribute.UrlTemplate is UrlTemplate template && - !template.Path.Any(x => x.Parameter?.Name.TextEquals(templateParameter.Name) == true)) - { - location = null; - name = null; - return false; - } - } - } - } - foreach (var member in classDeclaration.Members) { if (member is MethodDeclarationSyntax candidate && HasHttpVerbAttribute(candidate, context) && - !TryFindParameter(templateParameter, candidate, out _)) + TryFindParameter(templateParameter, candidate, out _)) { - location = templateParameter.Name.GetLocation(); - name = templateParameter.Name.ToString(); - return true; + location = null; + name = null; + return false; } } + + location = templateParameter.Name.GetLocation(); + name = templateParameter.Name.ToString(); + return true; } } @@ -885,13 +864,13 @@ StringBuilderPool.PooledStringBuilder ClassName() return builder.Append("Controller"); } - bool Equals(StringBuilderPool.PooledStringBuilder builder, string text) + bool Equals(StringBuilderPool.PooledStringBuilder x, string y) { - if (builder.Length == containingType.Name.Length) + if (x.Length == y.Length) { - for (var i = 0; i < builder.Length; i++) + for (var i = 0; i < x.Length; i++) { - if (builder[i] != containingType.Name[i]) + if (x[i] != y[i]) { return false; }