- #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.