Skip to content

Attributes ​

This page lists every public attribute class in the Hardened packages, grouped by what each one is for. It also lists the attributes of DependencyModules and ValidationModules that the Hardened guides cover. Three Hardened packages depend on those libraries: Hardened.Shared.Runtime on DependencyModules.Runtime, Hardened.Shared.Testing on DependencyModules.Testing, and Hardened.Requests.Runtime on ValidationModules.Runtime.

The Targets column gives the attribute's AttributeUsage, its own or its base class's. It says Any where neither declares one. The compiler then accepts the attribute on any declaration. Such a row's description says where the build reads it. Repeatable means AllowMultiple = true.

A module attribute is the attribute that the build writes for a module class. The attribute class is named after the module class with Attribute appended: the module class KestrelRuntime gets [KestrelRuntime]. Applying the attribute imports the module. A module attribute's properties are the module class's public settable properties. Every module attribute accepts a class, an assembly, a method and a parameter, and is repeatable. The tables show these targets as Module attribute.

Modules and configuration ​

AttributeTargetsNamespace and packageWhat it doesPage
[HardenedModule]AnyHardened.Shared.Runtime.Attributes in Hardened.Shared.RuntimeMakes the partial class it is on a module. The build writes the module's attributeModules
[<Module>], such as [TodosLibrary]Class, assembly, method, parameter; repeatableThe module's namespace, in the module's projectImports the module. The build writes it for each [HardenedModule] class
Properties: one named property for each public settable property of the module
Modules
[Enable<TFeature>]
TFeature has a public parameterless constructor
Class, assembly; repeatableHardened.Shared.Runtime.Attributes in Hardened.Shared.RuntimeTurns on the feature TFeature for the module class it is onThis page, Features
[HardenedCoreModule]Module attributeHardened.Shared.Runtime.DependencyInjection in Hardened.Shared.RuntimeRegisters shared services, such as the JSON serializer configuration. [HardenedRequestModule] imports itModules
[HardenedRequestModule]Module attributeHardened.Requests.Runtime.DependencyInjection in Hardened.Requests.RuntimeRegisters the request pipeline. [HardenedWebModule], [LambdaRuntimeModule] and [FunctionsRuntimeModule] import itModules
[ConfigurationModel]AnyHardened.Shared.Runtime.Attributes in Hardened.Shared.RuntimeMakes the partial class it is on a configuration model. The build writes an interface named I plus the class name, with a property for each field, and registers IOptions<> of the interfaceConfiguration
[FromEnvironmentVariable(environmentVariable)]
string environmentVariable
AnyHardened.Shared.Runtime.Attributes in Hardened.Shared.RuntimeOn a field of a configuration model: fills the field from that environment variableConfiguration
[HideConfigurationField]AnyHardened.Shared.Runtime.Attributes in Hardened.Shared.RuntimeOn a field of a configuration model: the build writes no property for the fieldConfiguration
[ConfigurationProvider]AnyHardened.Shared.Runtime.Attributes in Hardened.Shared.RuntimeNothing in the build or at run time reads itNone

The build reads [FromEnvironmentVariable] and [HideConfigurationField] on a field of the model class, and not on a property. [HardenedCoreModule] and [HardenedRequestModule] come with every host's module attribute. An application does not write them.

Services ​

The service attributes come from DependencyModules. Each one is in the namespace DependencyModules.Runtime.Attributes, in the package DependencyModules.Runtime 1.7.0. A project that references Hardened.Shared.Runtime needs no reference of its own to the package. Registering services covers each attribute.

AttributeTargetsWhat it does
[SingletonService]Class, method; repeatableRegisters the class, one instance for the application
Properties: As (unset: the service type the build picks), Using (RegistrationType.Add), Key (none), Realm (none), Order (0)
[ScopedService]Class, method; repeatableRegisters the class, one instance per request
Properties: the same as [SingletonService]
[TransientService]Class, method; repeatableRegisters the class, a new instance each time it is resolved
Properties: the same as [SingletonService]
[CrossWireService]Class, method; repeatableRegisters the class as itself and as every interface it declares, all resolving to one instance
Properties: Lifetime (ServiceLifetime.Singleton), Using (RegistrationType.Add), Key (none), Realm (none)
[IfEnvironment(params environmentNames)]
string[] environmentNames
ClassRegisters the class only in the named environments
[IfNotEnvironment(params environmentNames)]
string[] environmentNames
ClassRegisters the class only outside the named environments
[IfEnvironmentValue(key)], [IfEnvironmentValue(key, value)]
string key, string value
Class; repeatableRegisters the class when the variable has a value, or has exactly that value
[IfNotEnvironmentValue(key)], [IfNotEnvironmentValue(key, value)]
string key, string value
Class; repeatableRegisters the class when the variable has no value, or not exactly that value
[Decorator]ClassMakes the class wrap every registration of the service it implements
Properties: Service (none), Order (0), Realm (none), Implementation (none)
[Decorate(service, decorator)]
Type service, Type decorator
Class; repeatableApplies a decorator to a service from an assembly you do not control
Property: Order (0)
[Intercept(params interceptors)]
Type[] interceptors
Class; repeatableDoes nothing in a Hardened project: the interceptor never runs, and the build reports nothing
Properties: Service (none), Order (0), Realm (none), Lifetime (ServiceLifetime.Singleton), Members (InterceptedMembers.All)

Handlers and binding ​

