- Tested with a page containing 33% of invalid Ids which go through TagBuilder.CreateSanitizedId.
- Ran 10,000 requests with 20 in parallel and measured perf.
- Data before the change:
System.String allocated by CreateSanitizedId: 1.84 mb
System.Text.StringBuilder allocated by CreateSanitizedId: 1.68 mb
- Data after the change:
System.String allocated by CreateSanitizedId: 0.720 mb
System.Text.StringBuilder allocated by CreateSanitizedId: 0.560 mb
Around 60% improvement from the original case.
- 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.
- #1514
- refactor `RazorCompilationService` to allow a test subclass that normalizes Razor file line endings
- add `TestRazorCompilationService` to `RazorPageExecutionInstrumentationWebSite`
- adjust line endings to match in `RazorPageExecutionInstrumentationTest`
- add `ignoreLineEndingDifferences: true` to `Assert.Equal()` calls
- responses on Windows can have a mix of line endings
- `git config` setting affects line endings in .cshtml (and baseline) files
- however MVC and Razor mix `Environment.NewLine`s into HTTP responses
- update `PrecompilationTest` to split response regardless of line endings
- update `ResourceFile` to normalize all source file streams to LF only
- ensures consistent checksums and line mappings
- change `MvcRazorHostTest` to expect new line mappings
- recreate baseline files to expect new checksums and literal line endings
- use verbatim strings in affected tests
- careful use of `Environment.NewLine` in expectations is now just noise
nits:
- add doc comments in `RazorCompilationService`
- correct `TagHelpersTest` name to match containing file
- avoid incorrect `using` removal when `GENERATE_BASELINES` is not defined
- remove unnecessary `ResourceFile` normalization of output files
- 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
- #1485, #1487
- handle `TemplateInfo.HtmlFieldPrefix` in `ViewDataEvaluator.Eval()`
- attempt lookup in the `ViewDataDictionary` using full name then evaluate
relative `expression` against `viewData.Model`
- handle `null` or empty `expression` special case in this method (remove `throw`s)
- always pass relative `expression` name into `Eval()`
- remove `null` or empty `expression` handling from higher-level code
- in a couple of cases, special-case returned `ViewDataInfo`
- #2662
- remove incorrect guard from `DefaultHtmlGenerator.GenerateRadioButtion()`
- add doc comments for the core methods that have changed
- enable unit tests skipped due to one of above bugs
- fix one (yeah, just one) other test with incorrect expectations
- remove functional test comments about the above bugs and update expectations
nits:
- move some comments describing `ViewDataEvaluator` methods above the methods
This is some cleanup of how we add multi-registration services to avoid
duplication when calling AddMvcServices multiple times. Also improved
tests to be more clear, and to verify all of our special cases
explicitly.
- #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"
- test additional cases _close_ to these bugs as well
for #1485
- show odd `@Html.CheckBox()`, `@Html.Hidden()` behaviour in unit tests
- show odd `@Html.TextBox()` behaviour in functional tests (templates)
for #1487
- show odd `@Html.Value()` behaviour in unit tests
- show odd `@Html.RadioButton()`, `@Html.TextArea()` behaviour in functional tests
- show lack of validation attributes for `@Html.RadioButton()`, `<select>` tag helper
for #2662
- show odd `@Html.RadioButton(string.Empty)` behaviour in functional tests
for #2664
- show failures with `@Html.ListBox()` in unit tests
nits:
- test `IHtmlHelper` methods, not extensions
- use `ViewData`, not `ViewBag` in `HtmlGeneration_FormController`
- name test methods a bit more consistently
- rename `HtmlHelperValueExtensionsTest` to `HtmlHelperValueTest`
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()`
- `CultureReplacerMiddleware` no longer helping `RazorWebSite`
- regressed with @30d11a8
- `[ReplaceCulture]` sets up the correct culture early enough for consistent formatting
- remove `CultureReplacerMiddleware` from `RazorWebSite`
- only `Startup` class we have that used this with `RequestLocalizationMiddleware`
- testing `RequestLocalizationMiddleware`; so remove the confusing extra middleware
- baselines include both expected output and design-time line mappings
- controlled by GENERATE_BASELINES
- assertions related to file content are not checked in this mode
- add design-time test of Basic.cshtml to `MvcRazorHostTest`
- regenerate all files to avoid BOM and blank line noise in future PRs
- update out-of-date design-time Basic.cs file
nits:
- make a few variable names more consistent
- make `Assembly` fields `static`
- remove unused `_resourcesAssembly` field from `ErrorPageTests`
- remove `ResourceHelpers` which was specific to functional tests
- #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
- ICodeTreeCache => IChunkTreeCache
- ModelCodeGenerator => ModelChunkGenerator
- MvcCSharpCodeBuilder => MvcCSharpCodeGenerator
- Updated files that used Razor resources that are now in different namespaces.
- Updated variable names to account for Razor renames.
aspnet/Razor#140
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
FileVersion property renamed to AppendVersion in ImageTagHelper,
LinkTagHelper and ScriptTagHelper.
asp-file-version attribute renamed to asp-append-version.
Resolves issue #2540
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] support from TagHelpers. TagHelpers which
need access to context should use [ViewContext] to have it injected. To
access services, use constructor injection.
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.
- This involved also adding required attributes with wildcards.
- With this change AnchorTagHelpers and FormTagHelpers should no longer light up on every `<form>` or `<a>` tag.
#2581
- also rename files and directories with "GlobalImport" in name
- nearly blind but avoid "ViewImportss" in new names
- public API change: `ViewHierarchyUtility.GetGlobalImportLocations()` -> `GetViewImportsLocations()`
- primary source updates were comments, tests, and implementation details
nit:
- rename NestedGlobalImports.cs file to NestedViewImportsController.cs, matching class
- 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.
The assumption is ModelState should have entries if
1. An error is explicitly added by a model binder.
2. There is validation error reported while validating the model.
3. There is value bound by the model binder.
With this change there should be no extra entry other than for the cases mentioned above.
Also enabling the integration test cases.
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.
This change dramatically simplifies the parameter discovery logic in
DefaultApiDescriptionProvider. Instead of surfacing POCO objects as
parameters, we now fully expand every model.
The rationale is that we want to show every key/value that can be set by
the user and not force consumers of ApiDescription to do that themselves.
Tests are cleaned up to match the new behavior.
- Mvc is currently broken on CoreCLR because it is
inheriting dependencies from Microsoft.AspNet.Mvc.Common but the resulting
dependency to Microsoft.AspNet.Mvc.Common is then erased at pack time.
This change moves the dependencies down and makes the shared package
only depend on System.Runtime.
#2507
- in .kproj files, let VS mark a couple more test projects as such
- remove duplicate `ModelExpression` class
- not necessary now that test project references MVC Core project
- follow up to 9fded74
- avoid `resources` warning in project.json files
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.
Covers simple scenario for each model binder.
Covers scenarios mixing a POCO model binder -> Simple Model binder.
This contains tests for
HeaderModel
ServicesModelBinder
CancellationTokenModelBinder
ByteArrayModelBinder
FormFileModelBinder
Part 2 Will contain similar tests for
FormCollectionModelBinder
BinderTypeBasedModelBinder
TypeConverterModelBinder
TypeMatchModelBinder
Any leftovers for BodyModelBinder
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`
Consider
public class Person
{
[FromBody]
public Address Address { get; set; }
}
public class Address
{
[Required]
public string Street { get; set; }
public int Zip { get; set; }
}
Request body { "Zip" : 12345 }
In this case the error key would be "prefix.Address.Street" (assuming there is a prefix because of additional metadata/positioning for/of the Person model).
public class Person
{
[Required]
public string Name { get; set; }
}
public void Action([FromBody]Person p)
{
}
Request body { }
In this case the prefix gets ignored and the error key is Name.
Please note this is so that we are compatible with MVC 5.0
public class Person
{
[Required]
public string Name { get; set; }
}
public void Action([FromBody][ModelBinder(Name = "prefix")] Person p)
{
}
public void Action2([FromBody][Bind(Name = "prefix")] Person p)
{
}
Request body { }
In both these cases (Action and Action2) the prefix gets ignored and the error key is Name.
This is a slight improvement from mvc, as in MVC the action parameter would be null.
The followup for this would be to fix#2416 -
This PR ignores the validation assuming that #2416 will address the issues and update the test.
NOTE: previous versions of mvc did not have property binding and hence there is no precedence in this case. For MVC and Web API it was possible to body bind an action parameter which used an empty prefix instead of a parameter name for adding errors to model state (In case of MVC if a custom prefix was provided, it failed binding from body i.e the parameter was null).
This change moves [BindingBehavior(...)] and friends into the model
metadata layer, and removes the reflection code from
MutableObjectModelBinder that was looking for them previously.
Throw a meaningful exception if the attribute to copy does not exists
in the attributes of the TagHelperContext rather than:
`System.InvalidOperationException : Sequence contains no matching
element`.
Added test too.
This change adds more information to ModelAttributes, so that metadata
providers can look at the attributes on the property and type separately
if so desired
This change introduces a new property to ModelMetadata called
IsBindingRequired, which specifies whether or not a model value must be
present on the wire during model binding.
[DataMember(IsRequired = true)] is currently the only thing that will set
this property.
Updated tests and documentation for clarity on the difference in meaning
between MM.IsRequired and MM.IsBindingRequired. Moved setting for
IsRequired to ValidationMetadata which is a better fit.
Also added functional tests for [BindingBehavior] and [DataMember] in
model binding because they were totally missing.
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.
- Also modified existing tests to account for aspnet/Razor#332 which fixed models formatting after newline.
- Updated tests for inject to understand new formatting parsing.
aspnet/Razor#332
- Added unit tests to validate that the properties were rendered correctly.
- Modified functional tests to utilize PreElement and PostElement.
aspnet/Razor#341
- #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
This change caches the actual model metadata instances. Some profiling
showed we didn't go far enough, we were allocating a lot of ModelMetadata
+ ModelPropertyCollection instances.
- set correct `MarkAsHtmlEncodedMethodName` value in `MvcRazorHost`
- handle `HtmlString` values in `TagHelperOutput.Attributes` in `RazorPage`
- special-case double-quotes in `HtmlString` values
- add `static WriteTo()` method for use in tag helpers
- handle non-`string` `output.Attributes` values in tag helpers
- make `TagHelperContentWrapperTextWriter` a `public` class
- provide a `TagHelperContent.Append(object, ...)` extension method
- add `LinkTagHelper.Href` and `ScriptTagHelper.Src` properties
- avoid Razor HTML-encoding these attribute values before their use
- add `JavaScriptEncoder` properties in `LinkTagHelper` and `ScriptTagHelper`
- allow encoding testing without unit testing the default encoder
- handle MVC and Razor changes for this bug in existing tests
- add functional tests of encodings
- add test encoders to TestCommon project
nits:
- correct `InputTagHelper` to pass `type=""` through unchanged
- set correct `TagHelperContentTypeName` value in `MvcRazorHost`
- remove unnecessary `FormTagHelper.Method` and `OptionTagHelper.Selected` properties
- remove complex ternaries and `ShouldAddFileVersion()` methods
- add a few debug assertions
- fix some odd wrapping
- remove or `#if`-out unused `using`s
- remove trailing whitespace
Adding Equals and GetHashCode implementations - the lack of these results
in a lot of boxing.
Removing dead code, not possible to create a model metadata for a
parameter anymore.
- This solves tooling trying to resolve ChunkInheritanceUtility bits for chunks: Aka can't inherit `@using`, `@inject` etc. from _GlobalImport.cshtml
- Added test to validate paths are normalized for DecorateCodeBuilder.
#2271
- remove useless `configuration` variables and `Configuration` instances
- remove "Review" code comment
- unintentionally included in commit 4b5dd19
- reduce repeated code in `TestHelper` for functional tests
- `CreateServer()` methods had duplicate code, an ambiguous match, and an odd order
- rename `GetTestConfiguration()` to `UseCultureReplacer()` in functional tests
- 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
- few end tags for void elements e.g. `</input>`
- fair number of self-closing flow elements e.g. `<label .../>`
- most-visible change is correction of `<textarea>` in tag helper sample
- no product code changes
The DataAnnotationsMetadataProvider was setting the bool? IsRequired, all of the
time instead of only setting it to true when we found a RequiredAttribute.
So we never actually executed the fallback logic here. Found
this while working on removing some reflection code from the validator,
and wanted to split it out because it's simple.
- Tooling passes in rooted paths when asking for a RazorParser for a file. This was problematic when resolving inherited code trees and ultimately this commit tests that.
#2213
- skipped a new test. This is a known issue that I have reported to the respective team.
- This also fixes#1987 : Investigate xml serializer test failures in Core CLR
- #438 part 1/2 and #2027 part 1/3
slight oddity in the XML docs
- unfortunately Roslyn seems to ignore `TypeInfo` being a subclass of `Type`
nit: use correct `warningsAsErrors` datatype in test project.json
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.
- #1865
- change `MutableObjectModelBinder` to ignore exact match in value providers
- had an incorrect assumption: don't want exact model name to match since
this binder supports only complex objects
- also ignored `BinderModelName`, value provider filtering, et cetera
- reduces over-binding e.g. `[Required]` validation within missing properties
also add more tests of #2129 scenarios
- #2129
- do not propagate results with `!IsModelSet`, allowing empty prefix fallback
- adjust `ComplexModelDtoModelBinder` to at least fake-bind all properties
- default values not consistently picked up otherwise
nit: correct 2 test names in `KeyValuePairModelBinderTest`
- use named parameters more often
- add more comments about returned `ModelBindingResult`
- clean up `ModelBindingResult` doc comments
- cleanup `using`s
Nits:
- cleanup trailing whitespace
- change `retVal` -> `result` in `KeyValuePairModelBinderTest`
- Updated some naming bits that were still using the ViewStart name.
- Updated MvcRazorParserTests to test more cases of the parser, especially with @tagHelperPrefix.
#2110
- Any Action<ITagHelper, ViewContext> can be registered in DI to allow setting of tag helper properties after any [Activate] properties are set but before their bound from the source document and the tag helper is executed
- Removed previous tag helper options as initializers is the way to do this now
- #1689
- #2162
- see issues aspnet/DependencyInjection#193 and #1612
- use `TryAdd()` in `MvcServices` for the `IAssemblyProvider`
Move `ApplicationBasePath` handling into `RazorPreCompileModule`
- restores view precompilation in functional tests of sample sites
- if we need this, others will as well
- override `IApplicationEnvironment` but get folder from `ProjectContext`
- also remove remaining `IServiceProvider` implementations in this code
test fixes:
- simplify `IApplicationEnvironment` override
- move override logic into `TestHelper.CreateServer()` methods
- remove `LoggerFactory` setup
- does not seem to require special-casing
- remove unused `ITestConfigurationProvider` / `TestConfigurationProvider`
- remove `TestAssemblyProvider` classes
- no longer required
- remove `ReplaceCallContextServiceLocationService` test helper
- change MVC sample to fully-qualify config.json path
- avoids `ReplaceCallContextServiceLocationService` need in `MvcSampleTests`
- no longer required for other tests
nit: remove unused `_serviceProvider` and constructor overload in `RazorPreCompiler`
- work around aspnet/DNX#1361 and inconsistent dev boxes (from previous fix attempts)
- had inconsistent case in test/WebSites and test/WebSites/ConnegWebSite
- ConnegWebsite -> ContentNegotiationWebSite
- RazorInstrumentationWebsite -> RazorPageExecutionInstrumentationWebSite
- RazorViewEngineOptionsWebsite -> RazorEmbeddedViewsWebSite
nits:
- sort dependencies in functional test project.json
- correct a few readme.md files
- compiler given `ApplicationName`, not `ApplicationBasePath`
- @pranavkm wrote the tests prior to 64ddbe0160
nit: rewrap long line introduced in prior commit
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
- see commit 9d5364c
- never correct to pass a `Func<object>` to `GetExplorerForExpression()`
- `<label/>` tests succeeded because that tag helper doesn't use expression result
- `<select/>` tests succeeded because that tag helper gets result from `ViewData`
- does not use `ModelExplorer` due to #1468
nit: update variable names `metadata` -> `modelExplorer`
- jQuery and jQuery-validation files were not being copied
- update to match more-recent VS templates
nit: simplify wwwroot/lib directory tree slightly
- #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.
This feature allows routing to generate a link when the action that is
being linked-to does not yet exist. See the PR in routing for the actual
implementation changes. This PR just has a simple functional test for the
scenario.
- add `CachedDataAnnotationsMetadataAttributes.UIHint`
- set `ModelMetadata.TemplateHint` using `UIHintAttribute` or `HiddenInputAttribute`
- add doc comments for `TemplateHint`-related properties and methods
- add unit tests and use these attributes in functional tests
nits:
- cache and seal `CachedModelMetadata.IsCollectionType`
- correct doc comments for `ModelMetadata.RealModelType`
- add doc comments for `IsCollectionType`-related properties and methods
- add doc comments for `IsComplexType`-related properties and methods
- move `CachedModelMetadata.IsComplexType` right below `IsCollectionType`
- same for related fields and methods
- #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.
- #1516
- `allowMultiple == true` when model has a collection type
- ignore any `multiple` attribute in Razor source when generating element
- simplify tests too: fewer error cases
Note Razor author could allow browser user to submit values model binding
will likely ignore: Could mix a `multiple` attribute with a non-collection
`asp-for` expression.
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.
- change `AdditionalValues` type to `IDictionary<object, object>`
- copy `ModelMetadata.AdditionalValues` in `AssociatedMetadataProvider` sub-classes
nits:
- add XML comments
- correct indentation in `CachedModelMetadata`
- #1758
- provide the property bag in `ModelMetadata`; seal it in `CachedModelMetadata`
- add unit tests
- include use of `AdditionalValues` in model binding functional test
nits:
- expose `AdditionalValues` as an `IDictionary` though MVC 5 uses `Dictionary`
- seal `ModelMetadata.Properties` collection as well
- cover a few properties previously missed in `CachedDataAnnotationsModelMetadataTest`
- correct two `ModelMetadataTest` method names
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.
expire files in razor file cache.
Add a functional test to ensure the compiler cache does not get
initialized until the first request to a View.
Fixes#1708
1. Creates a filter called FormatFilter. This will look at the format parameter if present
in the route data or query data and sets the content type in ObjectResult
2. It adds new options called FormatterOptions, that contains the map of format to content tyepe
3. A method in MVC options to add the formatter mapping
- avoids checking these external .js files into our repo
- limit jQuery*.js versions to single value, mostly the latest but don't
cross over to jQuery.js 2.0.x range (incompatible with IE 6, 7, 8)
- #439 (3 of 3)
- extended the Validation web site to include use of `[Remote]`
- also confirm operation of the validation actions (which all reject their input)
- #439 (2 of 3)
- correct namespaces
- correct `Resources` class and member names; add new resources
- add `RequestServices` property to `ClientModelValidationContext`
- adjust to modern `IUrlHelper` API
- add `IClientModelValidator` support in `DataAnnotationsModelValidator`
- move previously-unused `StringSplit()` to `RemoteAttribute` and rename
- rewrite `RemoteAttributeTest`
- improve test method names
Reduce number of `[Remote]` constructor overloads
- remove `AreaReference` enum and related `[Remote]` constructor overload
- use `null` or empty `string` as explicit reference to the root area
- generally reduce parameter validation; match `UrlHelper`
Cleanup
- correct Engineering Guidelines violations
- especially: add doc comments
- correct spelling error in `_additonalFieldsSplit`
nits:
- minimize `null` checks in `AdditionalFields`
- make `GetClientValidationRules` `virtual`; some subclasses use `new` today
- add tests of `DataAnnotationsModelValidator.GetClientValidationRules()`
- remove `builder.ToString()` calls since it appears
https://roslyn.codeplex.com/workitem/246 has been resolved or Moq has
worked around that issue.
- #964
- compute `ModelMetadata.Order` based on `[Display]` attribute
- property affects e.g. `@Html.DisplayFor()` generation for complex objects
- also affects order of messages in validation summaries
- test new scenarios involving `ModelMetadata.Order`
- per-property `ModelMetadata` and related tests
- validation and `HtmlHelper` tests
- add `HtmlHelperValidationSummaryTest` (which touches on #453)
- update ModelBinding functional test to show use of `[Display(Order = x)]`
nits:
- move more `NullDisplayText` bits into proper slots (just above `Order`)
- add doc comments for `ComputeNullDisplayText()`
- add more assertions in tests using `ModelStateDictionary.HasReachedMaxErrors`
- remove some trailing whitespace
- avoid `Assert.True()` & `Assert.False()`; split some assertions up
- `""` -> `string.Empty` in affected test classes
- rename "DefaultEditorTemplatesTest~~s~~" class and file to follow guidelines
- rename "ModelBindingTest~~s~~" class and file to follow guidelines
FYI #1888 covers a predictable (or even just stable) order in the UI
Changes here are all focused around MaxModelErrors on
ModelStateDictionary.
MaxAllowedErrors now defaults to 200 (same as options). This means that
constructing a new ModelStateDictionary with the default constructor will
use this default. There's a new constructor for creating a
MaxAllowedErrors with a non-default value.
The ControllerActionArgumentBinder is now responsible for setting the
value from options onto ActionContext.ModelState. This results in better
layering and guarantees the option is respected if someone uses
extensibility to call model binding.
ModelStateDictionary.CanAddErrors is renamed to MaxErrorsReached. We
wanted to change the behavior of this property, but realized that it's
very useful inside the model validation code, so opted to renamed.
There's also a bunch of doc cleanup inside ModelStateDictionary to
simplify things and improve clarity.
This change allows you to set global defaults for ApiExplorer on the
ApplicationModel. Additionally, we're more lenient about configuring
ApiExplorer = on with conventional routing. If you turn on ApiExplorer at
the application level, we'll just skip over all conventionally routed
controllers instead of throwing.
This is a cleanup PR to improve the common usage of
ModelMetadata.Properties.
We found placed in code where both .Count and the ability to index by
property name would be useful. I was able to cascade this and simplify the
ModelBindingContext as well.
- with some `<text>` hacks, generated HTML is almost identical to tag helper version
- attribute order (HTML helpers consistently order alphabetically) is primary difference
- bit more testing, therefore related to #453
nits:
- remove some trailing whitespace
- clean up style in `MvcTagHelperTest[s]` and `MvcTagHelper_HomeController`
- e.g. more init syntax, fewer duplicate variables
- correct "MvcTagHelperTest~~s~~" file / class name
- remove unused `Order.OrderNumber` property in MvcTagHelpersWebSite project
- correct one spelling mistake
- Made @inject handle trailing semicolons identical to @using; essentially ignores it.
- Added parser, runtime/designtime codegen and functional tests.
- Added Microsoft.AspNet.Mvc.Common.Test.
- Transitioned pre-existing Microsoft.AspNet.Mvc.Common tests to the new test project.
- Updated transitioned tests to also work in CoreCLR (except ones with moq).
#1857
This change makes ApiDescription and ApiParameterDescription aware of all
of the new features we built into model binding for enhanced DTO support
(uber-binding).
The main change is that instead of sticking just to the declared
parameters on the action itself, we now traverse model metadata and break
the parameters down based on their logical data source.
This means that a model like the below will yield 3 parameters:
public class ProductChangeCommandDTO
{
public int Id { get; set; }
[FromBody]
public ProductDetails Changes { get; set; }
[FromQuery]
public string AdminComments { get; set; }
[FromServices]
public IProductRepository Repository { get; set; }
}
The 'Repository' will be hidden, as it's not related to user input.
Additionally, we treat different sources differently. In the
above example, 'Changes' is from the body and will be treated as a
leaf-node.
However if you use nested DTOs that are bound from the query string (using
[FromQuery]) or similar, we'll recursively explore to find as much
structure as possible.
This information is combined with data from the route template to give a
much more complete picture than we ever could in the past for parameters,
especially when DTO/Command pattern is used.
- add a couple more exclusions to .gitignore (recent VS additions)
- remove `<ProjectExtensions/>` elements
- update files that don't have the correct output directories
- remove dangling PrecompilationWebSite.kproj file
This change moves controller creation to the stage immediately before
model binding. The controller will be disposed/released before Resource
Filters run their 'OnResourceExecuted' method. Previously the controller's
lifetime surrounded all filter invocation.
Additionally, the Controller property is now gone from ActionContext, and
is moved to the 4 filter contexts that should have access to it
Action*Context and Result*Context.
This is a major change to how we handle the scenario where a controller is
a filter. We want to change the lifetime of the controller object, by
scoping it around action filters and result filters. This means that a
controller class can only implement action filters and result filters.
To implement #384 - we're creating a delegating filter class
'ControllerFilter' which will forward calls to the implementation of the
controller. This is discovered in the controller model and added to the
filter collection. This filter is removable as an opt-out of this feature.
The ControllerFilter only implements action filter and result filter, so
the new restriction about filter types on Controller is in place. A future
change will move the instantiation of the controller to after resource
filters.
This change adds support for our three-valued logic to the default value
handling part of the MutableObjectModelBinder.
The issue is that we want to look up a default value when a 'greedy' model
binder returns true but doesn't find a value.
We also don't want to call the property setter unless there is:
1). A value from model binding OR
2). A default value
In general all properties are get/set so filters can change them.
- some validate for not-null
- where we use services it's get/set also
Services are resolved in the Execute method if not provided.
A few more ActionResults that return a body have the ability to set a
status code now (optional).
- React to aspnet/Razor#221
- Modified existing TagHelper tests to no longer rely on ContentBehavior.
- Updated signatures of TagHelperExecutionContext and TagHelperContext pieces.
- React to aspnet/Razor#221
- Modified existing TagHelpers to no longer rely on ContentBehavior and to instead utilize GetChildContentAsync, PreContent, Content and PostContent.
- #1685
- move `ValidationSummary` type to the `Microsoft.AspNet.Mvc` namespace
- update tests and samples to match
- remove tests for case-insensitivity of `ValidationSummary` property values
- part II of #1253
- an expected case in template .cshtml files
- expression has name `""`; led to `ArgumentException` in `ModelExpression`
- test `@Model` and `@model.Property` in unit and functional tests
- update baselines to match
nits:
- remove a few unecessary `@`s in .cshtml files
- correct field names & ids in ProductList.cshtml (`foreach` confuses MVC)
- led to correct valiation attributes as well
- part I of #1253 using new Razor capabilities
- update baselines to match latest code generation
- use new `CodeBuilderContext` and `TagHelperAttributeValueCodeRenderer` signatures
- test complex expressions in bound non-string attribute values
See #1695 for a detailed explanation. This change builds support into the
system for the case that a model binder returns true without setting a
value for the Model.
In this case, validation will be skipped if it's a top-level object.
Note that explicitly setting null will still run validation.
This is a demonstration of how to inject an IRouter in between traditional
routes and MVC's handler. This allows you to accomplish a variety of
things that were possible with WebAPIs handlers, but inside the routing
system.
The example here turns a header representing the user into a locale, which
is used to select a controller. You could do other things like reject the
route match or change link generation.
There is one subtle project change here, to allow the same to be possible
for attribute routing, we need to create the attribute route after running
the user's routing configuration code.
- Support for binding posted file to type IFormFile
- Support for multipart/form-data in FormValueProviderFactory
- Updated Mvc Sample
- Added relevant unit and functional tests
- #1766
- use `ReplaceCultureAttribute` to avoid `CultureReplacer` thread consistency checks
- also update test expectations to match new formats
nit: use `UseMiddleware()` extension method rather than `app.Use()`
1) A few `<input/>` tag helpers in a partial view invoked (`@Html.PartialAsync()`) in a loop within a `@for` inside an `using @Html.BeginForm()` block.
2) A custom template e.g. EditorTemplates/MyType.cshtml containing a mix of `<input/>`, `<select/>`, and various input HTML helpers invoked (`@Html.Editor[For]()`) in a loop within a `@for` inside an `using @Html.BeginForm()` block.
3) `<select/>` tag helpers with an `using @Html.BeginForm()` block
4) HTML helpers in the <form/> tag helper
The action invoker no longer needs access to model metadata or to the
input formatter selector. This change removes the same as constructor
parameters and cleans up tests which use the invoker.
This is a new filter stage that surrounds the existing model binding,
action, and result parts of the pipeline. Resource Filters run after
Authorization Filters.
The other major change is to support one of the primary scenarios for
Resource Filters. We want a filter to be able to modify the inputs the
model binding (formatters, model binders, value providers, etc) -- this
means that those changes need to be held on a context object and preserved
so that they can be used in the controller.
So, IActionBindingContextProvider is removed - the ActionBindingContext
will be created by the invoker. For now it will be part of the action
context.
- StyleCop working again (handles C# 6.0 additions) though only locally for me
- disable some new rules:
- ConstFieldNamesMustBeginWithUpperCaseLetter
- InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements
- StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements
- StaticReadonlyFieldsMustBeginWithUpperCaseLetter
- PrefixCallsCorrectly
- correct remaining violations
- lots of long lines for example
- use more `var`; some manual updates since StyleCop doesn't check seemingly-unused blocks
nit: remove new trailing whitespace (was paranoid about adding it w/ fixes)
The ParameterModel and ParameterDescriptor have had a notion of
optionality for a while now, even though all parameters are treated as
'optional' in MVC.
This change removes these settings. Optionality for overloading in webapi
compat shim is reimplemented via a new binder metadata.
This change adds an interface for the functionality provide by
RouteConstraintAttribute, and adds support for configuration constraints
on actions/action-model.
Fix - When the model is passed in to a View, ViewDataDictionary sets it. During this process, we recurse through all the properties and create FastPropertyGetters for each of them. In this case, since it is an enumerable, the properties which we recurse through are not the elements of the collection but the properties of the Enumerable instead. i.e - Enumerable.Current. Creating getters for these properties are not necessary. The fix moves the property iteration step to a place where the properties are actually requested.
- Splitting TypeInformation class into two and separating their caches appropriately.
On a web server, this test ends up giving back a 204 because of the MVC
behavior when an action is declared to return void. The fix is to use
EmptyResult.
Absorbs the new IFileSystem interface. This change is to just address the breaking change introduced in IFileSystem.
Razor has to do the necessary changes to subscribe to the Watch event for expiring the modified files.
paths.
This website is written to assume that $pwd is always in the functional
tests directory when it's launched. This works fine for the functional
tests, but causes issues in many other contexts, including VS.
The issue is that responses to HEAD cannot have a body. When running these
tests on a real server, they break because the server throws when you try
to write to the body.
Project/Assembly names are all like 'FeatureWebSite' root namespaces
updated accordingly. This makes processing all of the functional tests and
deploying the web sites much simpler.
Adding dependencies and commands for iis, web listener and khestrel to each
site.
Each website comes with a readme.md to 'anchor' the otherwise empty
folder. We have another work item tracking adding content to these.
Once VS sees a project with a wwwroot, it wants to assign a port for iis,
so I let it.
The issue here is that a model state error is added with the model name
'doubled'. This is on a fairly obscure code path and the code dates back
to the original WSR git checkin of webapi. There are no wsr tests that
verify this behavior.
The cause here is that our 'greedy' model binders (like
FromHeaderModelBinder) return 'true' whether or not they successfully
found a model, because they don't want other model binders to run.
This also has an effect on the validation system. That means that
validators will run and attempt to validate the model (which may be null).
That's that rare case where we get to this code path.
- update XML docs to reflect new HTML / custom attribute separation
- update `Exception` messages to use new attribute names
- update MVC tag helper sample to use new custom attribute names
- add missing `<input/>` tag helper `throw`s test
nits:
- reword a few comments and messages for clarity and consistency
- use `<exception/>` sections to describe what's thrown
- add "Reviewers" comments about current throws
- note `<a/>` and `<form/>` are slightly inconsistent with others: `throw`
if unable to override specified `href` or `action` attributes; rest
`throw` only if custom attributes are inconsistent e.g. `<input/>` with
`asp-format` but no `asp-for`
- create test tag helpers after all property values are available
1. Updated ViewComponent to exposes similar properties to the existing ones in controller where
appropiate. We've left out Resolver for being a bad pattern (just inject the dependency on the constructor
or use Context.RequestServices to access it if needed) and Response as although available through the Context
property, it shouldn't be used/modified in a ViewComponent.
2. Updated ViewViewComponentResult to follow a similar pattern as ViewResult where the constructor is
parameterless and elements like ViewEngine are resolved during execution if the user does not set the
associated property on the object.
3. Updated ExecuteAsync in JsonViewComponentResult to remove the unnecessary pragma and async keyword from the
signature and to use Task.FromResult(true) instead.
4. Cleaned up ViewViewComponentResult tests.
Right now these use a commandline adapter to inject some data into the
tests, but it's really not needed. Instead, these routes use a prefix to
ensure that the scenario under test is isolated.
- #EngineeringDay
- license present but incorrect in just a few files
- skip generated files such as Resources.Designer.cs and files under
test\Microsoft.AspNet.Mvc.Razor.Host.Test\TestFiles\Output
- #EngineeringDay
- VS does not yet format auto-properties nicely; reverted what it did
Also revert changes under
- test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles
- #EngineeringDay
- Total replaced: 660 Matching files: 270 in *.cs
- Total replaced: 250 Matching files: 32 in all other files
- Total replaced: 22 Matching files: 8 in a few stragglers
Did not change files under following directories
- test\Microsoft.AspNet.Mvc.Razor.Host.Test\TestFiles\Output
- test\Microsoft.AspNet.Mvc.FunctionalTests\compiler\resources
- test\WebSites\TagHelpersWebSite
(Razor generates trailing whitespace in a case or two)
For each of these TODOs:
- If there's an active bug tracking the work, and the TODO provides
something of value, I left it and standardized the formatting. I also
added comments to the bug.
- If the comment provided no value (implement feature X when we do feature
X), I deleted it with impunity.
- If the comment was stale (won't fix or just out of date), then we
removed it uncerimoniously.
There was a single TODO that was actually actionable, so I enabled that
test.
- TagHelperAttributeDescriptors changed to be lighterweight and not depend on PropertyInfo, had to modify our use of them to work with the new contract.
- scenarios where helper takes different code paths were not well-explored
nits:
- improve a few comments and names
- refactor some setup code into helper methods
- use `EmptyModelMetadataProvider`, not `DataAnnotationsModelMetadataProvider`
Test gap around `GenerateTextBox()`'s `format` argument is temporary.
- #1523
- remove `TagHelperOutput.Merge()` extension method entirely
- test tag name preservation with all MVC tag helpers
- `<input/>` tag helper generation of a checkbox wasn't previously tested
nits:
- fix argument order in a couple of `Assert.Equal()` calls
- remove use of "original tag name"
This change enables some compatibility scenarios with MVC 5 by expanding
the set of legal ways to configure attribute routing. Most promiently, the
following example is now legal:
[HttpPost]
[Route("Products")]
public void MyAction() { }
This will define a single action that accepts POST on route "Products".
See the comments in #1194 for a more detailed description of what changed
with more examples.
These tests verify that per-request services can be injected into assets
that users provide/implements (filters, constraints, controllers, views,
etc).
The purpose is to verify that the services are correctly resolved from the
per-request service container, and don't have state that lingers and
influences the next request. This is important because changing the
lifetime of a framework services could easily impact the lifetimes of
others, and ultimately of something the user created.
Rather than throwing here, this does what routing does. If request
services aren't set, we just create our own scope.
This will NOT create an extra scope if request services are already set.
- clean up "the the" in XML comments
- simplify refactoring VS did when I renamed `GetHtmlHelperForViewData()`
- fix existing issue in `HtmlHelperCheckboxTest.CheckBoxReplacesUnderscoresInHtmlAttributesWithDashes()`
(was using a `HtmlHelper<ViewDataDictionary<TestModel>>`)
- add missing license headers
- make "post" more obvious
- use `Assert.IsAssignableFrom()`
nit: remove unused `using`s in `HtmlHelperLinkGenerationTest`
- helps w/ #453 since `Html.BeginForm()` wasn't previously tested
- provide a `DefaultTemplatesUtilities.GetHtmlHelper()` overload with an
`IHtmlGenerator` parameter
- update `DefaultTemplateUtilities` to use `DefaultHttpContext`
- stop using a mock for this purpose; provides a non-`null` `Request`
nit:
- `DefaultTemplatesUtilities.GetHtmlHelperForViewData()` -> `...GetHtmlHelper()`
for consistency with other overloads
This is the MVC companion to https://github.com/aspnet/Routing/pull/122
As routing flows, routes replace the route data and mutate a copy. This
allows users to make changes that dirty the data without affecting
undesired state changes.
We also add the 'next' router for diagnostic purposes.
- value may remain in the `FormContext` beyond `</select>` end tag but will
be cleaned up at the `</form>` end tag of the containing `<form/>` element
- `SelectTagHelper` called prior to helpers for contained `<option/>`s and
not again later
- adjust mock setups to handle new `GenerateSelect()` call
- add assertions for expected `FormContext.FormData` entry
nit: mention #1468 in a test comment
- use new `ModelMetadata.HtmlEncode` property in HTML helpers
- specifically in default HTML display and editor object templates (e.g.
`@Html.DisplayFor()`) when value is non-`null` and the template is invoked
with template depth greater than 1
- similar to MVC 5.2 commit [2b12791aee4f](https://aspnetwebstack.codeplex.com/SourceControl/changeset/2b12791aee4ffc56c7928b623bb45ee425813021)
nits:
- remove dupe `null` check in `DefaultDisplayTemplates.ObjectTemplate()`
- move backing fields initialized with constants together in `ModelMetadata`
The change here is to always use the provided formatter, instead of using
it as a fallback. This is much less surprising for users.
There are some other subtle changes here and cleanup of the tests, as well
as documentation additions.
The primary change is that we still want to run 'select' on a formatter
even if it's the only one. This allows us to choose a content type based
on the accept header.
In the case of a user-provided formatter, we'll try to honor the best
possible combination of Accept and specified ContentTypes (specified
ContentTypes win if there's a conflict). If nothing works, we'll still run
the user-provided formatter and let it decide what to do.
In the case of the default (formatters from options) we do conneg, and if
there's a conflict, fall back to a global (from services)
JsonOutputFormatter - we let it decide what to do.
This should leave us with a defined and tested behavior for all cases.
- 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`
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.
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.