- ensure `ViewDataDictionary` constructors are not passed a `null` or
`Mock.Of<IModelMetadataProvider>()` instance
- `ViewDataDictionary` constructors always use the `IModelMetadataProvider`
- `viewData.ModelMetadata` now never `null`
- `ViewDataDictionary<int>.Model` no longer throws if read before it's written
- `ViewDataDictionary.ModelMetadata` now copied to new instances in fewer cases
- e.g. don't use unusual `object` datatype with customized `ModelMetadata`
- `null` checks can generally be removed but in one case needed to
special-case metadata for `object`
nit: remove duplicate empty `string` check in
`ExpressionMetadataProvider.FromStringExpression()`
- ensure correct `ViewData.ModelState` value in a `RazorPage` instance
- let view components inherit `ViewData.Model` from surrounding context
- do not create an isolated `ViewDataDictionary<TModel>` in one HTML helper
- allows previous `ViewDataDictionary<TModel>` constructor to be `internal`
- also add comments for that constructor
- change two `ViewDataDictionary` copy constructor calls to avoid uselessly
copying `Model` and related information from source
- `ViewDataDictionary<TModel>` constructors now pass `typeof(TModel)` to base
`protected` constructors
- move type compatibility checks into base `ViewDataDictionary`
- remove `ViewDataDictionary<TModel>.ModelMetadata` override
- don't retrieve `ModelMetadata` twice in a single constructor invocation
- remove newly-unused `protected` properties and use `private` fields in copy
constructors
Address longstanding problems found (see #1466)
- avoid reusing `ModelMetadata` after `Model` value changes
- reset `ModelMetadata` backing field in `Model` setter
- `Model` and `ModelMetadata.Model` could previously get out of sync
- carry `ModelMetadata` forward from an outer scope only if `Model` matches
- previously two scopes could have different `Model` values but share their
`ModelMetadata` (and `ModelMetadata.Model`)
- related to previous item but didn't require `Model` setting; switching
to a property of the same type as containing `Model` was enough
- avoid NRE if `ViewDataDictionary<int>.Model` is read before it's written
- problem affected all non-`Nullable` value types
- `ViewDataDictionary.ModelMetadata` setter should throw if value is `null`
nits:
- add and reword doc and code comments
- `ViewDataDictionary<TModel>` constructors should only inherit base's
parameter descriptions; have more information in the derived class
- make a few `ViewDataDictionary` properties get-only
- clean up `using` statements in `ViewDataDictionary<TModel>`
- make two constructors `internal`
This change adds the concept of a full-name to viewcomponents. View
components can be invoked using either the short name or long name. If the
provided string contains a '.' character, then it will be compared against
full names, otherwise it will be matched against short names only.
The short name is used for view lookups.
If the name is explicitly set via ViewComponent attribute, then the full
name is the name provided. The short name is the portion of the name after
the last '.'. If there are no dots, then the short name and full name are
the same.
If the name is not set explicitly, then it is inferred from the Type and
namespace name. The short name is the Type name, minus the 'ViewComponent'
suffix (if present). The full name is the namespace of the defining class,
plus the short name.
- Added utility methods to construct valid SyntaxTreeNodes that represent the @removetaghelper directive.
- Added parse level unit tests to validate the @removetaghelper generates an accurate SyntaxTreeNode.
- Added parse level unit tests to validate the @removetaghelper throws with bad formats.
- Added TagHelperRegistration unit tests to validate the AddOrRemoveTagHelperCodeGenerators are understood and affect the descriptors found.
- Added Designtime mapping tests to validate correct source mappings are made to ensure proper coloring and lack-of C# intellisense.
- Added end-to-end tests to validate @removetaghelper can essentially disable TagHelpers on a page.
#112
- Added parsing recognition of the @removetaghelper directive.
- Added TagHelperDescriptor handling: @removetaghelper will cause the system to ignore TagHelpers that are added via @addtaghelper.
- Added Chunk generation, this involved building a CodeGenerator (soon to be named ChunkGenerator) that pulled out the stringified @removetaghelper lookup text which it then uses to construct a RemoveTagHelperChunk.
- Modified CodeVisitors to now understand RemoveTagHelperChunk's.
- Added code generation, this involved creating a dummy string in order to give the @removetaghelper "..." coloring.
#112
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.
ViewComponents and Controllers now follow the same rules exactly for what
types of classes they can be.
Also corrected a bug in a test for controllers. Closed-generic types can
be controllers, the test was wrong.
never that for `object`
- `ViewDataDictionary<TModel>.ModelMetadata` was for `object` after base
copy constructor got value from `ViewDataDictionary<object>`
- problem led to #1426 symptoms
- with copy constructor leaving `base.ModelMetadata==null` more often,
`ViewDataDictionary<TModel>.ModelMetadata` usually tracks `TModel` if
`Model==null`
nit:
- fix existing comment in main `ViewDataDictionary` copy constructor