@ngxtm/devkit 3.4.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Razor Pages
|
|
3
|
+
description: ASP.NET Core Razor Pages patterns for server-rendered web apps.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [razor, mvc, aspnet, web]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/*.cshtml', '**/*.cshtml.cs']
|
|
8
|
+
keywords: [PageModel, OnGet, OnPost, asp-for, asp-action]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Razor Pages
|
|
12
|
+
|
|
13
|
+
## **Priority: P1 (OPERATIONAL)**
|
|
14
|
+
|
|
15
|
+
ASP.NET Core Razor Pages patterns for server-rendered web applications.
|
|
16
|
+
|
|
17
|
+
## Implementation Guidelines
|
|
18
|
+
|
|
19
|
+
- **PageModel**: Keep logic in PageModel, not in `.cshtml`. Use handlers (`OnGet`, `OnPost`).
|
|
20
|
+
- **Model Binding**: Use `[BindProperty]` for form data. `[FromQuery]` for query params.
|
|
21
|
+
- **Tag Helpers**: Use `asp-for`, `asp-action`, `asp-route-*` for type-safe HTML.
|
|
22
|
+
- **Partial Views**: Reusable UI components with `<partial>` tag helper.
|
|
23
|
+
- **View Components**: Complex reusable UI with server logic.
|
|
24
|
+
- **Layout**: Shared layout in `_Layout.cshtml`. Use sections for page-specific content.
|
|
25
|
+
- **TempData**: Flash messages with PRG (Post-Redirect-Get) pattern.
|
|
26
|
+
|
|
27
|
+
## Anti-Patterns
|
|
28
|
+
|
|
29
|
+
- **No logic in `.cshtml`**: Move to PageModel or View Components.
|
|
30
|
+
- **No `ViewBag`/`ViewData`**: Use strongly-typed models.
|
|
31
|
+
- **No inline CSS/JS**: Use external files with bundling.
|
|
32
|
+
- **No form without anti-forgery**: Always include `@Html.AntiForgeryToken()` or use `asp-antiforgery`.
|
|
33
|
+
|
|
34
|
+
## Code
|
|
35
|
+
|
|
36
|
+
```csharp
|
|
37
|
+
// Pages/Users/Create.cshtml.cs
|
|
38
|
+
public class CreateModel(IUserService userService, ILogger<CreateModel> logger) : PageModel
|
|
39
|
+
{
|
|
40
|
+
[BindProperty]
|
|
41
|
+
public CreateUserInput Input { get; set; } = new();
|
|
42
|
+
|
|
43
|
+
public List<SelectListItem> Roles { get; set; } = [];
|
|
44
|
+
|
|
45
|
+
public async Task OnGetAsync()
|
|
46
|
+
{
|
|
47
|
+
Roles = await GetRolesAsync();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public async Task<IActionResult> OnPostAsync()
|
|
51
|
+
{
|
|
52
|
+
if (!ModelState.IsValid)
|
|
53
|
+
{
|
|
54
|
+
Roles = await GetRolesAsync();
|
|
55
|
+
return Page();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var result = await userService.CreateAsync(Input);
|
|
59
|
+
|
|
60
|
+
if (!result.IsSuccess)
|
|
61
|
+
{
|
|
62
|
+
ModelState.AddModelError(string.Empty, result.Error!);
|
|
63
|
+
Roles = await GetRolesAsync();
|
|
64
|
+
return Page();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
TempData["Success"] = "User created successfully";
|
|
68
|
+
return RedirectToPage("./Index");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
@* Pages/Users/Create.cshtml *@
|
|
75
|
+
@page
|
|
76
|
+
@model CreateModel
|
|
77
|
+
|
|
78
|
+
<h2>Create User</h2>
|
|
79
|
+
|
|
80
|
+
@if (TempData["Error"] is string error)
|
|
81
|
+
{
|
|
82
|
+
<div class="alert alert-danger">@error</div>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
<form method="post">
|
|
86
|
+
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
|
87
|
+
|
|
88
|
+
<div class="mb-3">
|
|
89
|
+
<label asp-for="Input.Name" class="form-label"></label>
|
|
90
|
+
<input asp-for="Input.Name" class="form-control" />
|
|
91
|
+
<span asp-validation-for="Input.Name" class="text-danger"></span>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="mb-3">
|
|
95
|
+
<label asp-for="Input.Email" class="form-label"></label>
|
|
96
|
+
<input asp-for="Input.Email" class="form-control" type="email" />
|
|
97
|
+
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div class="mb-3">
|
|
101
|
+
<label asp-for="Input.RoleId" class="form-label"></label>
|
|
102
|
+
<select asp-for="Input.RoleId" asp-items="Model.Roles" class="form-select">
|
|
103
|
+
<option value="">Select a role</option>
|
|
104
|
+
</select>
|
|
105
|
+
<span asp-validation-for="Input.RoleId" class="text-danger"></span>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<button type="submit" class="btn btn-primary">Create</button>
|
|
109
|
+
<a asp-page="./Index" class="btn btn-secondary">Cancel</a>
|
|
110
|
+
</form>
|
|
111
|
+
|
|
112
|
+
@section Scripts {
|
|
113
|
+
<partial name="_ValidationScriptsPartial" />
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Reference & Examples
|
|
118
|
+
|
|
119
|
+
For page conventions, view components, and AJAX patterns:
|
|
120
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
121
|
+
|
|
122
|
+
## Related Topics
|
|
123
|
+
|
|
124
|
+
aspnet-core | blazor | security
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Razor Pages Reference
|
|
2
|
+
|
|
3
|
+
Page conventions, view components, and form handling patterns.
|
|
4
|
+
|
|
5
|
+
## References
|
|
6
|
+
|
|
7
|
+
- [**Page Conventions**](page-conventions.md) - Routing and authorization.
|
|
8
|
+
- [**View Components**](view-components.md) - Reusable UI components.
|
|
9
|
+
- [**Forms**](forms.md) - Form handling and validation.
|
|
10
|
+
|
|
11
|
+
## Page Routing Conventions
|
|
12
|
+
|
|
13
|
+
```csharp
|
|
14
|
+
// Program.cs - Custom conventions
|
|
15
|
+
builder.Services.AddRazorPages(options =>
|
|
16
|
+
{
|
|
17
|
+
// Authorization
|
|
18
|
+
options.Conventions.AuthorizeFolder("/Admin");
|
|
19
|
+
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
|
|
20
|
+
options.Conventions.AllowAnonymousToPage("/Public/Index");
|
|
21
|
+
|
|
22
|
+
// Custom routes
|
|
23
|
+
options.Conventions.AddPageRoute("/Products/Details", "/p/{id}");
|
|
24
|
+
|
|
25
|
+
// Page model conventions
|
|
26
|
+
options.Conventions.AddFolderApplicationModelConvention("/Blog",
|
|
27
|
+
model => model.Filters.Add(new BlogPageFilter()));
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## View Components
|
|
32
|
+
|
|
33
|
+
```csharp
|
|
34
|
+
// ViewComponents/ShoppingCartViewComponent.cs
|
|
35
|
+
public class ShoppingCartViewComponent(ICartService cartService) : ViewComponent
|
|
36
|
+
{
|
|
37
|
+
public async Task<IViewComponentResult> InvokeAsync()
|
|
38
|
+
{
|
|
39
|
+
var cart = await cartService.GetCurrentCartAsync(
|
|
40
|
+
HttpContext.User.Identity?.Name);
|
|
41
|
+
|
|
42
|
+
return View(new ShoppingCartViewModel
|
|
43
|
+
{
|
|
44
|
+
ItemCount = cart?.Items.Count ?? 0,
|
|
45
|
+
Total = cart?.Total ?? 0
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
@* Views/Shared/Components/ShoppingCart/Default.cshtml *@
|
|
53
|
+
@model ShoppingCartViewModel
|
|
54
|
+
|
|
55
|
+
<div class="cart-widget">
|
|
56
|
+
<a asp-page="/Cart/Index">
|
|
57
|
+
<span class="badge">@Model.ItemCount</span>
|
|
58
|
+
Cart: @Model.Total.ToString("C")
|
|
59
|
+
</a>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
@* Usage in layout *@
|
|
63
|
+
<nav>
|
|
64
|
+
@await Component.InvokeAsync("ShoppingCart")
|
|
65
|
+
</nav>
|
|
66
|
+
|
|
67
|
+
@* Or with tag helper *@
|
|
68
|
+
<vc:shopping-cart></vc:shopping-cart>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Handler Methods
|
|
72
|
+
|
|
73
|
+
```csharp
|
|
74
|
+
public class ProductsModel : PageModel
|
|
75
|
+
{
|
|
76
|
+
[BindProperty(SupportsGet = true)]
|
|
77
|
+
public string? SearchTerm { get; set; }
|
|
78
|
+
|
|
79
|
+
[BindProperty(SupportsGet = true)]
|
|
80
|
+
public int PageNumber { get; set; } = 1;
|
|
81
|
+
|
|
82
|
+
public List<ProductDto> Products { get; set; } = [];
|
|
83
|
+
|
|
84
|
+
// GET /Products
|
|
85
|
+
public async Task OnGetAsync()
|
|
86
|
+
{
|
|
87
|
+
Products = await _service.SearchAsync(SearchTerm, PageNumber);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// GET /Products?handler=Export
|
|
91
|
+
public async Task<IActionResult> OnGetExportAsync()
|
|
92
|
+
{
|
|
93
|
+
var csv = await _service.ExportToCsvAsync(SearchTerm);
|
|
94
|
+
return File(csv, "text/csv", "products.csv");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// POST /Products (add to cart)
|
|
98
|
+
public async Task<IActionResult> OnPostAddToCartAsync(int productId)
|
|
99
|
+
{
|
|
100
|
+
await _cartService.AddItemAsync(productId);
|
|
101
|
+
return RedirectToPage();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// POST /Products?handler=Delete
|
|
105
|
+
public async Task<IActionResult> OnPostDeleteAsync(int id)
|
|
106
|
+
{
|
|
107
|
+
await _service.DeleteAsync(id);
|
|
108
|
+
TempData["Success"] = "Product deleted";
|
|
109
|
+
return RedirectToPage();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
@* Multiple forms on same page *@
|
|
116
|
+
<form method="get">
|
|
117
|
+
<input asp-for="SearchTerm" placeholder="Search..." />
|
|
118
|
+
<button type="submit">Search</button>
|
|
119
|
+
</form>
|
|
120
|
+
|
|
121
|
+
<a asp-page-handler="Export" asp-route-searchTerm="@Model.SearchTerm">
|
|
122
|
+
Export to CSV
|
|
123
|
+
</a>
|
|
124
|
+
|
|
125
|
+
@foreach (var product in Model.Products)
|
|
126
|
+
{
|
|
127
|
+
<div class="product">
|
|
128
|
+
<h3>@product.Name</h3>
|
|
129
|
+
|
|
130
|
+
<form method="post" asp-page-handler="AddToCart">
|
|
131
|
+
<input type="hidden" name="productId" value="@product.Id" />
|
|
132
|
+
<button type="submit">Add to Cart</button>
|
|
133
|
+
</form>
|
|
134
|
+
|
|
135
|
+
<form method="post" asp-page-handler="Delete"
|
|
136
|
+
onsubmit="return confirm('Are you sure?')">
|
|
137
|
+
<input type="hidden" name="id" value="@product.Id" />
|
|
138
|
+
<button type="submit" class="btn-danger">Delete</button>
|
|
139
|
+
</form>
|
|
140
|
+
</div>
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## AJAX with Razor Pages
|
|
145
|
+
|
|
146
|
+
```csharp
|
|
147
|
+
// PageModel
|
|
148
|
+
public class ContactModel : PageModel
|
|
149
|
+
{
|
|
150
|
+
[BindProperty]
|
|
151
|
+
public ContactForm Form { get; set; } = new();
|
|
152
|
+
|
|
153
|
+
public async Task<IActionResult> OnPostAsync()
|
|
154
|
+
{
|
|
155
|
+
if (!ModelState.IsValid)
|
|
156
|
+
{
|
|
157
|
+
// Return validation errors for AJAX
|
|
158
|
+
return new JsonResult(new
|
|
159
|
+
{
|
|
160
|
+
success = false,
|
|
161
|
+
errors = ModelState.ToDictionary(
|
|
162
|
+
kvp => kvp.Key,
|
|
163
|
+
kvp => kvp.Value?.Errors.Select(e => e.ErrorMessage))
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
await _emailService.SendContactFormAsync(Form);
|
|
168
|
+
|
|
169
|
+
return new JsonResult(new { success = true });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```html
|
|
175
|
+
@* AJAX form submission *@
|
|
176
|
+
<form id="contactForm" method="post">
|
|
177
|
+
@Html.AntiForgeryToken()
|
|
178
|
+
|
|
179
|
+
<input asp-for="Form.Name" />
|
|
180
|
+
<input asp-for="Form.Email" />
|
|
181
|
+
<textarea asp-for="Form.Message"></textarea>
|
|
182
|
+
|
|
183
|
+
<button type="submit">Send</button>
|
|
184
|
+
</form>
|
|
185
|
+
|
|
186
|
+
<div id="result"></div>
|
|
187
|
+
|
|
188
|
+
@section Scripts {
|
|
189
|
+
<script>
|
|
190
|
+
document.getElementById('contactForm').addEventListener('submit', async (e) => {
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
|
|
193
|
+
const form = e.target;
|
|
194
|
+
const formData = new FormData(form);
|
|
195
|
+
|
|
196
|
+
const response = await fetch(form.action, {
|
|
197
|
+
method: 'POST',
|
|
198
|
+
body: formData
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const result = await response.json();
|
|
202
|
+
|
|
203
|
+
if (result.success) {
|
|
204
|
+
document.getElementById('result').innerHTML =
|
|
205
|
+
'<div class="alert alert-success">Message sent!</div>';
|
|
206
|
+
form.reset();
|
|
207
|
+
} else {
|
|
208
|
+
// Display validation errors
|
|
209
|
+
console.log(result.errors);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
</script>
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Partial Views with Model
|
|
217
|
+
|
|
218
|
+
```csharp
|
|
219
|
+
// Partial with strongly-typed model
|
|
220
|
+
// Pages/Shared/_ProductCard.cshtml
|
|
221
|
+
@model ProductDto
|
|
222
|
+
|
|
223
|
+
<div class="card">
|
|
224
|
+
<img src="@Model.ImageUrl" alt="@Model.Name" />
|
|
225
|
+
<h5>@Model.Name</h5>
|
|
226
|
+
<p>@Model.Price.ToString("C")</p>
|
|
227
|
+
<a asp-page="/Products/Details" asp-route-id="@Model.Id">View</a>
|
|
228
|
+
</div>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
```html
|
|
232
|
+
@* Usage *@
|
|
233
|
+
@foreach (var product in Model.Products)
|
|
234
|
+
{
|
|
235
|
+
<partial name="_ProductCard" model="product" />
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@* Or with tag helper *@
|
|
239
|
+
<partial name="_ProductCard" model="Model.FeaturedProduct" />
|
|
240
|
+
|
|
241
|
+
@* Pass additional ViewData *@
|
|
242
|
+
<partial name="_ProductCard" model="product"
|
|
243
|
+
view-data='new ViewDataDictionary(ViewData) { { "ShowActions", true } }' />
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Areas Organization
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
Areas/
|
|
250
|
+
├── Admin/
|
|
251
|
+
│ ├── Pages/
|
|
252
|
+
│ │ ├── _ViewStart.cshtml @{ Layout = "_AdminLayout"; }
|
|
253
|
+
│ │ ├── Dashboard/
|
|
254
|
+
│ │ │ └── Index.cshtml
|
|
255
|
+
│ │ └── Users/
|
|
256
|
+
│ │ ├── Index.cshtml
|
|
257
|
+
│ │ └── Edit.cshtml
|
|
258
|
+
│ └── _AdminLayout.cshtml
|
|
259
|
+
└── Identity/
|
|
260
|
+
└── Pages/
|
|
261
|
+
└── Account/
|
|
262
|
+
├── Login.cshtml
|
|
263
|
+
└── Register.cshtml
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```html
|
|
267
|
+
@* Link to area page *@
|
|
268
|
+
<a asp-area="Admin" asp-page="/Dashboard/Index">Admin Dashboard</a>
|
|
269
|
+
<a asp-area="Identity" asp-page="/Account/Login">Login</a>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## TempData and Flash Messages
|
|
273
|
+
|
|
274
|
+
```csharp
|
|
275
|
+
// Set messages
|
|
276
|
+
TempData["Success"] = "Record saved successfully";
|
|
277
|
+
TempData["Error"] = "An error occurred";
|
|
278
|
+
TempData["Warning"] = "Please review your changes";
|
|
279
|
+
|
|
280
|
+
// In PageModel
|
|
281
|
+
public IActionResult OnPostDelete(int id)
|
|
282
|
+
{
|
|
283
|
+
var result = _service.Delete(id);
|
|
284
|
+
|
|
285
|
+
if (result.IsSuccess)
|
|
286
|
+
{
|
|
287
|
+
TempData["Success"] = $"Item {id} deleted";
|
|
288
|
+
return RedirectToPage("./Index");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
TempData["Error"] = result.Error;
|
|
292
|
+
return RedirectToPage();
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
```html
|
|
297
|
+
@* _Layout.cshtml - Flash message partial *@
|
|
298
|
+
@if (TempData["Success"] is string success)
|
|
299
|
+
{
|
|
300
|
+
<div class="alert alert-success alert-dismissible fade show">
|
|
301
|
+
@success
|
|
302
|
+
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
303
|
+
</div>
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
@if (TempData["Error"] is string error)
|
|
307
|
+
{
|
|
308
|
+
<div class="alert alert-danger alert-dismissible fade show">
|
|
309
|
+
@error
|
|
310
|
+
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
311
|
+
</div>
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@if (TempData["Warning"] is string warning)
|
|
315
|
+
{
|
|
316
|
+
<div class="alert alert-warning alert-dismissible fade show">
|
|
317
|
+
@warning
|
|
318
|
+
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
319
|
+
</div>
|
|
320
|
+
}
|
|
321
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: .NET Security
|
|
3
|
+
description: Security standards for .NET applications based on OWASP guidelines.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [security, auth, owasp, dotnet]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/*.cs', '**/appsettings*.json']
|
|
8
|
+
keywords: [Authorize, Authentication, Identity, JWT, CORS, password]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# .NET Security
|
|
12
|
+
|
|
13
|
+
## **Priority: P0 (CRITICAL)**
|
|
14
|
+
|
|
15
|
+
Security standards for .NET applications based on OWASP guidelines.
|
|
16
|
+
|
|
17
|
+
## Implementation Guidelines
|
|
18
|
+
|
|
19
|
+
- **Authentication**: ASP.NET Identity for users, JWT Bearer for APIs, Cookie auth for web apps.
|
|
20
|
+
- **Authorization**: Policy-based over role-based. Resource-based for fine-grained control.
|
|
21
|
+
- **Input Validation**: `FluentValidation` or `DataAnnotations`. Validate at API boundaries.
|
|
22
|
+
- **SQL Injection**: Always use parameterized queries. EF Core and Dapper handle this automatically.
|
|
23
|
+
- **XSS Prevention**: Razor auto-encodes by default. Use `HtmlEncoder` for manual encoding.
|
|
24
|
+
- **CSRF**: Anti-forgery tokens for forms. `SameSite=Strict` cookies.
|
|
25
|
+
- **Secrets**: Never hardcode. Use User Secrets (dev), Azure Key Vault (prod).
|
|
26
|
+
- **HTTPS**: Always `UseHttpsRedirection()`. Enable HSTS in production.
|
|
27
|
+
- **Headers**: Use security headers middleware (CSP, X-Frame-Options, etc.).
|
|
28
|
+
- **Rate Limiting**: Use built-in `RateLimiter` middleware (.NET 7+).
|
|
29
|
+
|
|
30
|
+
## Anti-Patterns
|
|
31
|
+
|
|
32
|
+
- **No hardcoded secrets**: Never commit API keys, connection strings, passwords.
|
|
33
|
+
- **No `[AllowAnonymous]` on sensitive endpoints**: Review all anonymous access.
|
|
34
|
+
- **No raw SQL with interpolation**: `$"SELECT * FROM Users WHERE Id = {id}"` is vulnerable.
|
|
35
|
+
- **No `*` CORS in production**: Specify allowed origins explicitly.
|
|
36
|
+
- **No disabled SSL validation**: Never `ServerCertificateCustomValidationCallback = (_, _, _, _) => true`.
|
|
37
|
+
|
|
38
|
+
## Code
|
|
39
|
+
|
|
40
|
+
```csharp
|
|
41
|
+
// JWT Bearer configuration
|
|
42
|
+
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
43
|
+
.AddJwtBearer(options =>
|
|
44
|
+
{
|
|
45
|
+
options.TokenValidationParameters = new TokenValidationParameters
|
|
46
|
+
{
|
|
47
|
+
ValidateIssuer = true,
|
|
48
|
+
ValidateAudience = true,
|
|
49
|
+
ValidateLifetime = true,
|
|
50
|
+
ValidateIssuerSigningKey = true,
|
|
51
|
+
ValidIssuer = builder.Configuration["Jwt:Issuer"],
|
|
52
|
+
ValidAudience = builder.Configuration["Jwt:Audience"],
|
|
53
|
+
IssuerSigningKey = new SymmetricSecurityKey(
|
|
54
|
+
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Policy-based authorization
|
|
59
|
+
builder.Services.AddAuthorization(options =>
|
|
60
|
+
{
|
|
61
|
+
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
|
|
62
|
+
options.AddPolicy("CanEditOrder", policy =>
|
|
63
|
+
policy.Requirements.Add(new ResourceOwnerRequirement()));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Parameterized query (safe from SQL injection)
|
|
67
|
+
var user = await connection.QuerySingleAsync<User>(
|
|
68
|
+
"SELECT * FROM Users WHERE Id = @Id AND Status = @Status",
|
|
69
|
+
new { Id = userId, Status = "Active" });
|
|
70
|
+
|
|
71
|
+
// Rate limiting
|
|
72
|
+
builder.Services.AddRateLimiter(options =>
|
|
73
|
+
{
|
|
74
|
+
options.AddFixedWindowLimiter("api", cfg =>
|
|
75
|
+
{
|
|
76
|
+
cfg.Window = TimeSpan.FromMinutes(1);
|
|
77
|
+
cfg.PermitLimit = 100;
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Reference & Examples
|
|
83
|
+
|
|
84
|
+
For JWT patterns, Identity configuration, and security headers:
|
|
85
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
86
|
+
|
|
87
|
+
## Related Topics
|
|
88
|
+
|
|
89
|
+
language | best-practices | aspnet-core
|