-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Closed
Labels
Priority:2Work that is important, but not critical for the releaseWork that is important, but not critical for the releaseapi-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labelstriage-focusAdd this label to flag the issue for focus at triageAdd this label to flag the issue for focus at triage
Milestone
Description
Background and Motivation
Now that C# supports generic attributes as of version 10/.NET 6, we should look through ASP.NET Core and consider adding generic versions of any attributes that accept type parameters (e.g. ConsumesAttribute).
Proposed API
namespace Microsoft.AspNetCore.Mvc;
//Original: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ModelMetadataTypeAttribute.cs
+[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+public class ModelMetadataTypeAttribute<TType> : ModelMetadataTypeAttribute
+{
+ public ModelMetadataTypeAttribute() : base(typeof(TType))
+ { }
+}
// Original: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/Filters/MiddlewareFilterAttribute.cs
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+public class MiddlewareFilterAttribute<TConfigurationType> : MiddlewareFilterAttribute
+{
+ public MiddlewareFilterAttribute() : base(typeof(TConfigurationType))
+ { }
+}
// Original: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ServiceFilterAttribute.cs
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+[System.Diagnostics.DebuggerDisplay("ServiceFilter: Type={ServiceType} Order={Order}")]
+public class ServiceFilterAttribute<TFilterType> : ServiceFilterAttribute
+ where TFilterType : IFilterMetadata
+{
+ public ServiceFilterAttribute() : base(typeof(TFilterType))
+ { }
+}
// Original: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ModelBinderAttribute.cs
+[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
+public class ModelBinderAttribute<TBinderType> : ModelBinderAttribute
+ where TBinderType : IModelBinder
+{
+ public ModelBinderAttribute() : base(typeof(TBinderType))
+ { }
+}
// Original: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ProducesAttribute.cs
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+public class ProducesAttribute<TType> : ProducesAttribute
+{
+ public ProducesAttribute() : base(typeof(TType))
+ { }
+}
// Original: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ProducesResponseTypeAttribute.cs
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+public class ProducesResponseTypeAttribute<TType> : ProducesResponseTypeAttribute
+{
+ public ProducesResponseTypeAttribute(int statusCode) : base(typeof(TType), statusCode)
+ { }
+ public ProducesResponseTypeAttribute(int statusCode, string contentType, params string[] additionalContentTypes)
+ : base(typeof(TType), statusCode, contentType, additionalContentTypes)
+ { }
+}
In addition to what listed above the original list (#37767 (comment)) contains:
src/Mvc/Mvc.Razor/src/Compilation/RazorViewAttribute.cs:
13: public class RazorViewAttribute : Attribute
src/Razor/Microsoft.AspNetCore.Razor.Language/src/ProvideRazorExtensionInitializerAttribute.cs:
9: public class ProvideRazorExtensionInitializerAttribute : Attribute
RazorViewAttribute is marked as obsolete, so, I don't think we need to do anything (cc @mkArtakMSFT in case you want to have it added).
Also, ProvideRazorExtensionInitializerAttribute is not part of the ASPNET.Core repo anymore.
Usage Examples
[ProducesResponseType<ValidationProblemDetails>(StatusCodes.Status400BadRequest)]
[ProducesResponseType<Todo>(StatusCodes.Status201Created)]
[EndpointName(nameof(AddTodo))]
[Tags("TodoApi")]
async Task<IResult> AddTodo(Todo todo, TodoDb db)
{
if (!MiniValidator.TryValidate(todo, out var errors))
return Results.ValidationProblem(errors);
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.Created($"/todos/{todo.Id}", todo);
}Alternative Designs
Risks
Very small, this will introduce new types derived from the non-generic ones.
nil4, hez2010, Hellevar, TanvirArjel, ShreyasJejurkar and 7 more
Metadata
Metadata
Assignees
Labels
Priority:2Work that is important, but not critical for the releaseWork that is important, but not critical for the releaseapi-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labelstriage-focusAdd this label to flag the issue for focus at triageAdd this label to flag the issue for focus at triage