The change here is to make an attribute route defined on a base class
inherited only if no other routes were defined 'closer' to the controller
class.
To put another way, attribute routes can either be inherited or
overridden, you can't inherit + add your own.
This change allows you to set global defaults for ApiExplorer on the
ApplicationModel. Additionally, we're more lenient about configuring
ApiExplorer = on with conventional routing. If you turn on ApiExplorer at
the application level, we'll just skip over all conventionally routed
controllers instead of throwing.
This change makes ApiDescription and ApiParameterDescription aware of all
of the new features we built into model binding for enhanced DTO support
(uber-binding).
The main change is that instead of sticking just to the declared
parameters on the action itself, we now traverse model metadata and break
the parameters down based on their logical data source.
This means that a model like the below will yield 3 parameters:
public class ProductChangeCommandDTO
{
public int Id { get; set; }
[FromBody]
public ProductDetails Changes { get; set; }
[FromQuery]
public string AdminComments { get; set; }
[FromServices]
public IProductRepository Repository { get; set; }
}
The 'Repository' will be hidden, as it's not related to user input.
Additionally, we treat different sources differently. In the
above example, 'Changes' is from the body and will be treated as a
leaf-node.
However if you use nested DTOs that are bound from the query string (using
[FromQuery]) or similar, we'll recursively explore to find as much
structure as possible.
This information is combined with data from the route template to give a
much more complete picture than we ever could in the past for parameters,
especially when DTO/Command pattern is used.
The ParameterModel and ParameterDescriptor have had a notion of
optionality for a while now, even though all parameters are treated as
'optional' in MVC.
This change removes these settings. Optionality for overloading in webapi
compat shim is reimplemented via a new binder metadata.
This change adds an interface for the functionality provide by
RouteConstraintAttribute, and adds support for configuration constraints
on actions/action-model.
This change enables some compatibility scenarios with MVC 5 by expanding
the set of legal ways to configure attribute routing. Most promiently, the
following example is now legal:
[HttpPost]
[Route("Products")]
public void MyAction() { }
This will define a single action that accepts POST on route "Products".
See the comments in #1194 for a more detailed description of what changed
with more examples.
Taking the suggestion here to move these to a sub-object. This is future
proof in the event that we need to capture more data for ApiExplorer, and
reads better.
This also comes with a rename of the namespace
Microsoft.AspNet.Mvc.ApplicationModel to
Microsoft.AspNet.Mvc.ApplicationModels.
Also tuned up some parameter and variable names for increased
understandability.