-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for argument list surrogates in minimal APIs #40712
Comments
Thanks for contacting us. We're moving this issue to the |
I suspect its fairly common for a number of API method to support a common set/subset of options/properties. Being able to do something akin to: |
It feels like there is an overlap between this functionality and that supported by the IModelBinder interface. The primary difference being the class is based declarative automatic generation of the fields based as opposed to being generated via bespoke code. I guess one potential approach to implementation would be to use the [Properties] attribute on the class as a trigger to the complier to auto generate the code to add a default implementation of the IModelBinder interface on the given class. Provision for this might also result in simpler/cleaner code for cases where IModelBinder may currently be required/used. |
Proposed APIAdd new namespace Microsoft.AspNetCore.Http;
+[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
+public sealed class ParametersAttribute : Attribute
+{ } The idea is supporting the attribute in multiples parameters and also mixed with parameters without the atrribute. Usage ExamplesAttribute specified in the delegate parameterapp.MapGet("/products/{id}", ([Parameters]ProductRequest req, [Parameters]Paging pageInfo) =>
{
return req.Db.Products.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize);
});
public record ProductRequest(int Id, ILogger<Program> Logger, MyDb Db);
public record Paging(int PageSize, int Page); or app.MapGet("/products/{id}", (int id, ILogger<Program> logger, MyDb db, [Parameters]Paging pageInfo) =>
{
return req.Db.Products.Skip((req.Page - 1) * req.PageSize).Take(req.PageSize);
});
public record Paging(int PageSize, int Page); Alternative DesignsAs an alternative design, we could also create a public interface (marker). namespace Microsoft.AspNetCore.Http.Metadata;
+public interface IFromParametersMetadata
+{} namespace Microsoft.AspNetCore.Http;
+[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
+public sealed class ParametersAttribute : Attribute, IFromParametersMetadata
+{ } That will allow users to create their own attribute implementation, as we have for |
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
I'm not sure that I like how generic This is going to be in a global using by default as part of the I know what we're really trying to indicate is that the properties of the parameter are treated as a top-level parameter and that it's hard to communicate this in a reasonably short attribute name though. Maybe |
I was waiting for this ugly name discussion 😄. I agree parameters is too generic. I can't wait to 🚲 shed on this. |
Some additional name ideas:
|
API review notes:
API Approved! namespace Microsoft.AspNetCore.Http;
+[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
+public sealed class AsParametersAttribute : Attribute
+{ }
namespace Microsoft.AspNetCore.Mvc;
-[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
+[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FromServicesAttribute : Attribute, IBindingSourceMetadata, IFromServiceMetadata |
Does this feature work in MVC? If not, are there any plans to add it? It seems like the idea can be applied to both frameworks. |
Issue for adding support to MVC: #42271 |
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
The idea here is to support using a type that can act like a surrogate for the argument list in a minimal API. The motivation is about refactoring a minimal API that takes a large set of parameters into one that takes a single object with top level properties that represent what were once arguments. This is a common pattern seen with CQRS frameworks where a request object is made to bind all inputs.
Describe the solution you'd like
The user wishes to refactor this to:
The parameter or type needs to be marked explicitly to identify that this is not from the body or elsewhere (query etc). These properties should also support binding attributes:
This would only work for top level properties in this object.
Additional context
Open questions:
The text was updated successfully, but these errors were encountered: