diff --git a/src/Microsoft.AspNetCore.Mvc.Analyzers/AttributesShouldNotBeAppliedToPageModelAnalyzer.cs b/src/Microsoft.AspNetCore.Mvc.Analyzers/AttributesShouldNotBeAppliedToPageModelAnalyzer.cs new file mode 100644 index 0000000000..95f5bcccc2 --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Analyzers/AttributesShouldNotBeAppliedToPageModelAnalyzer.cs @@ -0,0 +1,161 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class AttributesShouldNotBeAppliedToPageModelAnalyzer : DiagnosticAnalyzer + { + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create( + DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods, + DiagnosticDescriptors.MVC1002_RouteAttributesShouldNotBeAppliedToPageHandlerMethods, + DiagnosticDescriptors.MVC1003_RouteAttributesShouldNotBeAppliedToPageModels); + + public override void Initialize(AnalysisContext context) + { +#if !DEBUG + context.EnableConcurrentExecution(); +#endif + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + + TypeCache typeCache = null; + context.RegisterCompilationStartAction(compilationStartAnalysisContext => + { + typeCache = typeCache ?? new TypeCache(compilationStartAnalysisContext.Compilation); + + if (typeCache.PageModelAttribute == null || typeCache.PageModelAttribute.TypeKind == TypeKind.Error) + { + // No-op if we can't find types we care about. + return; + } + + InitializeWorker(compilationStartAnalysisContext, typeCache); + }); + } + + private void InitializeWorker(CompilationStartAnalysisContext compilationStartAnalysisContext, TypeCache typeCache) + { + compilationStartAnalysisContext.RegisterSymbolAction(symbolAnalysisContext => + { + var method = (IMethodSymbol)symbolAnalysisContext.Symbol; + + var declaringType = method.ContainingType; + if (!IsPageModel(declaringType, typeCache.PageModelAttribute)) + { + return; + } + + ReportFilterDiagnostic(ref symbolAnalysisContext, method, typeCache.IFilterMetadata); + ReportFilterDiagnostic(ref symbolAnalysisContext, method, typeCache.AuthorizeAttribute); + ReportFilterDiagnostic(ref symbolAnalysisContext, method, typeCache.AllowAnonymousAttribute); + + ReportRouteDiagnostic(ref symbolAnalysisContext, method, typeCache.IRouteTemplateProvider); + }, SymbolKind.Method); + + compilationStartAnalysisContext.RegisterSymbolAction(symbolAnalysisContext => + { + var type = (INamedTypeSymbol)symbolAnalysisContext.Symbol; + if (!IsPageModel(type, typeCache.PageModelAttribute)) + { + return; + } + + ReportRouteDiagnosticOnModel(ref symbolAnalysisContext, type, typeCache.IRouteTemplateProvider); + }, SymbolKind.NamedType); + } + + private static bool IsPageModel(INamedTypeSymbol type, INamedTypeSymbol pageAttributeModel) + { + return type.TypeKind == TypeKind.Class && + !type.IsStatic && + type.HasAttribute(pageAttributeModel, inherit: true); + } + + private static void ReportRouteDiagnosticOnModel(ref SymbolAnalysisContext symbolAnalysisContext, INamedTypeSymbol typeSymbol, INamedTypeSymbol routeAttribute) + { + var attribute = GetAttribute(typeSymbol, routeAttribute); + if (attribute != null) + { + var location = GetAttributeLocation(ref symbolAnalysisContext, attribute); + + symbolAnalysisContext.ReportDiagnostic(Diagnostic.Create( + DiagnosticDescriptors.MVC1003_RouteAttributesShouldNotBeAppliedToPageModels, + location, + attribute.AttributeClass.Name)); + } + } + + private static void ReportRouteDiagnostic(ref SymbolAnalysisContext symbolAnalysisContext, IMethodSymbol method, INamedTypeSymbol routeAttribute) + { + var attribute = GetAttribute(method, routeAttribute); + if (attribute != null) + { + var location = GetAttributeLocation(ref symbolAnalysisContext, attribute); + + symbolAnalysisContext.ReportDiagnostic(Diagnostic.Create( + DiagnosticDescriptors.MVC1002_RouteAttributesShouldNotBeAppliedToPageHandlerMethods, + location, + attribute.AttributeClass.Name)); + } + } + + private static void ReportFilterDiagnostic(ref SymbolAnalysisContext symbolAnalysisContext, IMethodSymbol method, INamedTypeSymbol filterAttribute) + { + var attribute = GetAttribute(method, filterAttribute); + if (attribute != null) + { + var location = GetAttributeLocation(ref symbolAnalysisContext, attribute); + + symbolAnalysisContext.ReportDiagnostic(Diagnostic.Create( + DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods, + location, + attribute.AttributeClass.Name)); + } + } + + private static AttributeData GetAttribute(ISymbol symbol, INamedTypeSymbol attributeType) + { + foreach (var attribute in symbol.GetAttributes()) + { + if (attributeType.IsAssignableFrom(attribute.AttributeClass)) + { + return attribute; + } + } + + return null; + } + + private static Location GetAttributeLocation(ref SymbolAnalysisContext symbolAnalysisContext, AttributeData attribute) + { + var syntax = attribute.ApplicationSyntaxReference.GetSyntax(symbolAnalysisContext.CancellationToken); + return syntax?.GetLocation() ?? Location.None; + } + + private class TypeCache + { + public TypeCache(Compilation compilation) + { + PageModelAttribute = compilation.GetTypeByMetadataName(SymbolNames.PageModelAttributeType); + IFilterMetadata = compilation.GetTypeByMetadataName(SymbolNames.IFilterMetadataType); + AuthorizeAttribute = compilation.GetTypeByMetadataName(SymbolNames.AuthorizeAttribute); + AllowAnonymousAttribute = compilation.GetTypeByMetadataName(SymbolNames.AllowAnonymousAttribute); + IRouteTemplateProvider = compilation.GetTypeByMetadataName(SymbolNames.IRouteTemplateProvider); + } + + public INamedTypeSymbol PageModelAttribute { get; } + + public INamedTypeSymbol IFilterMetadata { get; } + + public INamedTypeSymbol AuthorizeAttribute { get; } + + public INamedTypeSymbol AllowAnonymousAttribute { get; } + + public INamedTypeSymbol IRouteTemplateProvider { get; } + } + } +} diff --git a/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs new file mode 100644 index 0000000000..c473cc091d --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs @@ -0,0 +1,80 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Diagnostics; +using Microsoft.CodeAnalysis; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + internal static class CodeAnalysisExtensions + { + public static bool HasAttribute(this ITypeSymbol typeSymbol, ITypeSymbol attribute, bool inherit) + { + foreach (var type in typeSymbol.GetTypeHierarchy()) + { + if (type.HasAttribute(attribute)) + { + return true; + } + } + + return false; + } + + public static bool HasAttribute(this ISymbol symbol, ITypeSymbol attribute) + { + Debug.Assert(symbol != null); + Debug.Assert(attribute != null); + + foreach (var declaredAttribute in symbol.GetAttributes()) + { + if (declaredAttribute.AttributeClass == attribute) + { + return true; + } + } + + return false; + } + + public static bool IsAssignableFrom(this ITypeSymbol source, INamedTypeSymbol target) + { + Debug.Assert(source != null); + Debug.Assert(target != null); + + if (source.TypeKind == TypeKind.Interface) + { + foreach (var @interface in target.AllInterfaces) + { + if (source == @interface) + { + return true; + } + } + + return false; + } + + foreach (var type in target.GetTypeHierarchy()) + { + if (source == type) + { + return true; + } + } + + return false; + } + + private static IEnumerable GetTypeHierarchy(this ITypeSymbol typeSymbol) + { + while (typeSymbol != null) + { + yield return typeSymbol; + + typeSymbol = typeSymbol.BaseType; + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Mvc.Analyzers/DiagnosticDescriptors.cs b/src/Microsoft.AspNetCore.Mvc.Analyzers/DiagnosticDescriptors.cs index 89465662b4..524227c5e3 100644 --- a/src/Microsoft.AspNetCore.Mvc.Analyzers/DiagnosticDescriptors.cs +++ b/src/Microsoft.AspNetCore.Mvc.Analyzers/DiagnosticDescriptors.cs @@ -15,5 +15,32 @@ public static class DiagnosticDescriptors "Usage", DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods = + new DiagnosticDescriptor( + "MVC1001", + "Filters cannot be applied to page handler methods.", + "'{0}' cannoted be applied to a Razor Page handler methods. It may be applied either to a PageModel or globally.", + "Usage", + DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor MVC1002_RouteAttributesShouldNotBeAppliedToPageHandlerMethods = + new DiagnosticDescriptor( + "MVC1002", + "Route attributes cannot be applied to page handler methods.", + "'{0}' cannot be applied to a Razor Page handler methods. Routes for Razor Pages must be declared using the @page directive or using conventions.", + "Usage", + DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor MVC1003_RouteAttributesShouldNotBeAppliedToPageModels = + new DiagnosticDescriptor( + "MVC1003", + "Route attributes cannot be applied to page models.", + "'{0}' cannot be applied to a Razor Page model. Routes for Razor Pages must be declared using the @page directive or using conventions.", + "Usage", + DiagnosticSeverity.Warning, + isEnabledByDefault: true); } } diff --git a/src/Microsoft.AspNetCore.Mvc.Analyzers/SymbolNames.cs b/src/Microsoft.AspNetCore.Mvc.Analyzers/SymbolNames.cs index 9c49dd24e6..9e9065df04 100644 --- a/src/Microsoft.AspNetCore.Mvc.Analyzers/SymbolNames.cs +++ b/src/Microsoft.AspNetCore.Mvc.Analyzers/SymbolNames.cs @@ -5,12 +5,22 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers { internal static class SymbolNames { - public const string IHtmlHelperType = "Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper"; + public const string AllowAnonymousAttribute = "Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute"; + + public const string AuthorizeAttribute = "Microsoft.AspNetCore.Authorization.AuthorizeAttribute"; + + public const string IFilterMetadataType = "Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata"; public const string HtmlHelperPartialExtensionsType = "Microsoft.AspNetCore.Mvc.Rendering.HtmlHelperPartialExtensions"; + public const string IHtmlHelperType = "Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper"; + + public const string PageModelAttributeType = "Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageModelAttribute"; + public const string PartialMethod = "Partial"; public const string RenderPartialMethod = "RenderPartial"; + + public const string IRouteTemplateProvider = "Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider"; } } diff --git a/src/Microsoft.AspNetCore.Mvc/Microsoft.AspNetCore.Mvc.csproj b/src/Microsoft.AspNetCore.Mvc/Microsoft.AspNetCore.Mvc.csproj index 76c448b86b..bf0524c732 100644 --- a/src/Microsoft.AspNetCore.Mvc/Microsoft.AspNetCore.Mvc.csproj +++ b/src/Microsoft.AspNetCore.Mvc/Microsoft.AspNetCore.Mvc.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/AttributesShouldNotBeAppliedToPageModelAnalyzerTest.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/AttributesShouldNotBeAppliedToPageModelAnalyzerTest.cs new file mode 100644 index 0000000000..6a3672b8ed --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/AttributesShouldNotBeAppliedToPageModelAnalyzerTest.cs @@ -0,0 +1,112 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Analyzer.Testing; +using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class AttributesShouldNotBeAppliedToPageModelAnalyzerTest + { + private MvcDiagnosticAnalyzerRunner Executor { get; } = new MvcDiagnosticAnalyzerRunner(new AttributesShouldNotBeAppliedToPageModelAnalyzer()); + + [Fact] + public async Task NoDiagnosticsAreReturned_FoEmptyScenarios() + { + // Act + var result = await Executor.GetDiagnosticsAsync(source: string.Empty); + + // Assert + Assert.Empty(result); + } + + [Fact] + public Task NoDiagnosticsAreReturned_ForControllerActions() + => VerifyNoDiagnosticsAreReturned(); + + [Fact] + public Task NoDiagnosticsAreReturned_ForPageHandlersWithNonFilterAttributes() + => VerifyNoDiagnosticsAreReturned(); + + [Fact] + public Task NoDiagnosticsAreReturned_IfFiltersAreAppliedToPageModel() + => VerifyNoDiagnosticsAreReturned(); + + [Fact] + public Task NoDiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageModel() + => VerifyNoDiagnosticsAreReturned(); + + [Fact] + public Task NoDiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageModel() + => VerifyNoDiagnosticsAreReturned(); + + [Fact] + public Task DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethod() + => VerifyDefault(DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodDerivingFromCustomModel() + => VerifyDefault(DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageHandlerMethod() + => VerifyDefault(DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodForTypeWithPageModelAttribute() + => VerifyDefault(DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfAttributeIsAppliedToBaseType() + => VerifyDefault(DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfRouteAttributesAreAppliedToPageHandlerMethod() + => VerifyDefault(DiagnosticDescriptors.MVC1002_RouteAttributesShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod() + => VerifyDefault(DiagnosticDescriptors.MVC1001_FiltersShouldNotBeAppliedToPageHandlerMethods); + + [Fact] + public Task DiagnosticsAreReturned_IfRouteAttribute_IsAppliedToPageModel() + => VerifyDefault(DiagnosticDescriptors.MVC1003_RouteAttributesShouldNotBeAppliedToPageModels); + + private async Task VerifyNoDiagnosticsAreReturned([CallerMemberName] string testMethod = "") + { + // Arrange + var source = MvcTestSource.Read(GetType().Name, testMethod); + + // Act + var result = await Executor.GetDiagnosticsAsync(source.Source); + + // Assert + Assert.Empty(result); + } + + private async Task VerifyDefault(DiagnosticDescriptor descriptor, [CallerMemberName] string testMethod = "") + { + // Arrange + var testSource = MvcTestSource.Read(GetType().Name, testMethod); + var expectedLocation = testSource.DefaultMarkerLocation; + + // Act + var result = await Executor.GetDiagnosticsAsync(testSource.Source); + + // Assert + Assert.Collection( + result, + diagnostic => + { + + Assert.Equal(descriptor.Id, diagnostic.Id); + Assert.Same(descriptor, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(expectedLocation, diagnostic.Location); + }); + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs new file mode 100644 index 0000000000..45ef30ce92 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod : PageModel + { + [/*MM*/AllowAnonymous] + public void OnGet() + { + + } + + public void OnPost() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAttributeIsAppliedToBaseType.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAttributeIsAppliedToBaseType.cs new file mode 100644 index 0000000000..9ca5e1e251 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAttributeIsAppliedToBaseType.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [PageModel] + public abstract class DiagnosticsAreReturned_IfAttributeIsAppliedToBaseTypeBase + { + [/*MM*/Authorize] + public void OnGet() { } + } + + public class DiagnosticsAreReturned_IfAttributeIsAppliedToBaseType : DiagnosticsAreReturned_IfAttributeIsAppliedToBaseTypeBase + { + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageHandlerMethod.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageHandlerMethod.cs new file mode 100644 index 0000000000..7bbfe32c07 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageHandlerMethod.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class DiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageHandlerMethod : PageModel + { + [/*MM*/Authorize] + public void OnPost() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethod.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethod.cs new file mode 100644 index 0000000000..d91567c8cc --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethod.cs @@ -0,0 +1,13 @@ +using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethod : PageModel + { + [/*MM*/ServiceFilter(typeof(object))] + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodDerivingFromCustomModel.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodDerivingFromCustomModel.cs new file mode 100644 index 0000000000..946d5e42be --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodDerivingFromCustomModel.cs @@ -0,0 +1,20 @@ +using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [PageModel] + public abstract class CustomPageModel + { + + } + + public class DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodDerivingFromCustomModel : CustomPageModel + { + [/*MM*/ServiceFilter(typeof(object))] + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodForTypeWithPageModelAttribute.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodForTypeWithPageModelAttribute.cs new file mode 100644 index 0000000000..9b611840c3 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodForTypeWithPageModelAttribute.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [PageModel] + public class DiagnosticsAreReturned_IfFiltersAreAppliedToPageHandlerMethodForTypeWithPageModelAttribute : PageModel + { + [/*MM*/ServiceFilter(typeof(object))] + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfRouteAttribute_IsAppliedToPageModel.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfRouteAttribute_IsAppliedToPageModel.cs new file mode 100644 index 0000000000..3d865c3269 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfRouteAttribute_IsAppliedToPageModel.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [/*MM*/Route("/mypage")] + public class DiagnosticsAreReturned_IfRouteAttribute_IsAppliedToPageModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfRouteAttributesAreAppliedToPageHandlerMethod.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfRouteAttributesAreAppliedToPageHandlerMethod.cs new file mode 100644 index 0000000000..889272bc2c --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfRouteAttributesAreAppliedToPageHandlerMethod.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class DiagnosticsAreReturned_IfRouteAttributesAreAppliedToPageHandlerMethod : PageModel + { + [/*MM*/HttpHead] + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_ForControllerActions.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_ForControllerActions.cs new file mode 100644 index 0000000000..c187cc2ff3 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_ForControllerActions.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Authorization; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class NoDiagnosticsAreReturned_ForControllerActions : Controller + { + [Authorize] + public IActionResult AuthorizeAttribute() => null; + + [ServiceFilter(typeof(object))] + public IActionResult ServiceFilter() => null; + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_ForPageHandlersWithNonFilterAttributes.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_ForPageHandlersWithNonFilterAttributes.cs new file mode 100644 index 0000000000..3e593db2d4 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_ForPageHandlersWithNonFilterAttributes.cs @@ -0,0 +1,13 @@ +using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + public class NoDiagnosticsAreReturned_ForPageHandlersWithNonFilterAttributes : PageModel + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageModel.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageModel.cs new file mode 100644 index 0000000000..c298c43ff2 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageModel.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [AllowAnonymous] + public class NoDiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageModel.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageModel.cs new file mode 100644 index 0000000000..47c778eb9e --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageModel.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [Authorize] + public class NoDiagnosticsAreReturned_IfAuthorizeAttributeIsAppliedToPageModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfFiltersAreAppliedToPageModel.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfFiltersAreAppliedToPageModel.cs new file mode 100644 index 0000000000..5d0198174c --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/NoDiagnosticsAreReturned_IfFiltersAreAppliedToPageModel.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +{ + [ServiceFilter(typeof(object))] + public class NoDiagnosticsAreReturned_IfFiltersAreAppliedToPageModel : PageModel + { + public void OnGet() + { + } + } +}