-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Background and Motivation
Background on this issue can be found in this comment.
Proposed API
// Assembly: Microsoft.AspNetCore.Mvc.Abstractions;
namespace Microsoft.AspNetCore.Mvc.ModelBinding;
public abstract class ModelMetadata : IEquatable<ModelMetadata?>, IModelMetadataProvider
{
+ protected ModelMetadata(Type type, IParameterBindingMetadata? parameterBindingMetadata)
}
Usage Examples
This API is primarily intended for consumption within the EndpointMetadataApiDescriptionProvider
to construct the ModelMetadta
implementation that is a required part of ApiExplorer metadata.
aspnetcore/src/Mvc/Mvc.Abstractions/src/ApiExplorer/ApiParameterDescription.cs
Lines 7 to 17 in a21c9ed
namespace Microsoft.AspNetCore.Mvc.ApiExplorer; | |
/// <summary> | |
/// A metadata description of an input to an API. | |
/// </summary> | |
public class ApiParameterDescription | |
{ | |
/// <summary> | |
/// Gets or sets the <see cref="ModelMetadata"/>. | |
/// </summary> | |
public ModelMetadata ModelMetadata { get; set; } = default!; |
For the minimal API-based implementaton of ApiDescriptionProvider, there is a custom EndpointModelMetadtata
class that extends the abstract ModelMetadata
class that we are modifying:
aspnetcore/src/Mvc/Mvc.ApiExplorer/src/EndpointModelMetadata.cs
Lines 12 to 18 in 6812d1d
internal sealed class EndpointModelMetadata : ModelMetadata | |
{ | |
public EndpointModelMetadata(Type type, IParameterBindingMetadata? parameterBindingMetadata) : base(type, parameterBindingMetadata) | |
{ | |
IsBindingAllowed = true; | |
} | |
For a complete example of how these APIs are used, see aa3ac70.
Alternative Designs
- Implement ApiExplorer abstraction layer with no MVC dependencies 😛
- Cry 😭
- Shift
ModelMetadata
s use ofParameterBindingCache
to the concreteDefaultModelMetadata
implementation
Risks
The current shape of this change introduces a regression for scenarios where we generate ModelMetadata
for responses or request bodies annotated with Accepts
. Unlike parameters, where we can take advantage of the IParameterBindingMetadata
that we introduced earlier, there is no similar abstraction layer for response types/accepts metadata. This means that EndpointModelMetadata
generated for these will not have information about whether a type is parseable or complex.
We could solve this in one of two ways:
- Introduce metadata similar to
IParameterBindingMetadata
for responses and accepts metada and introduce new constructs onModelMetadata
that consume this metadata - Call it what it is and document this is a breaking change in the API
I lean slightly towards the later option here -- it's cheaper and we can always revisit and approach #2 if we discover that there were libraries that were taking advantage of ModelMetadata
for responses in the minimal API-based API explorer.