AttributeTargetsNamespace and packageWhat it doesPage
[Get(path)]
string path = "", which routes /
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeMakes the method a handler for GET and HEAD at the path template
Property: SuccessStatus (unset: 200)
Routing
[Post(path)]
As [Get]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeMakes the method a handler for POST at the path templateRouting
[Put(path)]
As [Get]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeMakes the method a handler for PUT at the path templateRouting
[Patch(path)]
As [Get]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeMakes the method a handler for PATCH at the path templateRouting
[Delete(path)]
As [Get]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeMakes the method a handler for DELETE at the path templateRouting
[BasePath(path)]
string path
Class, assemblyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeOn the module that holds the routes: prefixes every route in the module's projectRouting
[CaseInsensitiveRoutes]ClassHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeOn the module that holds the routes: matches its routes without regard to caseRouting
[RouteConstraint(name)]
string name
Method; repeatableHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeOn a static bool method that takes a ReadOnlySpan<char>: declares the route constraint nameRouting
[FromQueryString(name)]
string? name = null, which reads the parameter's own name
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeBinds the parameter from the query string value of that nameParameter binding
[FromHeader(name)]
As [FromQueryString]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeBinds the parameter from the request header of that nameParameter binding
[FromCookie(name)]
As [FromQueryString]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeBinds the parameter from the cookie of that nameParameter binding
[FromForm(name)]
As [FromQueryString]
AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeBinds the parameter from a field or a file of an application/x-www-form-urlencoded or multipart/form-data bodyForms and files
[FromBody]AnyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractBinds the parameter from the request bodyParameter binding
[FromServices]AnyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractResolves the parameter from the containerRegistering services
[Handler]ClassHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractMarks a class that implements a service interface generated from a contract. The class answers the contract's operationsGenerating from OpenAPI
[ResponseOnly]Property, parameterHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractMarks a member that responses carry and clients do not send. A contract's readOnly generates it. A request body can leave the member out even when it is requiredGenerating from OpenAPI
[RequestOnly]Property, parameterHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractMarks a member that clients send and responses do not carry. A contract's writeOnly generates it. Nothing enforces itGenerating from OpenAPI

The build reads a route attribute on a method. It reads a binding attribute on a parameter. Neither [ResponseOnly] nor [RequestOnly] is enforced. A request can set a readOnly member. A response writes a writeOnly member.

Responses and serialization ​

