Covers simple scenario for each model binder.
Covers scenarios mixing a POCO model binder -> Simple Model binder.
This contains tests for
FormCollectionModelBinder
BinderTypeBasedModelBinder
TypeConverterModelBinder
Remainging:
TypeMatchModelBinder
This also adds missing unit test for TypeMatchModelBinder as well.
Creates a new package 'Microsoft.AspNet.Mvc.Abstractions' which defines
APIs and contracts for core concepts and extensibility points in MVC.
Includes:
- ModelBinding
- Validation
- Model State
- Model Metadata
- Action Descriptors
- IActionResult
- Filters
- IActionConstraint
- part 1/2 of #2294
- handle readonly non-`null` collections in relevant binders
- `CollectionModelBinder.CopyToModel()` and `MutableObjectModelBinder.AddToProperty()` methods
- handle read-only controller properties in `DefaultControllerActionArgumentBinder`
- do not copy into arrays e.g. add `CopyToModel()` override in `ArrayModelBinder`
- remove ability to set a private controller property
- confirm `SetMethod.IsPublic` in `DefaultControllerActionArgumentBinder`
- avoid NREs in `GetModel()` overrides
Test handling of readonly collections
- previous tests barely touched this scenario
- also add more tests setting controller properties
nits:
- add missing `[NotNull]` attributes
- add missing doc comments
- consolidate a few `[Fact]`s into `[Theory]`s
- simplify some wrapping; shorten a few lines
- remove dead code in `DefaultControllerActionArgumentBinder` and `ControllerActionArgumentBinderTests`
The fix splits client validation and model validation into two separate hierarchies.
Introduced ClientModelValidatorProvider in MvcOptions, which can be iterated to produce IClientModelValidators.
As a result of this, HtmlGenerator code can be free of ActionBindingContext and directly consumes options.
This also means that we do not modify the client validations during resource filters.
- #2261
- include `short`, `ushort`, `float`, `double`
- correct typo in `<input/>` tag helper; ignored calculated format
- only one test for `<input/>`'s calculated format 😦
- fill some `Editor*()` and `<input/>` tag helper test gaps
nit: clean up some trailing whitespace
- add `IHtmlGenerator.GetCurrentValues()` method
- bring together bits of `GenerateSelect()` and `UpdateSelectListItemsWithDefaultValue()`
- get rid of ugly `out` parameter
- also allows `<option/>` tag helpers to run before `<select/>` helper generation
- match `null` values and `SelectListItem`s with empty values
- match `enum` names correctly
- add doc comments for `IHtmlGenerator.GenerateSelect()` methods
This change removes reflection from validator providers, and instead
relies on cached metadata in in the modelmetadata.
In general this means that our MVPs don't need to cache anything, they
just look at the metadata and create what they need.
In the case of data-annotations, we update the model details provider to
add validation attributes to the modelmetadata. This would allow someone
to replace the DataAnnotationsValidatorProvider, but still use the
metadata in these attributes.
The change to the IModelValidatorProvider api (to use a context) is
intended to minimize allocations. Currently each validator provider needs
to return a list so you end up with N+1 lists (N validators + a final list
to compine them all). This change will let us just create the final list
(and a small context object). This is a very very high traffic API so it
seemed worth doing.
There's also some general massaging of namespaces and file locations.
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