- #2941
- honor `ModelBindingResult.IsModelSet` and use `ModelBindingResult.ValidationNode`
- enable correct validation of collections or after model binding falls back to the empty prefix
- code previously matched `Controller.TryValidateModel()`; less context available in that case
- #2836
Part 1: Use existing property values when recursing in `MutableObjectModelBinder`
- remove `ComplexModelDTO` because that indirection made fixing this issue more difficult and doesn't add value
- started with an old closed PR (#2241) which did some of this work
- correct `MutableObjectModelBinderTest` tests that exercised behaviour that can't occur
- the old `dto.Results` dictionary was never incomplete; nor could it contain `null` values
Part 2: Change `MutableObjectModelBinder` to pass complex property values into binding system
- model binding no longer trounces nodes in the model tree that aren't bound
- create model instances less often in `TryUpdateModel` scenarios
- refactor `EnsureModel()` to `GetModel()` and use appropriately
- reorder logic in `SetProperty()` and `AddToProperty()` to avoid copying to / from the same collection
- also cleans up some code duplication
nits:
- clean up `MutableObjectModelBinderTest`
- fix odd line wrappings and indentation
- use `nameof()` more
- use `string.Empty` more
- simplify a couple of `Returns()` expressions
- make assertions in `TryUpdateModelIntegrationTest` more readable
- no need to work through `ModelStateDictionary.Keys`
- also use `Length` instead of `Count()`; test code but we don't need Linq at all in that test class
some more tests.
This change reverts the behavior change from
a6ce9abab1 and adds more tests around the
scneario that was actually broken.
The right behavior is that unconvertable values result in a validation
error. There's no special behavior around value types and required values.
This change restores a link generation behavior from MVC5 and earlier
where 'action' and 'controller' values are special cased-when using
Url.Action(...).
The change is that in-effect 'action' and 'controller' are always included
in the route values given to the routing system. Passing a null value into
the Url.Action(...) method means that the ambient value for that token
should be used explicitly. This means that the 'action' and 'controller'
tokens become sticky, even when something to the lexical left in the URL
(like area) changes.
ActionBindingContext
This change replaces IScopedInstance<T> in favor or IActionContextAccessor
and IActionBindingContextAccessor. In the spirit of IHttpContextAccessor,
these are both singletons which use AsyncLocal for storage.
This change allows the invoker factory to be cached which results in some
significant perf gains.
- #2633
- do not leave `ModelBindingResult.ValidationNode` as `null` when we hit the `null` `RawValue` special case
- move two bits of code together to make the special case more obvious
- add `ModelValidationNode` (that suppresses validation) when `HttpRequestMessageModelBinder` is successful
- also suppress validation of `HttpRequestMEssage` properties
- suppress validation in `CancellationTokenModelBinder`, `FormCollectionModelBinder`, `FormCollectionModelBinder`
- do not create a `ModelValidationNode` when validation fails in `TypeConverterModelBinder`
nits:
- improve some doc comments
- add a quick `HttpRequestMessageModelBinderTest`
- #2793
- add `ICollectionModelBinder`, allowing `GenericModelBinder` to call `CreateEmptyCollection()`
- adjust `CollectionModelBinder` and `DictionaryModelBinder` to activate model if default types are incompatible
- do not create default (empty) top-level collection in fallback case if Model already non-`null`
- change type checks in `GenericModelBinder` to align with `CollectionModelBinder` capabilities
- add special case for `IEnumerable<T>`
- correct `ModelMetadata` of a few tests that previously did not need that information
This change moves the responsibility for saving TempData into a filter,
which is registered with other View features. This moves TempData into the
ViewFeatures package.
ActionResults which require TempData to be kept use a new marker interface
which is handled by the filter.
- #2907
- return `null` if `Filter()` finds no matching value provider in collection
- fix lack of defensiveness in model binders' use of `IBindingSourceValueProvider` implementations
- remove test workaround for unusual `CompositeValueProvider` behaviour
- #2705
- add `JQueryFormValueProvider` and `JQueryFormValueProviderFactory`
- carry some code forward from MVC 5; correct to follow current coding guidelines
- refactor `ReadableStringCollectionValueProviderTest` into abstract `EnumerableValueProviderTest`
- enables reuse in new `JQueryFormValueProviderTest`
- also run these tests in `CompositeValueProviderTest`
nits:
- do not create a duplicate `CompositeValueProvider` instance in `Filter()`
- correct garbled sentence in `IBindingSourceValueProvider` doc comments
- simplify `FormValueProviderFactoryTest` (no need for Moq) and correct test name
- correct test class / file names
- `CompositeValueProviderTests` -> `CompositeValueProviderTest`
- `FormValueProviderFactoryTests` -> `FormValueProviderFactoryTest`
- Razor removed the ability to automatically resolve URLs prefixed with `~/`; therefore `ScriptTagHelper`, `LinkTagHelper` and `ImageTagHelper` have changed to take in `IUrlHelper`s and auto-resolve their URL based properties if they start with `~/`.
- Added a catch-all `~/` resolver for non `TagHelper` based HTML elements. Razor used to resolve any attribute value that started with `~/` now the behavior is restricted to attributes that can contain URLs.
- Updated `IUrlHelper` to accept `null` values.
- Added functional tests to validate that URLs resolve correctly.
- Updated `TagHelper` tests to ensure that URLs are resolved via an `IUrlHelper`.
#2807
For a typical configuration, it's now possible to cast a parameter
descriptor to ControllerParameterDescriptor or
ControllerBoundPropertyDescriptor to access the corresponding reflection
type.
- #2825
- new class names align with existing types such as `HttpNotFoundResult` and `HttpNotFoundObjectResult`
- remove similar types from WebApiCompatShim and use replacements in `ApiController`
- `NegotiatedContentResult<T>` remains because Core doesn't have an exact replacement
nits:
- add missing periods in some `Controller` doc comments
- #1418
- add new fallback binding in `DictionaryModelBinder`
- similar to MVC 5 approach but more explicit and with better key conversion support
- fix bugs in `PrefixContainer` encountered while adding new tests of #1418 scenarios
- did not handle entries like "[key]" or "prefix.key[index]" correctly
- refactor part of `GetKeyFromEmptyPrefix()` into `IndexOfDelimiter()`; share with `GetKeyFromNonEmptyPrefix()`
- extend `ReadableStringCollectionValueProviderTest` to cover bracketed key segments
nits:
- remove use of "foo", "bar", and "baz" in affected test classes
- `""` -> `string.Empty`
- `vpResult` -> `result`
- was "CS0649: Field is never assigned to, and will always have its default value `null'"
- visible only in VS builds due to aspnet/dnx#2284
nit: let VS do its thing with Microsoft.AspNet.Mvc.Localization.xproj
This change removes the validation that forces an OutputFormatter to set
an encoding, so that you can use the OutputFormatter base class for
non-text.
The check that we had would pretty much only be hit when you
didn't have any SupportedEncodings. If you have anything in
SupportedEncodings, then one of them will be picked as a default. So
removing the check is to do, because for a text-based formatter you'd
never run into this issue in the first place.
- Previously `ModelBindingResult.IsModelSet` would be set to true if type conversions resulted in empty => `null` values for ValueTypes. This resulted in improper usage of `ModelBindingResult`s creating null ref exceptions in certain cases.
- Updated existing functional test to account for new behavior. Previously it was handling the null ref exception by stating that errors were simply invalid; now we can provide a more distinct error.
- Added unit test to validate `TypeConverterModelBinder` does what it's supposed to when conversions result in null values.
- Added additional integration tests for `TypeConverterModelBinder`.
#2720
- Disabling tests which have corresponding bugs in mono.
- Fixing a few tests which do not handle *nix file system.
- Updating Travis configuration to use mono's alpha bits.
- Introducing PlatformNormalizer to normalize content across multiple platforms.
- Removed TaskHelper and refactored with ClosedGenericMatcher
- Removed TypeHelper
- Moved custom encodings to InputFormatter
- Moved ObjectToDictionary to PropertyHelper
- Removed respective tests and test projects
This is some low hanging fruit for reducing the number of resolves we have
per request.
DefaultHtmlGenerator: Lots of these are created by RazorPage. It needs
IUrlHelper, so scoped is the best we can do for now. For an example, on
the front page of our sample, 48 of these are created for each request.
48! This takes it down to 1-per-request.
JsonResult: Again, multiple created per request (12 for the sample). This
class is totally stateless, so we can get down to 0-per-request.
DefaultViewComponentInvokerFactory: Same story as JsonResult.
DefaultObjectValidator/MvcMarkerService/DefaultFilterProvider:
these are stateless and pretty much guaranteed to be used by every request.
Getting them off the table.
- cleanup duplicate code now that #2445 is fixed
- update unit tests using old `ModelBindingContext` setups
- fix (just) one integration test where `MutableObjectModelBinder` incorrectly calculated
`isTopLevelObject` and returned a non-`null` model
- undo temporary changes in `BodyModelBinderTests` due to increased reliance on incorrect
`isTopLevelObject` in #2445 fix
nits:
- combine tests that are now duplicates
- beef up coverage of some `MutableObjectModelBinderTest` cases
- remove unused `using`s
- part II of II for #2445
- `FormCollectionModelBinder` is an exception because container is not user-provided
- no `ModelState` entry added
- enable tests that #2445 was blocking
- fix these and other tests expecting different `ModelState` entries
- simplify logic in `FormFileModelBinder`
`ValueProviderResult`
- remove `protected` setters and parameterless constructor
- no scenario for their use in subclasses; however `ConvertTo()` remains `virtual`
- add single-parameter constructor
- use in most of the greedy and type-matching model binders
- add doc comments throughout class
nits:
- use new `ValueProviderResult` constructor in many existing tests
- `""` -> `string.Empty` and `vpr` -> `valueProviderResult` in `ValueProviderResultTest`
- improve some test names in `BodyValidationIntegrationTests`
- do not check `Message` of a Json.NET `Exception`
- part I of II for #2445 (with a duplicate code PR to follow)
- needed for #2445 because new `ModelState` entries for values will make inconsisteny worse
- change `BodyModelBinder` to use same keys for all `ModelBindingResult`s and `ModelState` entries
- return fatal error result if formatter adds an error to `ModelState`
- update potential callers to avoid avoid ignoring `IsFatalError`
- fix test attempting to serialize all of `ModelState`
- will be borked with additional `RawValue`s in state
- fix two other tests that serialized `ModelState` but checked only `IsValid`
nits:
- address minor inconsistencies in `ModelBindingContext`
- use `System.Reflection.Extensions` package a bit more, where it's already referenced
- remove some unused resources
- #2664
- use new property to correctly determine `isTargetEnum` in `GetCurrentValues()`
- avoid `ArgumentNullException` in all cases where raw values are `enum` but target is not
- stop skipping tests blocked by #2664, exposing a couple more #1487 issues
- use new property instead of private `GetElementType()` methods where possible
- cleans up some duplicate code
- also remove redundant use of `IsCollectionType` and `ElementMetadata`
nits:
- move properties above methods in `ModelMetadata`
- avoid accidentally-incorrect "Remove Unnecessary Usings"
This is the first step is some more refactorings to come in the future
with the goal of making MVC less monolythic. This makes the core of MVC
more reusable and more in line with the design of other vNext platform
components.
With this change, Mvc.Core contains just the minimal guts needed to build
a working app.
- Action Discovery
- Action Invoker
- Filters
- ObjectResult
- Model Metadata
- Model Binding
- Formatters
- Validation System
And yes, we are aware of the irony of 'minimal MVC' not including the view
system. The idea is that this is the kernel of an MVC app, and anything
real is layered on top.
The most noticable impact of this change is that MvcOptions has been blown
apart into more managable chunks. See the various ConfigureMvc*** methods.
The new Mvc.Extensions package is a placeholder while we evaluate and tune
the new definitions. Expect more changes as features are move to their own
packages, and in some case their own repositories.
For now there is no experience to bootstrap an Mvc.Core app. That's coming
next.
Combining IControllerModelBuilder and IActionModelBuilder into a pipeline
of IApplicationModelBuilders. Extensibility for framework features (Auth,
Cors, etc) should implement an IApplicationModelBuilder to add data to
models before IApplicationModelConventions have a chance to run.
Also deleting IGlobalFilterProvider while touching this code, this should
have been removed a while ago when we removed other options facades.
- only use MVC error message when `[BindRequired]` is violated
- update that error message to more clearly describe the problem
- enable all tests skipped due to dupe bug #2493
- update expectations of a few tests using the old messages
nits:
- rename `ModelBinding_MissingRequiredMember` to `ModelBinding_MissingBindRequiredMember`
- remove `<param>` description of removed `requiredValidator` parameter
- remove unused `MutableObjectModelBinderTest.GetRequiredValidator()`
- #2456
- visible behaviours now match MVC 5
- prevent `CollectionModelBinder` from converting no value to `byte[0]`
- prevent `TypeConverterModelBinder` from converting empty value to `byte[] { '\0' }`
nit:
- remove additional delegates `ModelBindingTestHelper.GetOperationBindingContext()` calls
- a few left despite #2625 cleanup
- use valid `multipart/form-data` content type; include a `boundary`
- correct expectations of `FormCollection` model binder's operation
- restore tests actually skipped for either of the above reasons
- add more tests with `ModelBindingResult.Model==null` and both `IsModelSet` values
#### Remove test references to Won't Fix bug #2473
- restore #2473 tests; update test expectations
- expect `null` composite results whenever binding fails
#### Restore test skipped due to "#2646"
- that issue does not exist; was likely #2466 or similar fixed bug
#### Rename model binding tests that still mention ReturnsFalse or ReturnsTrue
#### Minor src changes
- remove unused variable and unnecessary nesting in `DefaultControllerActionArgumentBinder`
- remove dangling mention of `[DefaultValue]` in `ComplexModelDtoModelBinder`
#### nits:
- remove empty delegates from some `GetOperationBindingContext` calls; `null` fine
- do some `using` cleanup
- combine two test methods in `KeyValuePairModelBinderTest`
- name a few more arguments
Updated the ResponseCacheFilter Duration, Location, NoStore, and VaryByHeader properties to return one of 3 values: the specific setting applied to the instance, the setting supplied by the CachePolicy (from the constructor), or a default value. The emphasis being not to change the outward function of these properties to consumers, but to defer the evaluation of these properties until the OnActionExecuting method.
Updated the ResponseCacheFilter to check whether a cache duration has been supplied when the NoStore property is false and throw an InvalidOperationException when a duration has not been provided.
Updated ResponseCacheFilterTest to reflect the changes in behavior in the ResponseCacheFilter
Updated the ResponseCacheFilterAttributeTest to reflect the change in the behavior of the ResponseCacheFilter
Added unit tests to ResponseCacheFilterTest.cs to verify that the CachePolicy properties are properly overriden with the properties set directly on the ResponseCacheFilter.
Added functional tests to test the ability to override CacheProfile settings with properties on the ResponseCacheAttribute
This change completely removes [Activate]. In a controller, you should
constructor injection or [FromServices] to access services.
To access context items (ActionContext, ActionBindingContext, root
ViewDataDictionary) you should use the respected attribute class.
We'd like to consider streamlining this further in the future by getting
down to a single injectable context for controllers, but for now this will
have to do.
This change removes [Activate] from ViewComponents. Accessing context
should be done through [ViewComponentContext]. Accessing services should
be done though constructor injection.
This change treats 'top-level' collection-type models similarly to
top-level POCO model - namely that they will always be instantiated even
if there's no data to put inside.
This change adds a [Required] client validator when
ModelMetadata.IsRequired == true. The bulk of the changes here are
mechanical updates to test files.
- use `IDictionary<string, TValue>` support in `<a/>` and `<form/>` tag helpers
- make `RouteValues` dictionaries `IDictionary<string, string>` for ease of use
- remove `TagHelperOutputExtensions.FindPrefixedAttributes()`
- set all `GeneratedTagHelperContext` properties
- add error for tag helper dictionary properties where `TValue` is `ModelExpression`
- add new `RazorPage.InvalidTagHelperIndexerAssignment()` method and resource
tests
- use new `isIndexer` argument when creating `TagHelperAttributeDescriptor`
- arrange `AnchorTagHelper` and `FormTagHelper` correctly
- also expect `routeValues != null` in calls to `IHtmlGenerator`
nits:
- get rid of some `foo` and `bar` gunk in tests
- remove unused variable to cleanup a test compilation warning
with MVC5.
This change removes the behavior in model binding to validate values 'on
the wire' for requiredness instead of the looking at the model. This
restores the behavior of [Required] for model binding to the MVC5
semantics.
Also ensures that when a type is marked as skipped, any sub property which is model bound (and hence a modelstate un validated entry),
is marked as skipped (otherwise it would cause the ModelState to be invalid).
Also fixing a bug in model state dictionary FindKeyWithPrefix was not considering [0] & [0][0] as a valid prefix.
This part of the change removes default value support from ModelBinding.
Updated some unit tests to verify that it does nothing in that case.
Deleted a functional test as it was pure duplication of another
(supported) case where the property has a pre-initialized value.
This change simplifies InputFormatterContext/OutputFormatterContext by
swapping ActionContext for HttpContext.
This change is important especially for InputFormatterContext as it
decouples ModelState from ActionContext - allowing us to fix a
related bug where the _wrong_ ModelState can be passed in for a
TryUpdateModel operation.
Add SerializerSettings to MvcOptions and pass those options to the JsonInputFormatter and JsonOutputFormatter.
Remove custom contract resolver.
PR feedback
Pass JsonSerializerSettings to JsonPatchInputFormatter
PR feedback
Make DI JsonOutputFormatter formatter use MvcOptions SerializerSettings
Fix JsonPatchInputFormatter using null ContractResolver
Fix tests
methods
This change applies the 'override' semantic to attribute routes on virtual
methods.
A method override can either inherit attribute routes from a base
definition, or can replace them. It's not possible to inherit routes and
also add to them.
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.
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`