AttributeTargetsNamespace and packageWhat it doesPage
[HttpStatus(statusCode)]
int statusCode
Class, structHardened.Web.Runtime.Responses in Hardened.Web.RuntimeOn a response type: the status a response of that type answers withDeclared responses
[Throws<TError>], [Throws<TError>(statusCode)]
int statusCode (unset: the status in TError's [HttpStatus])
Method; repeatableHardened.Web.Runtime.Responses in Hardened.Web.RuntimeDeclares a non-2xx response that the handler answers by throwing, so the OpenAPI document lists it
Property: Description (none)
Declared responses
[AnswersHeader(status, name)]
int status, string name
[AnswersHeader(name)]
string name
Class, method, interface; repeatableHardened.Requests.Abstract.Responses in Hardened.Requests.AbstractLists a header on the response with that status in the OpenAPI document. With no status, on every response the operation lists
Properties: Description (none), Methods (none), NotWhenStreaming (false)
Declared responses
[ResponseModel(model)]
ResponseModel model: Throws, Response or Union
ClassHardened.Requests.Abstract.Responses in Hardened.Requests.AbstractNames the response model of the module's handlers. A code-first build generates the same code with it or without itDeclared responses
[Produces(params contentTypes)]
string[] contentTypes
Class, method, assemblyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractThe media types the operation answers with, in preference orderContent negotiation
[RawResponse(contentType)]
string contentType = "text/plain"
MethodHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractObsolete. [Produces] under an older name, and the compiler warns with CS0618 naming [Produces]Content negotiation
[ContentNegotiation(mode)]
ContentNegotiationMode mode: Strict answers 406, Lenient answers with the default serializer
Class, assemblyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractChooses the answer to a request for a media type that no operation produces. See LimitsContent negotiation
[WritesContentType(params contentTypes)]
string[] contentTypes
Assembly; repeatableHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractNames the media types a serializer in the assembly writes a model as. The build reads it before it warns HRDR012Content negotiation
[JsonErrorBodies]Class, assemblyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractOn the module that declares the routes: answers every response with a status of 400 or more as JSON, whatever the request negotiatedContent negotiation
[JsonEnumNaming(naming)]
EnumNaming naming: MemberName, CamelCase, KebabCaseLower, SnakeCaseLower or SnakeCaseUpper
Enum, assemblyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractHow the values of one enum, or of every enum in the assembly, are written in JSON. Without it they are camelCaseJSON serialization
[AotSerializerModule]ClassHardened.Requests.Runtime in Hardened.Requests.RuntimeOn the application module: registers JSON serializers that read only from the registered resolvers, for Native AOTJSON serialization
[MessagePackSerializerLibrary]Module attributeHardened.Requests.Serializers.MessagePack in Hardened.Requests.Serializers.MessagePackRegisters the MessagePack reader and writerMessagePack
[ServerSentEvents]MethodHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeSends the handler's IAsyncEnumerable<T> as text/event-stream in place of newline-delimited JSONStreaming responses

[RawResponse] carries [Obsolete] with the message Use [Produces] instead. [RawResponse("text/csv")] is [Produces("text/csv")].

The enums that the constructors take are in these namespaces:

TypeNamespace
ResponseModelHardened.Requests.Abstract.Responses
ContentNegotiationModeHardened.Requests.Abstract.Serializer
EnumNamingHardened.Requests.Abstract.Attributes

Validation ​

AttributeTargetsNamespace and packageWhat it doesPage
[Validate<TValidated>]
TValidated is a reference type
Class, methodHardened.Requests.Runtime.Validation in Hardened.Requests.RuntimeThe build attaches it to a handler whose parameters declare constraints. It runs every registered IValidatorFor<TValidated> against the bound parametersNone
[ValidationMode(stopMode)]
ValidationStopMode stopMode: CollectAll or StopOnFirstError
Class, methodHardened.Requests.Runtime.Validation in Hardened.Requests.RuntimeWhether a request that fails validation is answered with every failure or with the first. A handler under no declaration gets every failure. The nearest declaration wins. ValidationStopMode is in the namespace ValidationModules. See LimitsValidation

TValidated is an interface that the generated parameters class implements. With no IValidatorFor<TValidated> registered, the request fails with an InvalidOperationException that names the type.

The constraint attributes come from ValidationModules. Each one is in the namespace ValidationModules.Constraints, in the package ValidationModules.Runtime 1.2.0. A project that references Hardened.Requests.Runtime needs no reference of its own to the package. Validation covers each constraint. Every constraint also takes the properties Code, Message, When and Unless, all unset.

AttributeTargetsWhat it does
[Required]Property, field, parameter; repeatableThe value is present
Property: AllowEmptyStrings (false)
[StringLength(max)]
int max, or Min and Max
Property, field, parameter; repeatableA string's length is within the bounds
[Range(min, max)]
min and max as int, long, double or string, or Min and Max
Property, field, parameter; repeatableThe value is within the bounds
Properties: ExclusiveMin (false), ExclusiveMax (false)
[Pattern(pattern)], [Pattern(regexProvider, regexMember)]
string pattern, or Type regexProvider and string regexMember for a [GeneratedRegex] method
Property, field, parameter; repeatableThe string matches the regular expression
Properties: Options (RegexOptions.None), MatchTimeoutMilliseconds (0)
[ItemCount(min, max)]
int min = 0, int max = int.MaxValue, or Min and Max
Property, field, parameter; repeatableA collection's count is within the bounds
[AllowedValues(params values)]
object[] values
Property, field, parameter; repeatableThe value is one of these
Property: Comparison (StringComparison.Ordinal)
[DeniedValues(params values)]
object[] values
Property, field, parameter; repeatableThe value is none of these
[MultipleOf(divisor)]
divisor as int, long, double or string
Property, field, parameter; repeatableThe number is a multiple of the divisor
[UniqueItems]Property, field, parameter; repeatableA collection's items are distinct
[EmailAddress]Property, field, parameter; repeatableThe string is an email address
[Phone]Property, field, parameter; repeatableThe string is a phone number
[Url]Property, field, parameter; repeatableThe string is a URL
[CreditCard]Property, field, parameter; repeatableThe string is a credit card number
[Base64String]Property, field, parameter; repeatableThe string is Base64
[FileExtensions]Property, field, parameter; repeatableThe string ends in one of the extensions
Property: Extensions (png,jpg,jpeg,gif)
[ValidateNested], [ValidateNested(polymorphism)]
Polymorphism polymorphism
Property, field, parameter; repeatableChecks the constraints of the member's own type

Filters ​

AttributeTargetsNamespace and packageWhat it doesPage
[Retry]Class, methodHardened.Requests.Runtime.Filters in Hardened.Requests.RuntimeRuns the handler again when an attempt fails
Properties: Attempts (3), Retries (reads and sets Attempts), SleepTime (500 ms), TotalBudget (10000 ms), AllowNonIdempotent (false)
The execution pipeline
[Timeout]Class, method, assemblyHardened.Requests.Runtime.Filters in Hardened.Requests.RuntimeBounds how long the operation may take. The nearest declaration wins
Properties: Milliseconds (30000), Status (504), RetryAfterSeconds (0, which writes no Retry-After), Deadline (true)
Request timeouts
[RequestTimeouts(milliseconds)]
int milliseconds
Module attributeHardened.Requests.Runtime.Filters in Hardened.Requests.RuntimeBounds every handler in the application that no nearer declaration boundsRequest timeouts
[RateLimit]Class, method; repeatableHardened.Requests.Runtime.RateLimiting in Hardened.Requests.RuntimeLimits how many requests each caller can make in a window. A request past the limit gets 429
Properties: PermitLimit (100), WindowSeconds (60), Name ("default"), Scope (RateLimitScope.Transport)
Rate limiting
[CacheResponse<TProvider>(params values)]
string[] values
TProvider implements ICacheKeyProvider
Class, method; repeatableHardened.Requests.Runtime.Caching in Hardened.Requests.RuntimeStores the handler's response and serves it to a later request with the same key, without running the handler. TProvider builds the key from the values
Properties: Duration (0, which stores for 60 seconds), Scope (CacheScope.Unstated), Tags (empty), CoalesceMisses (false)
Response caching
[CacheControl]AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeWrites the Cache-Control header on the handler's responses, or on those of every handler in the class. It stores nothing
Properties: MaxAge (0), Type (CacheControlEnum.MaxAge | CacheControlEnum.Public)
Response caching
[HardenedMemoryResponseCache]Module attributeHardened.Requests.Caching.Memory in Hardened.Requests.Caching.MemoryRegisters the in-process store that [CacheResponse<TProvider>] keeps responses inResponse caching
[Compress]Class, methodHardened.Web.Runtime.Compression in Hardened.Web.RuntimeCompresses the handler's response for a request whose Accept-Encoding names gzip or Brotli
Property: Favor (CompressionType.Default, which follows the configured order)
Compression
[Compress<TPredicate>(params args)]
object[] args
TPredicate implements ICompressionPredicate
Class, methodHardened.Web.Runtime.Compression in Hardened.Web.RuntimeAs [Compress], when TPredicate says so, given the value the handler returned
Property: Favor (as [Compress])
Compression
[ResponseCompression]Module attributeHardened.Web.Runtime.Compression in Hardened.Web.RuntimeCompresses every response in the application. It applies the module that [Enable<ResponseCompression>] appliesCompression
[ConditionalGet]Class, methodHardened.Web.Runtime.Conditional in Hardened.Web.RuntimeGives a GET handler's response an ETag, and answers a request whose If-None-Match matches with 304 and no bodyConditional requests
[Cors]Class, methodHardened.Web.Runtime.Cors in Hardened.Web.RuntimeLimits CORS to the handlers it covers, which answer with the application's CorsConfiguration. Once a handler or a module declares it, a route without a declaration gets no CORS headersCORS
[Cors<TPolicy>]Class, methodHardened.Web.Runtime.Cors in Hardened.Web.RuntimeAs [Cors], with the configuration that AddCorsPolicy<TPolicy> registered. TPolicy can be any typeCORS
[AnswersStatus(status, body)], [AnswersStatus(status)]
int status, Type body
Class, interface; repeatableHardened.Requests.Abstract.Responses in Hardened.Requests.AbstractOn a filter attribute: every operation that carries the filter publishes the status, with that body, in the OpenAPI document
Properties: Description, Methods and StatusFrom (none), NotWhenStreaming (false)
The execution pipeline
[ReadsHeader(name)]
string name
Class, method, interface; repeatableHardened.Web.Runtime.Responses in Hardened.Web.RuntimeOn a filter attribute: every operation that carries the filter publishes the header as an optional parameter
Properties: Description and Methods (none), NotWhenStreaming (false), WhenAnswered (none): a response header a success must list for the parameter to be published
The execution pipeline

The defaults in the table are the values of a new instance. A filter attribute that goes on a method or a class also goes on a [HardenedModule] class. There it covers the handlers compiled with the module. Limits lists the enum values that fail the build on a module class.

The enums in the table are in these namespaces:

TypeNamespaceValues
RateLimitScopeHardened.Requests.Runtime.RateLimitingTransport, Principal
CacheScopeHardened.Requests.Abstract.CachingUnstated, AllCallers, PerCaller
CompressionTypeHardened.Web.Runtime.CompressionDefault, GZip, Br
CacheControlEnumHardened.Web.Runtime.CacheControlFlags: MaxAge, NoCache, NoStore, NoTransform, Public, Private

Authentication and authorization ​

AttributeTargetsNamespace and packageWhat it doesPage
[HttpAuthenticationScheme(scheme)]
string scheme
ClassHardened.Requests.Abstract.Authorization in Hardened.Requests.AbstractOn an IAuthenticationScheme class: publishes it as an HTTP scheme, such as bearer
Properties: BearerFormat (none), Description (none)
Authentication
[ApiKeyAuthenticationScheme(name, location)]
string name, ApiKeyLocation location
ClassHardened.Requests.Abstract.Authorization in Hardened.Requests.AbstractOn an IAuthenticationScheme class: publishes it as an API key in a header, a query parameter or a cookie
Property: Description (none)
Authentication
[OAuth2AuthenticationScheme(flow)]
OAuth2Flow flow
ClassHardened.Requests.Abstract.Authorization in Hardened.Requests.AbstractOn an IAuthenticationScheme class: publishes it as OAuth2 with one flow
Properties: AuthorizationUrl, TokenUrl, RefreshUrl and Description (none)
Authentication
[Authorize<TAuth>]
TAuth implements IAuthenticationScheme
Class, method. On a [HardenedModule] class, every handler compiled with the moduleHardened.Requests.Runtime.Authorization in Hardened.Requests.RuntimeRequires an authenticated caller, and names the scheme TAuth in the OpenAPI documentAuthentication
[Authorize<TAuth, TPolicy>]
TPolicy implements IAuthorizationPolicy and has a public parameterless constructor
Class, method. On a [HardenedModule] class, every handler compiled with the moduleHardened.Requests.Runtime.Authorization in Hardened.Requests.RuntimeRequires an authenticated caller who satisfies the policy TPolicyAuthorization
[AuthorizeGrants(params grants)]
string[] grants
Class, method; repeatable. On a [HardenedModule] class, every handler compiled with the moduleHardened.Requests.Runtime.Authorization in Hardened.Requests.RuntimeRequires every grant namedAuthorization
[AuthorizeGrants<T>]
T implements IGrantProvider and has a public parameterless constructor
Class, method; repeatable. On a [HardenedModule] class, every handler compiled with the moduleHardened.Requests.Runtime.Authorization in Hardened.Requests.RuntimeRequires every grant that T namesAuthorization
[AllowAnonymous]Class, methodHardened.Requests.Runtime.Authorization in Hardened.Requests.RuntimeMakes the handler public. It overrides every requirementAuthorization
[RequireAuthorization]Class, assemblyHardened.Requests.Runtime.Authorization in Hardened.Requests.RuntimeOn a [HardenedModule] class: every handler in the application that declares no authorization requires an authenticated callerAuthorization
[JwtBearerAuthentication<TScheme>]
TScheme implements IAuthenticationScheme
ClassHardened.Requests.Jwt in Hardened.Requests.JwtOn a [HardenedModule] class: authenticates a bearer token as a JWT for the scheme TScheme. JWT_ISSUER, JWT_AUDIENCE, and JWT_AUTHORITY or JWT_JWKS_URL configure itAuthentication

The types that the table names are in these namespaces:

TypeNamespaceValues
ApiKeyLocationHardened.Requests.Abstract.AuthorizationHeader, Query, Cookie
OAuth2FlowHardened.Requests.Abstract.AuthorizationAuthorizationCode, ClientCredentials, Implicit, Password
IAuthenticationSchemeHardened.Requests.Abstract.Authorization
IAuthorizationPolicyHardened.Requests.Abstract.Authorization
IGrantProviderHardened.Requests.Runtime.Authorization

Authorization covers how the requirements on a method, its class and a module combine.

Web hosts and the OpenAPI document ​

AttributeTargetsNamespace and packageWhat it doesPage
[HardenedWebModule]Module attributeHardened.Web.Runtime.DependencyInjection in Hardened.Web.RuntimeServes the routes, and /health/live and /health/ready. [KestrelRuntime], [AspNetCoreRuntime] and [CloudRunRuntime] import itHosts
[KestrelRuntime]Module attributeHardened.Web.Kestrel.Runtime in Hardened.Web.Kestrel.RuntimeRuns the application on Kestrel, without the ASP.NET Core request pipelineHosts
[AspNetCoreRuntime]Module attributeHardened.Web.AspNetCore.Runtime in Hardened.Web.AspNetCore.RuntimeRuns the application inside the ASP.NET Core request pipeline, where app.UseHardened() adds itHosts
[OpenApiInfo(title, version, description)]
string title, string version = "1.0.0", string? description = null
ClassHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeOn the module that publishes the document: the document's infoThe OpenAPI document
[Server(url, description)]
string url, string? description = null
Class, assembly; repeatableHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeOn the module that publishes the document: adds the URL to the document's serversThe OpenAPI document
[Tag(name)]
string name
ClassHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeThe tag the class's operations are published under. Without it, the class name without a Controller suffixThe OpenAPI document
[Operation(id)]
string id
MethodHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeThe operationId the handler publishes. Without it, the method name with its first letter lower-casedThe OpenAPI document
[OpenApiDocumentPath(path)]
string path
ClassHardened.Web.Runtime.OpenApi in Hardened.Web.RuntimeOn a feature marker class: [Enable<>] of the class serves the document at the path in place of /openapi.jsonThe OpenAPI document
[HardenedOpenApiUi]Module attributeHardened.Web.Runtime.OpenApi in Hardened.Web.RuntimeServes a reference page for the OpenAPI document
Properties: Path (/docs), Title (API Reference), DocumentPath (/openapi.json), ScriptUrl (@scalar/api-reference 1.65.1 from jsDelivr), ScriptIntegrity (that script's SHA-384 hash), DecodeMessagePack (false), MessagePackScriptUrl (@msgpack/msgpack 3.1.3 from jsDelivr), Environments (unset, which serves the page in every environment)
The OpenAPI document
[HardenedStaticContent]Module attributeHardened.Web.StaticContent in Hardened.Web.StaticContentServes a directory of files
Properties: Path (wwwroot), FallBackFile (none), RoutePrefix (/)
None
[WebLibrary]AnyHardened.Web.Runtime.Attributes in Hardened.Web.RuntimeNothing in the build or at run time reads itNone

[LambdaHttpModule], [CloudRunRuntime] and [HttpModule] are the web hosts of the three clouds. Their rows are under AWS, Google Cloud and Azure.

The string properties of [HardenedOpenApiUi] keep the module's defaults when the attribute leaves them unset. The full ScriptUrl default is https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.65.1/dist/browser/standalone.js. The full MessagePackScriptUrl default is https://cdn.jsdelivr.net/npm/@msgpack/msgpack@3.1.3/dist.umd/msgpack.min.js. Environments is a comma-separated list of environment names.

RoutePrefix on [HardenedStaticContent] is the path the directory is served under, such as /static. It applies to a directory read at run time. A build that declares HardenedStaticContent items serves their manifest, and each item's own RoutePrefix sets where its files are served.

The build's HRDR004 message says to move shared handlers into a [WebLibrary] project.

Views ​

AttributeTargetsNamespace and packageWhat it doesPage
[Output<TOutput>]
TOutput implements IHardenedResponseOutput and has a public parameterless constructor
MethodHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractRenders the handler's return value with the view TOutput, in place of serializing itViews
[TemplateBase(baseType)]
Type baseType
ClassHardened.Requests.Abstract.Templates in Hardened.Requests.AbstractOn a template engine's feature marker: the class that the generated view base derives fromNone
[TemplateContentType(contentType)]
string contentType
ClassHardened.Requests.Abstract.Templates in Hardened.Requests.AbstractOn a template engine's feature marker: the media type that views on that base produceNone

RazorTemplates is the marker that [Enable<RazorTemplates>] takes. It carries [TemplateBase(typeof(HardenedHtmlTemplate<>))] and [TemplateContentType("text/html; charset=utf-8")]. IHardenedResponseOutput is in Hardened.Requests.Abstract.Outputs.

Features ​

The table lists each type that [Enable<TFeature>] takes as TFeature.

TFeatureNamespace and packageTurns onPage
OpenApiDocumentPublishingHardened.Web.Runtime.OpenApi in Hardened.Web.RuntimeEmbeds the OpenAPI document written from the module's routes, and serves it at /openapi.jsonThe OpenAPI document
A class of your own with [OpenApiDocumentPath(path)]Your ownThe same, served at pathThe OpenAPI document
ConditionalGetHardened.Web.Runtime.Conditional in Hardened.Web.Runtime[ConditionalGet] on every GET handler in the applicationConditional requests
ResponseCompressionHardened.Web.Runtime.Compression in Hardened.Web.RuntimeCompression of every response in the applicationCompression
RequestTimeoutsHardened.Requests.Runtime.Filters in Hardened.Requests.RuntimeA 30-second budget for every handler that no nearer declaration boundsRequest timeouts
RazorTemplatesHardened.Templates.RazorBlade in Hardened.Templates.RazorBladeThe generated base class that the module's RazorBlade views inheritViews

The build reads [Enable<TFeature>] on the module class. [assembly: Enable<TFeature>] compiles and turns nothing on. The build also applies the registrations of a TFeature that is a module.

Testing ​

AttributeTargetsNamespace and packageWhat it doesPage
[ModuleTest]MethodDependencyModules.xUnit.Attributes in DependencyModules.xUnit, or in DependencyModules.xUnit4 for xunit.v3 4.xBuilds the application for the test method and supplies its parameters, under xUnit v3
xUnit's FactAttribute properties: DisplayName, Skip, SkipExceptions, SkipType, SkipUnless, SkipWhen (none), Explicit (false), Timeout (0)
Writing a test
[ModuleTest]MethodDependencyModules.NUnit.Attributes in DependencyModules.NUnitThe same, under NUnitWriting a test
[HardenedTestEntryPoint(entryPoint)]
Type entryPoint
Class, method, assemblyHardened.Shared.Testing.Attributes in Hardened.Shared.TestingNames the module each test buildsWriting a test
[EnvironmentName(name)]
string name
AnyHardened.Shared.Testing.Attributes in Hardened.Shared.TestingOn a test method, its class or the assembly: the name of the test's environment. Without it, testWriting a test
[EnvironmentValue(variable, value)]
string variable, string value
Class, method, assembly; repeatableHardened.Shared.Testing.Attributes in Hardened.Shared.TestingA variable in the test's environmentWriting a test
[WebTesting]AssemblyHardened.Web.Testing in Hardened.Web.TestingRegisters ITestWebApp, the test credential source, and a client for each test parameter of a client typeSending requests
[Grants(params grants)]
string[] grants
Class, method, parameter, assemblyHardened.Web.Testing in Hardened.Web.TestingSends the test's requests with these grants, in X-Test-GrantsSending requests
[Subject(subject)]
string subject
Class, method, parameter, assemblyHardened.Web.Testing in Hardened.Web.TestingSends the test's requests as this caller, in X-Test-SubjectSending requests
[Claim(name, value)]
string name, string value
Class, method, parameter, assembly; repeatableHardened.Web.Testing in Hardened.Web.TestingSends the test's requests with this claim, in X-Test-ClaimsSending requests
[Anonymous]Class, method, parameter, assemblyHardened.Web.Testing in Hardened.Web.TestingSends the test's requests with no credentialSending requests
[JwtTestIssuer]Class, method, assemblyHardened.Requests.Jwt.Testing in Hardened.Requests.Jwt.TestingMakes the application trust TestJwtIssuer's key in place of its JWKS, and registers TestJwtIssuer for the test to sign tokens withAuthentication
[PipelineHost]Class, method, assemblyHardened.Web.Testing in Hardened.Web.TestingRuns the test on the pipeline host, in the test's own call with no socket. ContainerPolicy = TestContainerPolicy.Reused sends every request of a test to the test's own containerTest hosts, One container for every request of every test
[KestrelTesting]Assembly; repeatableHardened.Web.Kestrel.Testing in Hardened.Web.Kestrel.TestingRuns a test that carries [KestrelRuntime] on Kestrel, on a loopback portTest hosts
[AspNetCoreTesting], [AspNetCoreTesting(composition)]
Type composition, an IAspNetCoreTestComposition
Assembly; repeatableHardened.Web.AspNetCore.Testing in Hardened.Web.AspNetCore.TestingRuns a test that carries [AspNetCoreRuntime] inside the ASP.NET Core pipeline, on Kestrel, on a loopback portTest hosts
[KiotaTesting]Assembly; repeatableHardened.Kiota.Testing in Hardened.Kiota.TestingMakes each Kiota client a test parameter, built over the test's hostTyped clients
[RefitTesting]Assembly; repeatableHardened.Refit.Testing in Hardened.Refit.TestingMakes each Refit interface a test parameter, built over the test's hostTyped clients
[TestClientRoute(routeType)]
Type routeType, an ITestClientRoute
Assembly; repeatableHardened.Web.Testing in Hardened.Web.TestingNames a route of your own that builds typed clients for the assembly's tests. [KiotaTesting] and [RefitTesting] derive from itTyped clients
[TestCredential]
No public constructor
Any; abstractHardened.Web.Testing in Hardened.Web.TestingThe base class of [Grants], [Subject], [Claim] and [Anonymous]None
[TestHost]
No public constructor
Class, method, assembly; abstractHardened.Web.Testing in Hardened.Web.TestingThe base class of an attribute that names a test's host, such as [PipelineHost]None
[TestHostProvider]
No public constructor
Assembly; repeatable; abstractHardened.Web.Testing in Hardened.Web.TestingThe base class of an attribute that names the host a runtime attribute on a test stands for, such as [KestrelTesting]None

The [ModuleTest] attributes come from DependencyModules. A test project references one runner package. The xUnit attribute derives from xUnit's FactAttribute. The NUnit attribute is an NUnit test builder. It has no settable property.

[KiotaTesting] and [RefitTesting] take their targets from TestClientRouteAttribute. [KestrelTesting] and [AspNetCoreTesting] take theirs from TestHostProviderAttribute. IAspNetCoreTestComposition is in Hardened.Web.AspNetCore.Testing. ITestClientRoute is in Hardened.Web.Testing.

The attributes in the next table come from DependencyModules. Hardened.Shared.Testing depends on DependencyModules.Testing 1.7.0. A test project references one of the three mock library packages itself. The hardened-web template's test project references DependencyModules.NSubstitute.

AttributeTargetsNamespace and packageWhat it doesPage
[Mock]Parameter; repeatableDependencyModules.Testing.Attributes in DependencyModules.TestingRegisters a test double for the parameter's type in the test's container, and passes it to the testSubstituting services
[Shared]ParameterDependencyModules.Testing.Attributes in DependencyModules.TestingOn a parameter that sends requests, such as ITestWebApp, HttpClient or a generated client: sends every request it makes to the test's own containerWriting a test
[TestExport(service)]
Type service
Class, method, assembly; repeatableDependencyModules.Testing.Attributes in DependencyModules.TestingRegisters a class of your own for every test it covers
Properties: Implementation (none), Lifetime (ServiceLifetime.Transient), Shared (false)
Substituting services
[NSubstituteSupport]Class, method, assemblyDependencyModules.NSubstitute in DependencyModules.NSubstituteMakes [Mock] build its doubles with NSubstituteSubstituting services
[MoqSupport]Class, method, assemblyDependencyModules.Moq in DependencyModules.MoqMakes [Mock] build its doubles with MoqSubstituting services
[FakeItEasySupport]Class, method, assemblyDependencyModules.FakeItEasy in DependencyModules.FakeItEasyMakes [Mock] build its doubles with FakeItEasySubstituting services

Triggers ​

AttributeTargetsNamespace and packageWhat it doesPage
[Queue(name)]
string name
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method a handler for the messages from a queue. Routes as QUEUE /{name}Triggers
[Topic(name)]
string name
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method a handler for the messages published to a topic. Routes as TOPIC /{name}Triggers
[Timer(name)]
string name
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method run each time a schedule fires. Routes as TIMER /{name}Triggers
[Event(source, detailType)]
string source, string detailType
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method a handler for an event from an event bus: source is who published it, detailType what happened. Routes as EVENT /{source}/{detailType}Triggers
[Change(name)]
string name
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method a handler for a row or document that changed. Routes as CHANGE /{name}Triggers
[Stream(name)]
string name
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method a handler for records from a sharded stream. Routes as STREAM /{name}Triggers
[Blob(name)]
string name
AnyHardened.Functions.Runtime.Attributes in Hardened.Functions.RuntimeMakes the method a handler for a notification that an object changed. Routes as BLOB /{name}Triggers
[HardenedFunction(functionName)]
string? functionName = null, which uses the method's name
AnyHardened.Requests.Abstract.Attributes in Hardened.Requests.AbstractMakes the method a handler for a direct invocation, whose caller gets the return value. Routes as INVOKE /{functionName}Triggers

The build reads the trigger attributes on a method. Hardened.Functions.Runtime references no cloud. The adapter package that the project references decides which cloud service each trigger receives from. AWS, Google Cloud and Azure name each adapter's module attribute.

Each cloud's adapter package registers its module from a build property. An application does not write the module attribute to get the adapter. It writes the attribute to change a setting, such as [SqsModule(ReportBatchItemFailures = true)].

Testing functions ​

AttributeTargetsNamespace and packageWhat it doesPage
[FunctionTesting]Class, method, assemblyHardened.Functions.Testing in Hardened.Functions.TestingMakes the trigger façades test parameters. A test sends messages to its handlers through themTesting functions
[PipelineDelivery]Class, methodHardened.Functions.Testing in Hardened.Functions.TestingPuts the tests it covers back on the neutral delivery, where the assembly declares a cloud's testing attributeTesting functions
[LambdaTesting]Class, method, assemblyHardened.Aws.Lambda.Testing in Hardened.Aws.Lambda.TestingDelivers each façade call through the function's LambdaInvocationHandler, as the AWS eventAWS Testing
[CloudRunTesting]Class, method, assemblyHardened.Gcp.CloudRun.Testing in Hardened.Gcp.CloudRun.TestingBuilds each façade call into the request its Google Cloud source sendsGoogle Cloud Testing
[AzureFunctionsTesting]Class, method, assemblyHardened.Azure.Functions.Testing in Hardened.Azure.Functions.TestingBuilds each façade call into the trigger data the isolated worker receivesAzure Testing

Without a cloud's testing attribute, a façade call is built as a request. The request runs the pipeline with no envelope and no host. The hardened-function template's test project declares [assembly: FunctionTesting] and the chosen cloud's attribute.

AWS ​

AttributeTargetsNamespace and packageWhat it doesPage
[LambdaHttpModule]Module attributeHardened.Aws.Lambda.Http in Hardened.Aws.Lambda.HttpServes the routes from Lambda, behind an API Gateway HTTP API or a function URLAWS Web applications
[InvokeModule]Module attributeHardened.Aws.Lambda.Invoke in Hardened.Aws.Lambda.InvokeThe adapter for [HardenedFunction], invoked directlyAWS Invocations
[SqsModule]Module attributeHardened.Aws.Lambda.Sqs in Hardened.Aws.Lambda.SqsThe adapter for [Queue], from Amazon SQS
Property: ReportBatchItemFailures (false)
AWS Queues
[SnsModule]Module attributeHardened.Aws.Lambda.Sns in Hardened.Aws.Lambda.SnsThe adapter for [Topic], from Amazon SNSAWS Topics
[EventBridgeModule]Module attributeHardened.Aws.Lambda.EventBridge in Hardened.Aws.Lambda.EventBridgeThe adapter for [Timer] and [Event], from Amazon EventBridgeAWS Overview
[DynamoDbStreamsModule]Module attributeHardened.Aws.Lambda.DynamoDb in Hardened.Aws.Lambda.DynamoDbThe adapter for [Change], from DynamoDB Streams
Property: ReportBatchItemFailures (false)
AWS Changes
[NewImage]ParameterHardened.Aws.Lambda.DynamoDb in Hardened.Aws.Lambda.DynamoDbBinds the row as it is after the change, in DynamoDB's own form, type tags and allAWS Changes
[OldImage]ParameterHardened.Aws.Lambda.DynamoDb in Hardened.Aws.Lambda.DynamoDbBinds the row as it was before the change, in DynamoDB's own form, type tags and allAWS Changes
[KinesisModule]Module attributeHardened.Aws.Lambda.Kinesis in Hardened.Aws.Lambda.KinesisThe adapter for [Stream], from Kinesis Data Streams
Property: ReportBatchItemFailures (false)
AWS Streams
[S3Module]Module attributeHardened.Aws.Lambda.S3 in Hardened.Aws.Lambda.S3The adapter for [Blob], from S3 object notificationsAWS Blobs
[LambdaRuntimeModule]Module attributeHardened.Aws.Lambda.Runtime.Modules in Hardened.Aws.Lambda.RuntimeThe invocation loop that every Lambda function runs. Every adapter's module imports itAWS Overview
[LambdaWebTesting]Class, method, assemblyHardened.Aws.Lambda.Testing in Hardened.Aws.Lambda.TestingRuns web tests through the function's LambdaInvocationHandler, as API Gateway payload format 2.0 events
Property: ResponseMode (LambdaResponseMode.Buffered)
AWS Testing
[DynamoDbClientModule]Module attributeHardened.Aws.DynamoDbClient in Hardened.Aws.DynamoDbClientRegisters IDynamoDbClientProvider, on any hostDynamoDB client
[LocalDynamoDb]AnyHardened.Aws.DynamoDbClient.Testing in Hardened.Aws.DynamoDbClient.TestingOn a test: points IDynamoDbClientProvider at DynamoDB Local in a Docker container. A derived class creates the tables
Property: Image (amazon/dynamodb-local:latest)
DynamoDB client

LambdaResponseMode is in Hardened.Aws.Lambda.Runtime.Streaming. Its values are Buffered, Stream and Mixed. [LambdaTesting] is under Testing functions.

Google Cloud ​

AttributeTargetsNamespace and packageWhat it doesPage
[CloudRunRuntime]Module attributeHardened.Gcp.CloudRun.Runtime in Hardened.Gcp.CloudRun.RuntimeRuns the application as a Cloud Run service on Kestrel, and serves trigger handlers beside the routesWeb services
[InvokeModule]Module attributeHardened.Gcp.CloudRun.Invoke in Hardened.Gcp.CloudRun.InvokeThe adapter for [HardenedFunction], invoked by a POST to the service
Property: Prefix (/_triggers/invoke/)
Google Cloud Invocations
[PubSubModule]Module attributeHardened.Gcp.CloudRun.PubSub in Hardened.Gcp.CloudRun.PubSubThe adapter for [Queue], from a Pub/Sub push subscription, and [Topic], from an Eventarc trigger on a Pub/Sub topicGoogle Cloud Overview
[SchedulerModule]Module attributeHardened.Gcp.CloudRun.Scheduler in Hardened.Gcp.CloudRun.SchedulerThe adapter for [Timer], from a Cloud Scheduler job
Property: Prefix (/_triggers/timer/)
Google Cloud Timers
[EventarcModule]Module attributeHardened.Gcp.CloudRun.Eventarc in Hardened.Gcp.CloudRun.EventarcThe adapter for [Event], any CloudEvent that Eventarc deliversGoogle Cloud Events
[FirestoreModule]Module attributeHardened.Gcp.CloudRun.Firestore in Hardened.Gcp.CloudRun.FirestoreThe adapter for [Change], from Firestore through EventarcGoogle Cloud Changes
[OldValue]ParameterHardened.Gcp.CloudRun.Firestore in Hardened.Gcp.CloudRun.FirestoreBinds the document as it was before the changeGoogle Cloud Changes
[StorageModule]Module attributeHardened.Gcp.CloudRun.Storage in Hardened.Gcp.CloudRun.StorageThe adapter for [Blob], from Cloud Storage through Eventarc or a Pub/Sub notificationGoogle Cloud Blobs

[CloudRunRuntime] imports [KestrelRuntime]. The Cloud Functions host runs a [CloudRunRuntime] application. It has no attribute of its own. The two Prefix defaults are InvokeEnvelope.DefaultPrefix and SchedulerEnvelope.DefaultPrefix. They apply when the attribute leaves Prefix unset. [CloudRunTesting] is under Testing functions.

Azure ​

AttributeTargetsNamespace and packageWhat it doesPage
[HttpModule]Module attributeHardened.Azure.Functions.Http in Hardened.Azure.Functions.HttpServes the routes from Azure Functions, through one HTTP function named HttpAzure Web applications
[ServiceBusModule]Module attributeHardened.Azure.Functions.ServiceBus in Hardened.Azure.Functions.ServiceBusThe adapter for [Queue], from a Service Bus queue, and [Topic], from a subscription of a Service Bus topic
Properties: Connection (unset: the app setting AzureWebJobsServiceBus), ReportsItemFailures (false), Subscription (unset; a [Topic] handler needs it)
Azure Queues
[TimerModule]Module attributeHardened.Azure.Functions.Timer in Hardened.Azure.Functions.TimerThe adapter for [Timer], from a timer triggerAzure Timers
[EventGridModule]Module attributeHardened.Azure.Functions.EventGrid in Hardened.Azure.Functions.EventGridThe adapter for [Event], from Event Grid in the CloudEvents schemaAzure Events
[CosmosDbModule]Module attributeHardened.Azure.Functions.CosmosDb in Hardened.Azure.Functions.CosmosDbThe adapter for [Change], from the Cosmos DB change feed
Properties: Database (required), Connection (unset: the app setting CosmosDB), LeaseContainer (unset: leases), RetryCount and RetryDelay (unset: no retry policy)
Azure Changes
[EventHubsModule]Module attributeHardened.Azure.Functions.EventHubs in Hardened.Azure.Functions.EventHubsThe adapter for [Stream], from Event Hubs
Properties: Connection (unset: the app setting AzureWebJobsEventHubs), ConsumerGroup (unset: $Default), RetryCount and RetryDelay (unset: no retry policy)
Azure Streams
[BlobsModule]Module attributeHardened.Azure.Functions.Blobs in Hardened.Azure.Functions.BlobsThe adapter for [Blob], from Blob Storage through Event Grid
Property: Connection (unset: the app setting AzureWebJobsStorage)
Azure Blobs
[FunctionsRuntimeModule]Module attributeHardened.Azure.Functions.Runtime.Modules in Hardened.Azure.Functions.RuntimeRuns each invocation. Every adapter's module imports itAzure Overview
[AzureFunctionsWebTesting]Class, method, assemblyHardened.Azure.Functions.Testing in Hardened.Azure.Functions.TestingRuns web tests through the app's FunctionsInvocationHandler, with no Functions hostAzure Testing

The Azure build reads the module attributes' settings from the application class. It writes them into the function metadata. [CosmosDbModule] without Database fails the build with HRDAZ003. A [Topic] handler fails the build with the same diagnostic when [ServiceBusModule] sets no Subscription.

When Connection is unset, the build names no connection for Service Bus, Cosmos DB and Blob Storage. The Azure extension's default setting then applies. For Event Hubs the build writes AzureWebJobsEventHubs. The defaults AzureWebJobsServiceBus, CosmosDB, leases, $Default and AzureWebJobsStorage are the Azure extensions' own.

[AzureFunctionsTesting] is under Testing functions.

Limits ​

On a [HardenedModule] class, an attribute with an enum argument or enum property set to a value other than the enum's zero value fails the build. The error is in the generated <Module>.Module.g.cs. It is CS1503 for a constructor argument and CS0266 for a named property. These attributes fail the build on a module class with the values shown:

Attribute on the module classError
[ContentNegotiation(ContentNegotiationMode.Lenient)]CS1503
[ResponseModel(ResponseModel.Response)]CS1503
[ValidationMode(ValidationStopMode.StopOnFirstError)]CS1503
[RateLimit(Scope = RateLimitScope.Principal)]CS0266
[Compress(Favor = CompressionType.Br)]CS0266
[CacheControl(Type = CacheControlEnum.NoStore)]CS0266
[CacheResponse<VaryByRoute>(Scope = CacheScope.PerCaller)]CS0266

The filter attributes in the table compile with the same values off the module. [RateLimit] compiles with its value on a controller class. [Compress], [CacheControl] and [CacheResponse<TProvider>] compile with theirs on a handler method. [ValidationMode] compiles with StopOnFirstError on either. [RateLimit(Scope = RateLimitScope.Transport)] sets the zero value and compiles on the module class.

[ContentNegotiation] sets nothing in either placement it accepts. Lenient on a module class fails the build. On an assembly the attribute has no effect.

Next ​

  • Modules: module attributes, imports and module properties
  • The execution pipeline: filter attributes on a method, a class or a module, and writing your own
  • Triggers: the trigger attributes and the adapter on each cloud
  • Packages: every package and what it ships
  • Diagnostics: the build's diagnostics, such as HRDR004 and HRDAZ003

Released under the MIT License.