Separates the MMP into two phases:
1). Creation of the ModelMetadata, discovery of properties and attributes
(reflection) is part of the MMP
2). Lookup of details based on attributes is now part of another phase,
and has its results cached.
Users can now implements and register an IFooMetadataProvider to customize
a single aspect of metadata (see how data annotations does it).
- #1468
- Always use `ModelExplorer` in `<select/>`, `DropDownListFor()` and `ListBoxFor()` cases
- allows evaluation of more-complex expressions
- Use `ViewData.Model` in `DropDownList()` and `ListBox()` template cases
- `ViewData` was previously ignored in these cases
nit: change `ViewDataDictionary.Eval()` to return `Model` if `expression` is `null` or empty
- now `throw` on `null` or empty `expression` name in `ViewDataEvaluator.Eval()`
- simplifies some of the higher-level code
- no change to `selectList` fallback; `Model` incorrect for that case
- no change to `GenerateRadioButton()`; would change behaviour unrelated to #1468
- this helper uses incorrect `ViewData` lookup text, see #1487
- #944
- name `string` expression name and `Expression<Func<TModel, TResult>>`
parameters "expression"
- single special case is `GenerateIdFromName(string fullName)` since every
other expression name is relative to the current
`ViewData,TemplateInfo.HtmlFieldPrefix` value
- applied from `IHtmlHelper` and `IHtmlGenerator` on up
- name `IHtmlHelper` and `IHtmlHelper<TModel>` parameters "htmlHelper"
- rename `TProperty` and `TValue` type parameters to `TResult`
nits:
- clean up abbreviated names in `CachedExpressionCompiler`
- change `ObjectToDictionary()`'s parameter name to `value`
- use `nameof` more to make renaming (and refactoring) easier in the future
- rewrap parameters and arguments to avoid long lines and orphans
This also fixes#1503.
Currently all model binders except mutable object binder are independent of validation code. The mutable object binder which needs to do some validation ( for scenarios involving [BindRequired] and [BindNever]).
We would be going with an approach where required validaiton happens in input formatters and model binders.
This is needed as validation for value types can best be done at creation time.
Followup PRs:
Introduce support for skipping validation (and not binding) for a particular property/type etc.
- #524
- add tests of `DropDownList` and `ListBox` HTML helpers
- extend tests of `<select/>` tag helper
- add scenario to a functional test
New `HtmlHelperSelectTest` does not cover everything. In future (see #453):
- use non-`null` `optionLabel` and `htmlAttributes` arguments
- confirm value sources and their priorities
- mock an `IHtmlGenerator` and confirm how it is called
- mock an `IHtmlHelper` and confirm how extension methods call that
- correct typo in 3303286288
- really seal `CachedModelMetadata.Properties`
- make a couple of test methods `public` (!!)
- add Microsoft.AspNet.PageExecutionInstrumentation to Mvc.sln
- remove `<RootNamespace/>`, `<ProjectExtensions/>`, etc. from .kproj files
services
* Added WithControllersFromServiceProvider that replaces the default
controller activator with a service based one.
* Move activation to DefaultControllerFactory
* Modify [Activate] behavior so that it no longer activates services. Use
[FromService] attribute to hydrate services
Fixes#1707
Attribute route link generation will now have a slight preference for
entries that can use ambient values (vs ignoring an ambient value). This
means that areas will be more 'sticky' with regard to link generation
without the need to specify a better Order.
This change makes the attribute route capable of responding to updates in
the action descriptor collection.
The change moves the actual route implementation to InnerAttributeRoute.
AttributeRoute now wraps an InnerAttributeRoute - when processing a route,
AttributeRoute will now check with action descriptor collection if its
InnerAttributeRoute is still 'current' and rebuild it if necessary.
This is a major refactor of how IBinderMetadata interacts with model
binders and value providers. We're doing this to support better
extensibility for metadata in ApiExplorer.
You'll notice a bunch of deleted code in DefaultApiDescriptionProvider
that maps metadata marker interfaces to a fixed list of Api sources. This
is replaced now with IBindingSourceMetadata - which also replaces the
hierarchy of marker interfaces. Now user code can create an arbitrary
binding source and have a consistent API for model-binders,
value-providers and full-visibility in ApiExplorer as
well.
Additonally, there's some error checking in place that better enforces the
constraints we already have in the system. IE you can't create a 'greedy'
model binder that uses value-provider data.
Two additional enhancements are planned for followup PRs:
1. Add a BindingSource property to model-metadata. This will remove some
duplication, but I want to delay it because it would touch another 10 or
so files.
2. Add an extensibility interface for our 'special' model binders like the
file binder so these can show up in ApiExplorer as well.