From c116a38c87ef7a32f40659d393cae25677dfbdbd Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 2 Feb 2016 12:10:43 -0800 Subject: [PATCH] Reducing ModelBindingContext allocations Closes #4007, Fixes #3622, Fixes #3621 Squashed commit of the following: commit 4b3095671d945ae79baa4fc4ba22a2ce5ebe488e Author: Louis DeJardin Date: Mon Feb 1 15:05:58 2016 -0800 PR Feedback #4007 ModelBindingContext.ModelType. Need similar changes a couple of other places in this class. commit 7c45847d1d4c3eb02c48710bb4f100d4d1305385 Author: Louis DeJardin Date: Mon Feb 1 15:01:13 2016 -0800 PR Feedback #4007 Please clean out the now-extra added usings for System.Diagnostics. commit 13263fb29a0a12b472eab130eafe6760f6279262 Author: Louis DeJardin Date: Mon Feb 1 14:58:52 2016 -0800 PR Feedback #4007 Confusing to read: How can overallResult be non-null here? commit dfb52e1bd48397580eacf87be3541b159dbe79f1 Author: Louis DeJardin Date: Mon Feb 1 14:47:28 2016 -0800 PR Feedback #4007 End these new guys with a period. commit f4c745a0a805b960234cd4d810378bc40b8e5c8c Author: Louis DeJardin Date: Mon Feb 1 14:44:10 2016 -0800 Fixing unit tests Also fixes rebase error in CancellationTokenModelBinder commit f3874cc27388552e863d99d8e6631a2901f8e000 Author: Louis DeJardin Date: Mon Feb 1 13:01:02 2016 -0800 PR Feedback #4007 Remove commented-out code. commit 44ec1a5a3bd4fdeb4d1c4de9f0b402ff0fd34ffe Author: Louis DeJardin Date: Mon Feb 1 12:22:04 2016 -0800 PR Feedback #4007 Why now public? commit 9aa45eda42ec9b11b7e6b73a14e887f1be8cb130 Author: Louis DeJardin Date: Mon Feb 1 12:18:19 2016 -0800 PR Feedback #4007 Leave out .Test commit 58d32d809797d25cc9b5b4c0516ae9e5992fa66e Author: Louis DeJardin Date: Fri Jan 29 15:41:14 2016 -0800 PR Feedback #4007 By making this async, we've undone an optimization here. Notice BindModelAync now has a state machine. commit f7503228b77803b786c19e06e60f618f6f5e15c5 Author: Louis DeJardin Date: Fri Jan 29 15:30:54 2016 -0800 PR Feedback #4007 Don't need extra line commit cf26f3e5125792d6af0ca2afda672e241fe0e164 Author: Louis DeJardin Date: Fri Jan 29 15:28:23 2016 -0800 PR Feedback #4007 No longer need most of the using System.Diagnostics additions commit e90c40c4e4315462efc9ade1585e2e8c085588a4 Author: Louis DeJardin Date: Fri Jan 29 15:12:50 2016 -0800 PR Feedback #4007 Suggest Microsoft.AspNetCore.Mvc.Internal. commit 5360599e9c09ab97b8136977ee0917fd88f51f76 Author: Louis DeJardin Date: Fri Jan 29 14:57:28 2016 -0800 PR Feedback #4007 Remove this line. commit ce63edba51721412684a54886109e6b2225c6c99 Author: Louis DeJardin Date: Fri Jan 29 14:14:02 2016 -0800 PR Feedback #4007 incorrect mentions of DefaultModelBindingContext in doc comments commit bbc738ca2304243839e8d68615ff4bbf14f3279c Author: Louis DeJardin Date: Fri Jan 29 13:59:50 2016 -0800 PR Feedback #4007 Could we convert most of these setups to avoid the "async but not await" mess? commit 0827e6917481e3fafb2905a3fa93cf90afb9be40 Author: Louis DeJardin Date: Fri Jan 29 11:02:00 2016 -0800 PR Feedback #4007 remove the file commit 3dd0d10d7f16c94df5f6d34ecb5f2efda62bccd8 Author: Louis DeJardin Date: Thu Jan 28 13:34:31 2016 -0800 Revert "PR Feedback" This reverts commit 589d3e65d406b127a0b833d86c05ad4a8c5172c8. It seems the assignment of these properties is not appropriate in both cases. commit c8a97ada63fa16ee7df6c165031bf15b1c23e8a2 Author: Louis DeJardin Date: Thu Jan 28 12:37:18 2016 -0800 PR Feedback DefaultModelBindingContext should not be in Abstractions commit 5e3b6a1486283f45867830693d4fd23cc967f06f Author: Louis DeJardin Date: Thu Jan 28 12:35:28 2016 -0800 PR Feedback Is it still needed and, if so, where does the problem lie? commit 44635a75af05034863f0d4b80b2eb857d43766b2 Author: Louis DeJardin Date: Thu Jan 28 11:06:26 2016 -0800 PR Feedback * this is either supported (shouldn't assert) or not supported (should throw). I don't feel like these asserts add much value * this isn't something that should throw commit 648975cad14ac5e3738ea454c490ca221f650155 Author: Louis DeJardin Date: Thu Jan 28 10:54:28 2016 -0800 PR Feedback remove the other static constructors for Task they don't have a purpose anymore commit d0e15211530668ec21406121342715b0d0f606a6 Author: Louis DeJardin Date: Thu Jan 28 10:51:24 2016 -0800 PR Feedback the reason for the separation was to put the implementation somewhere else commit 2caf88df7a37664db829d660cbb5266cf6871f2c Author: Louis DeJardin Date: Thu Jan 28 10:48:25 2016 -0800 PR Feedback * coding standards... * yea * private readonly commit 6c2c640611686a554a8c417a407fe169c45a690e Author: Louis DeJardin Date: Thu Jan 28 10:46:12 2016 -0800 PR Feedback * disposable -> * Fill in the blanks. commit df07891c798627ac9c8fce6a7598d9386e979615 Author: Louis DeJardin Date: Thu Jan 28 10:44:07 2016 -0800 PR Feedback Value to assign to the ... for modelName and model as well. commit 8e9ade7378577eddc0ba8e939deafe8d12781b8a Author: Louis DeJardin Date: Thu Jan 28 10:43:50 2016 -0800 PR Feedback Should this just be an abstract class rather than an interface? commit a66685e2470a84b0acbf4e797eff5010a1a066ab Author: Louis DeJardin Date: Wed Jan 27 23:47:44 2016 -0800 PR Feedback Suggest resetting FallbackToEmptyPrefix for current context as part of PushContext(). commit d85e66f59d24e0959652f1683cb94c4b513d75c0 Author: Louis DeJardin Date: Wed Jan 27 23:34:42 2016 -0800 PR Feedback Add a using for the Internal namespace. commit bef09536f881d400f15a83b7788c828903679a38 Author: Louis DeJardin Date: Wed Jan 27 23:27:30 2016 -0800 PR Feedback needs lots of /// doc love and blank lines commit 4173488112f2889d662d5a7c55f249aefa821c22 Author: Louis DeJardin Date: Wed Jan 27 23:06:49 2016 -0800 PR Feedback Temp file accidentally added. Oops. commit 6790d6104d5bd72ce7eab270bfe9a360cacf74f2 Author: Louis DeJardin Date: Wed Jan 27 23:04:40 2016 -0800 PR Feedback please remove the else bits after returns commit 8d077ee27109133d18c5cddfe3b9b6c6e9a40e0e Author: Louis DeJardin Date: Wed Jan 27 22:57:38 2016 -0800 PR Feedback The code at one point matched the comment -- always returning something other than NoResult. Likely the comment needs to change. commit 0ea6c2186212444f46c7a48394b86b14190a9026 Author: Louis DeJardin Date: Wed Jan 27 22:50:02 2016 -0800 PR Feedback Don't recall why this was virtual but why remove that? commit 0b27f3e62df6836e6e8751967c47c6192c3eec9a Author: Louis DeJardin Date: Wed Jan 27 22:35:57 2016 -0800 PR Feedback No need for this line; just asserted that Result is already null. commit c85648bb680bdbdb33381cd1af91133d04d56592 Author: Louis DeJardin Date: Wed Jan 27 22:34:26 2016 -0800 PR Feedback Comment needs some love since NoResult is no more. commit a606cf32386de9e4566a678b34a195cc0720211a Author: Louis DeJardin Date: Wed Jan 27 22:18:55 2016 -0800 PR Feedback * Long enough to start wrapping this. Same for a few other properties in this class. * Why is this check debug-only? * /// docs and some blank lines between members commit 7efce5675a78350a4a7fde4b54fcb7886fe18252 Author: Louis DeJardin Date: Wed Jan 27 20:29:50 2016 -0800 PR Feedback Why not use the Task helper used elsewhere? commit eb5fe6f95a463eb2f162f51649ffea57db87e286 Author: Louis DeJardin Date: Wed Jan 27 20:28:31 2016 -0800 PR Feedback Sort usings commit df3bd00c4b59d2434e3a7be28e637d3c8008ae32 Author: Louis DeJardin Date: Wed Jan 27 20:27:38 2016 -0800 PR Feedback Dead code commit fe7ec17fbb5209f2904f067ec1f91169ab05fb33 Author: Louis DeJardin Date: Wed Jan 27 20:26:04 2016 -0800 PR Feedback Putting internal back in place commit 496f1f97ac48b2e95572dd6d463ced3366f8d36c Author: Louis DeJardin Date: Wed Jan 27 20:21:03 2016 -0800 PR Feedback stylecop 13040: Move these to the top of the file. commit cd003d0bca6516a907a0ae889d2e6130ff473b57 Author: Louis DeJardin Date: Wed Jan 27 19:38:15 2016 -0800 Renames to asp.net core commit e1cf523119084e35b70f11f67f64f651c39e1c8b Author: Louis DeJardin Date: Thu Jan 21 21:21:44 2016 -0800 Removing NoResult and fixing tests commit 5af6223a4d60b6c4139c1fc62ebf297ab0e5454f Author: Louis DeJardin Date: Thu Dec 17 11:49:08 2015 -0800 Reducing ModelBindingContext allocations --- Mvc.NoFun.sln | 1 + .../ModelBinding/IModelBinder.cs | 4 +- .../ModelBinding/ModelBindingContext.cs | 375 ++++++------------ .../ModelBinding/ModelBindingResult.cs | 48 +-- .../Internal/ControllerArgumentBinder.cs | 17 +- .../Internal/DefaultModelBindingContext.cs | 323 +++++++++++++++ .../ModelBinding/ArrayModelBinder.cs | 5 +- .../BinderTypeBasedModelBinder.cs | 25 +- .../ModelBinding/BodyModelBinder.cs | 23 +- .../ModelBinding/ByteArrayModelBinder.cs | 17 +- .../CancellationTokenModelBinder.cs | 13 +- .../ModelBinding/CollectionModelBinder.cs | 59 +-- .../ModelBinding/CompositeModelBinder.cs | 129 +++--- .../ModelBinding/DictionaryModelBinder.cs | 41 +- .../ModelBinding/FormCollectionModelBinder.cs | 9 +- .../ModelBinding/FormFileModelBinder.cs | 15 +- .../ModelBinding/GenericModelBinder.cs | 28 +- .../ModelBinding/HeaderModelBinder.cs | 18 +- .../ModelBinding/KeyValuePairModelBinder.cs | 77 ++-- .../Metadata/DefaultModelMetadata.cs | 7 - .../ModelBinding/ModelBindingHelper.cs | 11 +- .../ModelBinding/MutableObjectModelBinder.cs | 52 +-- .../ModelBinding/ServicesModelBinder.cs | 15 +- .../ModelBinding/SimpleTypeModelBinder.cs | 21 +- .../HttpRequestMessageModelBinder.cs | 7 +- .../BindAttributeTest.cs | 6 +- .../ControllerBaseTest.cs | 244 +++++------- .../Internal/ControllerActionInvokerTest.cs | 4 +- .../Internal/ControllerArgumentBinderTests.cs | 73 ++-- .../Internal/ModelBinderExtensions.cs | 15 + .../ModelBinding/ArrayModelBinderTest.cs | 52 ++- ...nderTypeBasedModelBinderModelBinderTest.cs | 27 +- .../ModelBinding/BodyModelBinderTests.cs | 26 +- .../ModelBinding/ByteArrayModelBinderTests.cs | 16 +- .../CancellationTokenModelBinderTests.cs | 12 +- .../ModelBinding/CollectionModelBinderTest.cs | 89 ++--- .../ModelBinding/CompositeModelBinderTest.cs | 284 +++++-------- .../DefaultModelBindingContextTest.cs | 96 +++++ .../ModelBinding/DictionaryModelBinderTest.cs | 67 ++-- .../FormCollectionModelBinderTest.cs | 20 +- .../ModelBinding/FormFileModelBinderTest.cs | 48 +-- .../ModelBinding/HeaderModelBinderTests.cs | 28 +- .../KeyValuePairModelBinderTest.cs | 97 ++--- .../ModelBinding/ModelBindingContextTest.cs | 80 ---- .../ModelBinding/ModelBindingHelperTest.cs | 55 +-- .../ModelBinding/ModelBindingResultTest.cs | 57 +-- .../MutableObjectModelBinderTest.cs | 71 ++-- .../ModelBinding/ServicesModelBinderTest.cs | 20 +- .../ModelBinding/SimpleTypeModelBinderTest.cs | 30 +- .../ModelBinding/StubModelBinder.cs | 74 ++++ .../Internal/ModelMetadataProviderTest.cs | 2 +- .../ActionParametersIntegrationTest.cs | 16 +- .../ArrayModelBinderIntegrationTest.cs | 16 +- ...nderTypeBasedModelBinderIntegrationTest.cs | 74 +++- .../BodyValidationIntegrationTests.cs | 28 +- .../ByteArrayModelBinderIntegrationTest.cs | 8 +- ...ellationTokenModelBinderIntegrationTest.cs | 6 +- .../CollectionModelBinderIntegrationTest.cs | 34 +- .../DictionaryModelBinderIntegrationTest.cs | 22 +- ...rmCollectionModelBindingIntegrationTest.cs | 6 +- .../FormFileModelBindingIntegrationTest.cs | 8 +- .../GenericModelBinderIntegrationTest.cs | 45 ++- .../HeaderModelBinderIntegrationTest.cs | 8 +- .../KeyValuePairModelBinderIntegrationTest.cs | 24 +- .../ModelPrefixSelectionIntegrationTest.cs | 10 +- ...MutableObjectModelBinderIntegrationTest.cs | 86 ++-- .../ServicesModelBinderIntegrationTest.cs | 8 +- .../SimpleTypeModelBinderIntegrationTest.cs | 24 +- .../ValidationIntegrationTests.cs | 56 +-- .../HttpRequestMessageModelBinderTest.cs | 14 +- 70 files changed, 1794 insertions(+), 1632 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultModelBindingContext.cs create mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ModelBinderExtensions.cs create mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DefaultModelBindingContextTest.cs delete mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingContextTest.cs create mode 100644 test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/StubModelBinder.cs diff --git a/Mvc.NoFun.sln b/Mvc.NoFun.sln index cab458c988..166b89b514 100644 --- a/Mvc.NoFun.sln +++ b/Mvc.NoFun.sln @@ -28,6 +28,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}" ProjectSection(SolutionItems) = preProject global.json = global.json + NuGet.config = NuGet.config NuGetPackageVerifier.json = NuGetPackageVerifier.json EndProjectSection EndProject diff --git a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/IModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/IModelBinder.cs index 834886d712..948af2f376 100644 --- a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/IModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/IModelBinder.cs @@ -24,9 +24,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// with . If model binding failed, the /// should be a value created with . /// If there was no data, or this model binder cannot handle the operation, the - /// should be . + /// should be null. /// /// - Task BindModelAsync(ModelBindingContext bindingContext); + Task BindModelAsync(ModelBindingContext bindingContext); } } diff --git a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingContext.cs b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingContext.cs index 7530c5fcf9..35690dc1e1 100644 --- a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingContext.cs +++ b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -9,248 +9,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// /// A context that contains operating information for model binding and validation. /// - public class ModelBindingContext + public abstract class ModelBindingContext { - private string _fieldName; - private ModelMetadata _modelMetadata; - private string _modelName; - private ModelStateDictionary _modelState; - private OperationBindingContext _operationBindingContext; - private IValueProvider _valueProvider; - - /// - /// Initializes a new instance of the class. - /// - public ModelBindingContext() - { - } - - /// - /// Creates a new for top-level model binding operation. - /// - /// - /// The associated with the binding operation. - /// - /// associated with the model. - /// associated with the model. - /// The name of the property or parameter being bound. - /// A new instance of . - public static ModelBindingContext CreateBindingContext( - OperationBindingContext operationBindingContext, - ModelMetadata metadata, - BindingInfo bindingInfo, - string modelName) - { - if (operationBindingContext == null) - { - throw new ArgumentNullException(nameof(operationBindingContext)); - } - - if (metadata == null) - { - throw new ArgumentNullException(nameof(metadata)); - } - - if (modelName == null) - { - throw new ArgumentNullException(nameof(modelName)); - } - - var binderModelName = bindingInfo?.BinderModelName ?? metadata.BinderModelName; - var propertyPredicateProvider = - bindingInfo?.PropertyBindingPredicateProvider ?? metadata.PropertyBindingPredicateProvider; - - return new ModelBindingContext() - { - BinderModelName = binderModelName, - BindingSource = bindingInfo?.BindingSource ?? metadata.BindingSource, - BinderType = bindingInfo?.BinderType ?? metadata.BinderType, - PropertyFilter = propertyPredicateProvider?.PropertyFilter, - - // We only support fallback to empty prefix in cases where the model name is inferred from - // the parameter or property being bound. - FallbackToEmptyPrefix = binderModelName == null, - - // Because this is the top-level context, FieldName and ModelName should be the same. - FieldName = binderModelName ?? modelName, - ModelName = binderModelName ?? modelName, - - IsTopLevelObject = true, - ModelMetadata = metadata, - ModelState = operationBindingContext.ActionContext.ModelState, - OperationBindingContext = operationBindingContext, - ValueProvider = operationBindingContext.ValueProvider, - - ValidationState = new ValidationStateDictionary(), - }; - } - - public static ModelBindingContext CreateChildBindingContext( - ModelBindingContext parent, - ModelMetadata modelMetadata, - string fieldName, - string modelName, - object model) - { - if (parent == null) - { - throw new ArgumentNullException(nameof(parent)); - } - - if (modelMetadata == null) - { - throw new ArgumentNullException(nameof(modelMetadata)); - } - - if (fieldName == null) - { - throw new ArgumentNullException(nameof(fieldName)); - } - - if (modelName == null) - { - throw new ArgumentNullException(nameof(modelName)); - } - - return new ModelBindingContext() - { - ModelState = parent.ModelState, - OperationBindingContext = parent.OperationBindingContext, - ValueProvider = parent.ValueProvider, - ValidationState = parent.ValidationState, - - Model = model, - ModelMetadata = modelMetadata, - ModelName = modelName, - FieldName = fieldName, - BinderModelName = modelMetadata.BinderModelName, - BinderType = modelMetadata.BinderType, - BindingSource = modelMetadata.BindingSource, - PropertyFilter = modelMetadata.PropertyBindingPredicateProvider?.PropertyFilter, - }; - } - - /// - /// Represents the associated with this context. - /// - public OperationBindingContext OperationBindingContext - { - get { return _operationBindingContext; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _operationBindingContext = value; - } - } - - /// - /// Gets or sets the name of the current field being bound. - /// - public string FieldName - { - get { return _fieldName; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _fieldName = value; - } - } - - /// - /// Gets or sets the model value for the current operation. - /// - /// - /// The will typically be set for a binding operation that works - /// against a pre-existing model object to update certain properties. - /// - public object Model { get; set; } - - /// - /// Gets or sets the metadata for the model associated with this context. - /// - public ModelMetadata ModelMetadata - { - get { return _modelMetadata; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _modelMetadata = value; - } - } - - /// - /// Gets or sets the name of the model. This property is used as a key for looking up values in - /// during model binding. - /// - public string ModelName - { - get { return _modelName; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _modelName = value; - } - } - - /// - /// Gets or sets the used to capture values - /// for properties in the object graph of the model when binding. - /// - public ModelStateDictionary ModelState - { - get { return _modelState; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _modelState = value; - } - } - - /// - /// Gets the type of the model. - /// - /// - /// The property must be set to access this property. - /// - public Type ModelType => ModelMetadata?.ModelType; - /// /// Gets or sets a model name which is explicitly set using an . - /// . /// - public string BinderModelName { get; set; } - - /// - /// Gets or sets a value which represents the associated with the - /// . - /// - public BindingSource BindingSource { get; set; } + public abstract string BinderModelName { get; set; } /// /// Gets the of an associated with the /// . /// - public Type BinderType { get; set; } + public abstract Type BinderType { get; set; } + + /// + /// Gets or sets a value which represents the associated with the + /// . + /// + public abstract BindingSource BindingSource { get; set; } /// /// Gets or sets a value that indicates whether the binder should use an empty prefix to look up @@ -260,41 +36,138 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// Passed into the model binding system. Should not be true when is /// false. /// - public bool FallbackToEmptyPrefix { get; set; } + public abstract bool FallbackToEmptyPrefix { get; set; } + + /// + /// Gets or sets the name of the current field being bound. + /// + public abstract string FieldName { get; set; } /// /// Gets or sets an indication that the current binder is handling the top-level object. /// /// Passed into the model binding system. - public bool IsTopLevelObject { get; set; } + public abstract bool IsTopLevelObject { get; set; } /// - /// Gets or sets the associated with this context. + /// Gets or sets the model value for the current operation. /// - public IValueProvider ValueProvider - { - get { return _valueProvider; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } + /// + /// The will typically be set for a binding operation that works + /// against a pre-existing model object to update certain properties. + /// + public abstract object Model { get; set; } - _valueProvider = value; - } - } + /// + /// Gets or sets the metadata for the model associated with this context. + /// + public abstract ModelMetadata ModelMetadata { get; set; } + + /// + /// Gets or sets the name of the model. This property is used as a key for looking up values in + /// during model binding. + /// + public abstract string ModelName { get; set; } + + /// + /// Gets or sets the used to capture values + /// for properties in the object graph of the model when binding. + /// + public abstract ModelStateDictionary ModelState { get; set; } + + /// + /// Gets the type of the model. + /// + /// + /// The property must be set to access this property. + /// + public abstract Type ModelType { get; } + + /// + /// Represents the associated with this context. + /// + public abstract OperationBindingContext OperationBindingContext { get; set; } /// /// Gets or sets a predicate which will be evaluated for each property to determine if the property /// is eligible for model binding. /// - public Func PropertyFilter { get; set; } + public abstract Func PropertyFilter { get; set; } /// /// Gets or sets the . Used for tracking validation state to /// customize validation behavior for a model object. /// - public ValidationStateDictionary ValidationState { get; set; } + public abstract ValidationStateDictionary ValidationState { get; set; } + + /// + /// Gets or sets the associated with this context. + /// + public abstract IValueProvider ValueProvider { get; set; } + + /// + /// + /// On completion returns a which + /// represents the result of the model binding process. + /// + /// + /// If model binding was successful, the should be a value created + /// with . If model binding failed, the + /// should be a value created with . + /// If there was no data, or this model binder cannot handle the operation, the + /// should be null. + /// + /// + public abstract ModelBindingResult? Result { get; set; } + + /// + /// Pushes a layer of state onto this context. Model binders will call this as part of recursion when binding properties + /// or collection items. + /// + /// to assign to the property. + /// Name to assign to the property. + /// Name to assign to the property. + /// Instance to assign to the property. + /// A scope object which should be used in a using statement where PushContext is called. + public abstract NestedScope EnterNestedScope(ModelMetadata modelMetadata, string fieldName, string modelName, object model); + + /// + /// Pushes a layer of state onto this context. Model binders will call this as part of recursion when binding properties + /// or collection items. + /// + /// A scope object which should be used in a using statement where PushContext is called. + public abstract NestedScope EnterNestedScope(); + + /// + /// Removes a layer of state pushed by calling . + /// + protected abstract void ExitNestedScope(); + + /// + /// Return value of . Should be disposed + /// by caller when child binding context state should be popped off of + /// the . + /// + public struct NestedScope : IDisposable + { + private readonly ModelBindingContext _context; + + /// + /// Initializes the for a . + /// + /// + public NestedScope(ModelBindingContext context) + { + _context = context; + } + + /// + /// Exits the created by calling . + /// + public void Dispose() + { + _context.ExitNestedScope(); + } + } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingResult.cs b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingResult.cs index 7ea7457dd3..72f63cc851 100644 --- a/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingResult.cs +++ b/src/Microsoft.AspNetCore.Mvc.Abstractions/ModelBinding/ModelBindingResult.cs @@ -12,18 +12,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// public struct ModelBindingResult : IEquatable { - /// - /// A representing the lack of a result. The model binding - /// system will continue to execute other model binders. - /// - public static readonly ModelBindingResult NoResult = new ModelBindingResult(); - - /// - /// Returns a completed representing the lack of a result. The model - /// binding system will continue to execute other model binders. - /// - public static readonly Task NoResultAsync = Task.FromResult(NoResult); - /// /// Creates a representing a failed model binding operation. /// @@ -38,22 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding return new ModelBindingResult(key, model: null, isModelSet: false); } - - /// - /// Creates a completed representing a failed model binding operation. - /// - /// The key of the current model binding operation. - /// A completed representing a failed model binding operation. - public static Task FailedAsync(string key) - { - if (key == null) - { - throw new ArgumentNullException(nameof(key)); - } - - return Task.FromResult(Failed(key)); - } - + /// /// Creates a representing a successful model binding operation. /// @@ -72,25 +45,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding return new ModelBindingResult(key, model, isModelSet: true); } - /// - /// Creates a completed representing a successful model binding - /// operation. - /// - /// The key of the current model binding operation. - /// The model value. May be null. - /// A completed representing a successful model bind. - public static Task SuccessAsync( - string key, - object model) - { - if (key == null) - { - throw new ArgumentNullException(nameof(key)); - } - - return Task.FromResult(Success(key, model)); - } - private ModelBindingResult(string key, object model, bool isModelSet) { Key = key; diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerArgumentBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerArgumentBinder.cs index d632b1f68e..89408ec0e1 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerArgumentBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/ControllerArgumentBinder.cs @@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal return actionArguments; } - public async Task BindModelAsync( + public async Task BindModelAsync( ParameterDescriptor parameter, OperationBindingContext operationContext) { @@ -112,21 +112,22 @@ namespace Microsoft.AspNetCore.Mvc.Internal } var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType); - var modelBindingContext = ModelBindingContext.CreateBindingContext( + var modelBindingContext = DefaultModelBindingContext.CreateBindingContext( operationContext, metadata, parameter.BindingInfo, parameter.Name); - var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext); - if (modelBindingResult.IsModelSet) + await operationContext.ModelBinder.BindModelAsync(modelBindingContext); + var modelBindingResult = modelBindingContext.Result; + if (modelBindingResult != null && modelBindingResult.Value.IsModelSet) { _validator.Validate( operationContext.ActionContext, operationContext.ValidatorProvider, modelBindingContext.ValidationState, - modelBindingResult.Key, - modelBindingResult.Model); + modelBindingResult.Value.Key, + modelBindingResult.Value.Model); } return modelBindingResult; @@ -225,9 +226,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal { var parameter = parameterMetadata[i]; var modelBindingResult = await BindModelAsync(parameter, operationContext); - if (modelBindingResult.IsModelSet) + if (modelBindingResult != null && modelBindingResult.Value.IsModelSet) { - arguments[parameter.Name] = modelBindingResult.Model; + arguments[parameter.Name] = modelBindingResult.Value.Model; } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultModelBindingContext.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultModelBindingContext.cs new file mode 100644 index 0000000000..5a2027bfb2 --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/DefaultModelBindingContext.cs @@ -0,0 +1,323 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; + +namespace Microsoft.AspNetCore.Mvc.ModelBinding +{ + /// + /// A context that contains operating information for model binding and validation. + /// + public class DefaultModelBindingContext : ModelBindingContext + { + private State _state; + private readonly Stack _stack = new Stack(); + + /// + /// Initializes a new instance of the class. + /// + public DefaultModelBindingContext() + { + } + + /// + /// Creates a new for top-level model binding operation. + /// + /// + /// The associated with the binding operation. + /// + /// associated with the model. + /// associated with the model. + /// The name of the property or parameter being bound. + /// A new instance of . + public static ModelBindingContext CreateBindingContext( + OperationBindingContext operationBindingContext, + ModelMetadata metadata, + BindingInfo bindingInfo, + string modelName) + { + if (operationBindingContext == null) + { + throw new ArgumentNullException(nameof(operationBindingContext)); + } + + if (metadata == null) + { + throw new ArgumentNullException(nameof(metadata)); + } + + if (modelName == null) + { + throw new ArgumentNullException(nameof(modelName)); + } + + var binderModelName = bindingInfo?.BinderModelName ?? metadata.BinderModelName; + var propertyPredicateProvider = + bindingInfo?.PropertyBindingPredicateProvider ?? metadata.PropertyBindingPredicateProvider; + + return new DefaultModelBindingContext() + { + BinderModelName = binderModelName, + BindingSource = bindingInfo?.BindingSource ?? metadata.BindingSource, + BinderType = bindingInfo?.BinderType ?? metadata.BinderType, + PropertyFilter = propertyPredicateProvider?.PropertyFilter, + + // We only support fallback to empty prefix in cases where the model name is inferred from + // the parameter or property being bound. + FallbackToEmptyPrefix = binderModelName == null, + + // Because this is the top-level context, FieldName and ModelName should be the same. + FieldName = binderModelName ?? modelName, + ModelName = binderModelName ?? modelName, + + IsTopLevelObject = true, + ModelMetadata = metadata, + ModelState = operationBindingContext.ActionContext.ModelState, + OperationBindingContext = operationBindingContext, + ValueProvider = operationBindingContext.ValueProvider, + + ValidationState = new ValidationStateDictionary(), + }; + } + + /// + public override NestedScope EnterNestedScope( + ModelMetadata modelMetadata, + string fieldName, + string modelName, + object model) + { + if (modelMetadata == null) + { + throw new ArgumentNullException(nameof(modelMetadata)); + } + + if (fieldName == null) + { + throw new ArgumentNullException(nameof(fieldName)); + } + + if (modelName == null) + { + throw new ArgumentNullException(nameof(modelName)); + } + + var scope = EnterNestedScope(); + + Model = model; + ModelMetadata = modelMetadata; + ModelName = modelName; + FieldName = fieldName; + BinderModelName = modelMetadata.BinderModelName; + BinderType = modelMetadata.BinderType; + BindingSource = modelMetadata.BindingSource; + PropertyFilter = modelMetadata.PropertyBindingPredicateProvider?.PropertyFilter; + + FallbackToEmptyPrefix = false; + IsTopLevelObject = false; + + return scope; + } + + /// + public override NestedScope EnterNestedScope() + { + _stack.Push(_state); + + Result = null; + + return new NestedScope(this); + } + + /// + protected override void ExitNestedScope() + { + _state = _stack.Pop(); + } + + /// + public override OperationBindingContext OperationBindingContext + { + get { return _state.OperationBindingContext; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _state.OperationBindingContext = value; + } + } + + /// + public override string FieldName + { + get { return _state.FieldName; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _state.FieldName = value; + } + } + + /// + public override object Model + { + get { return _state.Model; } + set { _state.Model = value; } + } + + /// + public override ModelMetadata ModelMetadata + { + get { return _state.ModelMetadata; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _state.ModelMetadata = value; + } + } + + /// + public override string ModelName + { + get { return _state.ModelName; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _state.ModelName = value; + } + } + + /// + public override ModelStateDictionary ModelState + { + get { return _state.ModelState; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _state.ModelState = value; + } + } + + /// + public override Type ModelType => ModelMetadata?.ModelType; + + /// + public override string BinderModelName + { + get { return _state.BinderModelName; } + set { _state.BinderModelName = value; } + } + + /// + public override BindingSource BindingSource + { + get { return _state.BindingSource; } + set { _state.BindingSource = value; } + } + + /// + public override Type BinderType + { + get { return _state.BinderType; } + set { _state.BinderType = value; } + } + + /// + public override bool FallbackToEmptyPrefix + { + get { return _state.FallbackToEmptyPrefix; } + set { _state.FallbackToEmptyPrefix = value; } + } + + /// + public override bool IsTopLevelObject + { + get { return _state.IsTopLevelObject; } + set { _state.IsTopLevelObject = value; } + } + + /// + public override IValueProvider ValueProvider + { + get { return _state.ValueProvider; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _state.ValueProvider = value; + } + } + + /// + public override Func PropertyFilter + { + get { return _state.PropertyFilter; } + set { _state.PropertyFilter = value; } + } + + /// + public override ValidationStateDictionary ValidationState + { + get { return _state.ValidationState; } + set { _state.ValidationState = value; } + } + + /// + public override ModelBindingResult? Result + { + get + { + return _state.Result; + } + set + { + if (value.HasValue && value.Value == default(ModelBindingResult)) + { + throw new ArgumentException(nameof(ModelBindingResult)); + } + + _state.Result = value; + } + } + + private struct State + { + public OperationBindingContext OperationBindingContext; + public string FieldName; + public object Model; + public ModelMetadata ModelMetadata; + public string ModelName; + + public IValueProvider ValueProvider; + public Func PropertyFilter; + public ValidationStateDictionary ValidationState; + public ModelStateDictionary ModelState; + + public string BinderModelName; + public BindingSource BindingSource; + public Type BinderType; + public bool FallbackToEmptyPrefix; + public bool IsTopLevelObject; + + public ModelBindingResult? Result; + }; + } +} diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ArrayModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ArrayModelBinder.cs index 1c2a55ea28..a0d092a2b3 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ArrayModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ArrayModelBinder.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { @@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class ArrayModelBinder : CollectionModelBinder { /// - public override Task BindModelAsync(ModelBindingContext bindingContext) + public override Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (bindingContext.ModelMetadata.IsReadOnly) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return base.BindModelAsync(bindingContext); diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BinderTypeBasedModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BinderTypeBasedModelBinder.cs index a62f86b59a..3e2676931c 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BinderTypeBasedModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BinderTypeBasedModelBinder.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Core; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Mvc.ModelBinding @@ -21,23 +22,28 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding private readonly ConcurrentDictionary _typeActivatorCache = new ConcurrentDictionary(); - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task. if (bindingContext.BinderType == null) { - // Return NoResult so that we are able to continue with the default set of model binders, + // Return null so that we are able to continue with the default set of model binders, // if there is no specific model binder provided. - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return BindModelCoreAsync(bindingContext); } - private async Task BindModelCoreAsync(ModelBindingContext bindingContext) + private async Task BindModelCoreAsync(ModelBindingContext bindingContext) { var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; var createFactory = _typeActivatorCache.GetOrAdd(bindingContext.BinderType, _createFactory); @@ -52,15 +58,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding typeof(IModelBinder).FullName)); } - var result = await modelBinder.BindModelAsync(bindingContext); - - var modelBindingResult = result != ModelBindingResult.NoResult ? - result : - ModelBindingResult.Failed(bindingContext.ModelName); + await modelBinder.BindModelAsync(bindingContext); // A model binder was specified by metadata and this binder handles all such cases. // Always tell the model binding system to skip other model binders i.e. return non-null. - return modelBindingResult; + if (bindingContext.Result == null) + { + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + } } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BodyModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BodyModelBinder.cs index f854657dd1..e9b673cad7 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BodyModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/BodyModelBinder.cs @@ -33,8 +33,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task. @@ -45,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Formatters are opt-in. This model either didn't specify [FromBody] or specified something // incompatible so let other binders run. - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return BindModelCoreAsync(bindingContext); @@ -58,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// /// A which when completed returns a . /// - private async Task BindModelCoreAsync(ModelBindingContext bindingContext) + private async Task BindModelCoreAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -101,7 +106,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // This model binder is the only handler for the Body binding source and it cannot run twice. Always // tell the model binding system to skip other model binders and never to fall back i.e. indicate a // fatal error. - return ModelBindingResult.Failed(modelBindingKey); + bindingContext.Result = ModelBindingResult.Failed(modelBindingKey); + return; } try @@ -114,10 +120,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Formatter encountered an error. Do not use the model it returned. As above, tell the model // binding system to skip other model binders and never to fall back. - return ModelBindingResult.Failed(modelBindingKey); + bindingContext.Result = ModelBindingResult.Failed(modelBindingKey); + return; } - return ModelBindingResult.Success(modelBindingKey, model); + bindingContext.Result = ModelBindingResult.Success(modelBindingKey, model); + return; } catch (Exception ex) { @@ -126,7 +134,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // This model binder is the only handler for the Body binding source and it cannot run twice. Always // tell the model binding system to skip other model binders and never to fall back i.e. indicate a // fatal error. - return ModelBindingResult.Failed(modelBindingKey); + bindingContext.Result = ModelBindingResult.Failed(modelBindingKey); + return; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs index 399e6fc3a7..ad22b699e7 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { @@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class ByteArrayModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -26,14 +27,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Check if this binder applies. if (bindingContext.ModelType != typeof(byte[])) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } // Check for missing data case 1: There was no element containing this data. var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); @@ -42,13 +44,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var value = valueProviderResult.FirstValue; if (string.IsNullOrEmpty(value)) { - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } try { var model = Convert.FromBase64String(value); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return TaskCache.CompletedTask; } catch (Exception exception) { @@ -60,7 +64,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Matched the type (byte[]) only this binder supports. As in missing data cases, always tell the model // binding system to skip other model binders i.e. return non-null. - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CancellationTokenModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CancellationTokenModelBinder.cs index 0b0097e254..560a6831ab 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CancellationTokenModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CancellationTokenModelBinder.cs @@ -1,9 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using Microsoft.AspNetCore.Mvc.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { @@ -13,8 +15,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class CancellationTokenModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + if (bindingContext.ModelType == typeof(CancellationToken)) { // We need to force boxing now, so we can insert the same reference to the boxed CancellationToken @@ -23,10 +30,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // DO NOT simplify this code by removing the cast. var model = (object)bindingContext.OperationBindingContext.HttpContext.RequestAborted; bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); } - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CollectionModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CollectionModelBinder.cs index ead04b7c9f..2d261f92cb 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CollectionModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CollectionModelBinder.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class CollectionModelBinder : ICollectionModelBinder { /// - public virtual async Task BindModelAsync(ModelBindingContext bindingContext) + public virtual async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -44,10 +44,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding model = CreateEmptyCollection(bindingContext.ModelType); } - return ModelBindingResult.Success(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return; } - return ModelBindingResult.NoResult; + return; } var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); @@ -91,7 +92,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding valueProviderResult); } - return ModelBindingResult.Success(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return; } /// @@ -147,16 +149,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var elementMetadata = metadataProvider.GetMetadataForType(typeof(TElement)); - var innerBindingContext = ModelBindingContext.CreateChildBindingContext( - bindingContext, - elementMetadata, - fieldName: bindingContext.FieldName, - modelName: bindingContext.ModelName, - model: null); foreach (var value in values) { - innerBindingContext.ValueProvider = new CompositeValueProvider + bindingContext.ValueProvider = new CompositeValueProvider { // our temporary provider goes at the front of the list new ElementalValueProvider(bindingContext.ModelName, value, values.Culture), @@ -164,12 +160,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding }; object boundValue = null; - var result = - await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(innerBindingContext); - if (result != null && result.IsModelSet) + + using (bindingContext.EnterNestedScope( + elementMetadata, + fieldName: bindingContext.FieldName, + modelName: bindingContext.ModelName, + model: null)) { - boundValue = result.Model; - boundCollection.Add(ModelBindingHelper.CastOrDefault(boundValue)); + await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(bindingContext); + + if (bindingContext.Result != null && bindingContext.Result.Value.IsModelSet) + { + boundValue = bindingContext.Result.Value.Model; + boundCollection.Add(ModelBindingHelper.CastOrDefault(boundValue)); + } } } @@ -214,23 +218,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding foreach (var indexName in indexNames) { var fullChildName = ModelNames.CreateIndexModelName(bindingContext.ModelName, indexName); - var childBindingContext = ModelBindingContext.CreateChildBindingContext( - bindingContext, - elementMetadata, - fieldName: indexName, - modelName: fullChildName, - model: null); - var didBind = false; object boundValue = null; + ModelBindingResult? result; + using (bindingContext.EnterNestedScope( + elementMetadata, + fieldName: indexName, + modelName: fullChildName, + model: null)) + { + await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(bindingContext); + result = bindingContext.Result; + } - var result = - await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(childBindingContext); - if (result != null && result.IsModelSet) + if (result != null && result.Value.IsModelSet) { didBind = true; - boundValue = result.Model; + boundValue = result.Value.Model; } // infinite size collection stops on first bind failure diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CompositeModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CompositeModelBinder.cs index c46f914720..aa9b2b51f1 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CompositeModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/CompositeModelBinder.cs @@ -36,70 +36,78 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// public IList ModelBinders { get; } - public virtual Task BindModelAsync(ModelBindingContext bindingContext) + public virtual Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } - var newBindingContext = CreateNewBindingContext(bindingContext); - if (newBindingContext == null) - { - // Unable to find a value provider for this binding source. Binding will fail. - return ModelBindingResult.NoResultAsync; - } - - return RunModelBinders(newBindingContext); + return RunModelBinders(bindingContext); } - private async Task RunModelBinders(ModelBindingContext bindingContext) + private async Task RunModelBinders(ModelBindingContext bindingContext) { RuntimeHelpers.EnsureSufficientExecutionStack(); - // Perf: Avoid allocations - for (var i = 0; i < ModelBinders.Count; i++) + ModelBindingResult? overallResult = null; + try { - var binder = ModelBinders[i]; - var result = await binder.BindModelAsync(bindingContext); - if (result != ModelBindingResult.NoResult) + using (bindingContext.EnterNestedScope()) { - // This condition is necessary because the ModelState entry would never be validated if - // caller fell back to the empty prefix, leading to an possibly-incorrect !IsValid. In most - // (hopefully all) cases, the ModelState entry exists because some binders add errors before - // returning a result with !IsModelSet. Those binders often cannot run twice anyhow. - if (result.IsModelSet || - bindingContext.ModelState.ContainsKey(bindingContext.ModelName)) + if (PrepareBindingContext(bindingContext)) { - if (bindingContext.IsTopLevelObject && result.Model != null) + // Perf: Avoid allocations + for (var i = 0; i < ModelBinders.Count; i++) { - ValidationStateEntry entry; - if (!bindingContext.ValidationState.TryGetValue(result.Model, out entry)) + var binder = ModelBinders[i]; + await binder.BindModelAsync(bindingContext); + if (bindingContext.Result != null) { - entry = new ValidationStateEntry() + var result = bindingContext.Result.Value; + // This condition is necessary because the ModelState entry would never be validated if + // caller fell back to the empty prefix, leading to an possibly-incorrect !IsValid. In most + // (hopefully all) cases, the ModelState entry exists because some binders add errors before + // returning a result with !IsModelSet. Those binders often cannot run twice anyhow. + if (result.IsModelSet || + bindingContext.ModelState.ContainsKey(bindingContext.ModelName)) { - Key = result.Key, - Metadata = bindingContext.ModelMetadata, - }; - bindingContext.ValidationState.Add(result.Model, entry); + if (bindingContext.IsTopLevelObject && result.Model != null) + { + ValidationStateEntry entry; + if (!bindingContext.ValidationState.TryGetValue(result.Model, out entry)) + { + entry = new ValidationStateEntry() + { + Key = result.Key, + Metadata = bindingContext.ModelMetadata, + }; + bindingContext.ValidationState.Add(result.Model, entry); + } + } + + overallResult = bindingContext.Result; + return; + } + + // Current binder should have been able to bind value but found nothing. Exit loop in a way that + // tells caller to fall back to the empty prefix, if appropriate. Do not return result because it + // means only "other binders are not applicable". + + // overallResult MUST still be null at this return statement. + return; } } - - return result; } - - // Current binder should have been able to bind value but found nothing. Exit loop in a way that - // tells caller to fall back to the empty prefix, if appropriate. Do not return result because it - // means only "other binders are not applicable". - break; } } - - // Either we couldn't find a binder, or the binder couldn't bind. Distinction is not important. - return ModelBindingResult.NoResult; + finally + { + bindingContext.Result = overallResult; + } } - private static ModelBindingContext CreateNewBindingContext(ModelBindingContext oldBindingContext) + private static bool PrepareBindingContext(ModelBindingContext bindingContext) { // If the property has a specified data binding sources, we need to filter the set of value providers // to just those that match. We can skip filtering when IsGreedy == true, because that can't use @@ -119,8 +127,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // public IActionResult UpdatePerson([FromForm] Person person) { } // // In this example, [FromQuery] overrides the ambient data source (form). - IValueProvider valueProvider = oldBindingContext.ValueProvider; - var bindingSource = oldBindingContext.BindingSource; + + var valueProvider = bindingContext.ValueProvider; + var bindingSource = bindingContext.BindingSource; + var modelName = bindingContext.ModelName; + var fallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix; + if (bindingSource != null && !bindingSource.IsGreedy) { var bindingSourceValueProvider = valueProvider as IBindingSourceValueProvider; @@ -130,43 +142,30 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (valueProvider == null) { // Unable to find a value provider for this binding source. - return null; + return false; } } } - var newBindingContext = new ModelBindingContext - { - Model = oldBindingContext.Model, - ModelMetadata = oldBindingContext.ModelMetadata, - FieldName = oldBindingContext.FieldName, - ModelState = oldBindingContext.ModelState, - ValueProvider = valueProvider, - OperationBindingContext = oldBindingContext.OperationBindingContext, - PropertyFilter = oldBindingContext.PropertyFilter, - BinderModelName = oldBindingContext.BinderModelName, - BindingSource = oldBindingContext.BindingSource, - BinderType = oldBindingContext.BinderType, - IsTopLevelObject = oldBindingContext.IsTopLevelObject, - ValidationState = oldBindingContext.ValidationState, - }; - if (bindingSource != null && bindingSource.IsGreedy) { - newBindingContext.ModelName = oldBindingContext.ModelName; + bindingContext.ModelName = modelName; } else if ( - !oldBindingContext.FallbackToEmptyPrefix || - newBindingContext.ValueProvider.ContainsPrefix(oldBindingContext.ModelName)) + !fallbackToEmptyPrefix || + valueProvider.ContainsPrefix(bindingContext.ModelName)) { - newBindingContext.ModelName = oldBindingContext.ModelName; + bindingContext.ModelName = modelName; } else { - newBindingContext.ModelName = string.Empty; + bindingContext.ModelName = string.Empty; } - return newBindingContext; + bindingContext.ValueProvider = valueProvider; + bindingContext.FallbackToEmptyPrefix = false; + + return true; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/DictionaryModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/DictionaryModelBinder.cs index 21dcb61578..47f7800323 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/DictionaryModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/DictionaryModelBinder.cs @@ -22,26 +22,28 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class DictionaryModelBinder : CollectionModelBinder> { /// - public override async Task BindModelAsync(ModelBindingContext bindingContext) + public override async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } - var result = await base.BindModelAsync(bindingContext); - if (!result.IsModelSet) + await base.BindModelAsync(bindingContext); + if (bindingContext.Result == null || !bindingContext.Result.Value.IsModelSet) { // No match for the prefix at all. - return result; + return; } + var result = bindingContext.Result.Value; + Debug.Assert(result.Model != null); var model = (IDictionary)result.Model; if (model.Count != 0) { // ICollection> approach was successful. - return result; + return; } var enumerableValueProvider = bindingContext.ValueProvider as IEnumerableValueProvider; @@ -49,7 +51,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // No IEnumerableValueProvider available for the fallback approach. For example the user may have // replaced the ValueProvider with something other than a CompositeValueProvider. - return result; + return; } // Attempt to bind dictionary from a set of prefix[key]=value entries. Get the short and long keys first. @@ -57,18 +59,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (!keys.Any()) { // No entries with the expected keys. - return result; + return; } // Update the existing successful but empty ModelBindingResult. var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var valueMetadata = metadataProvider.GetMetadataForType(typeof(TValue)); - var valueBindingContext = ModelBindingContext.CreateChildBindingContext( - bindingContext, - valueMetadata, - fieldName: bindingContext.FieldName, - modelName: bindingContext.ModelName, - model: null); var modelBinder = bindingContext.OperationBindingContext.ModelBinder; @@ -79,21 +75,26 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // that culture when rendering a form. var convertedKey = ModelBindingHelper.ConvertTo(kvp.Key, culture: null); - valueBindingContext.ModelName = kvp.Value; + using (bindingContext.EnterNestedScope( + modelMetadata: valueMetadata, + fieldName: bindingContext.FieldName, + modelName: kvp.Value, + model: null)) + { + await modelBinder.BindModelAsync(bindingContext); - var valueResult = await modelBinder.BindModelAsync(valueBindingContext); + var valueResult = bindingContext.Result; - // Always add an entry to the dictionary but validate only if binding was successful. - model[convertedKey] = ModelBindingHelper.CastOrDefault(valueResult.Model); - keyMappings.Add(kvp.Key, convertedKey); + // Always add an entry to the dictionary but validate only if binding was successful. + model[convertedKey] = ModelBindingHelper.CastOrDefault(valueResult.Value.Model); + keyMappings.Add(kvp.Key, convertedKey); + } } bindingContext.ValidationState.Add(model, new ValidationStateEntry() { Strategy = new ShortFormDictionaryValidationStrategy(keyMappings, valueMetadata), }); - - return result; } /// diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormCollectionModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormCollectionModelBinder.cs index 0813fde64d..2feaef2527 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormCollectionModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormCollectionModelBinder.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.Extensions.Primitives; @@ -18,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class FormCollectionModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -31,13 +32,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (bindingContext.ModelType != typeof(IFormCollection)) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return BindModelCoreAsync(bindingContext); } - private async Task BindModelCoreAsync(ModelBindingContext bindingContext) + private async Task BindModelCoreAsync(ModelBindingContext bindingContext) { object model; var request = bindingContext.OperationBindingContext.HttpContext.Request; @@ -52,7 +53,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); - return ModelBindingResult.Success(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); } private class EmptyFormCollection : IFormCollection diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormFileModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormFileModelBinder.cs index 794dfb6ebd..f70074a1b2 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormFileModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/FormFileModelBinder.cs @@ -10,6 +10,7 @@ using System.Reflection; #endif using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.Net.Http.Headers; @@ -21,7 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class FormFileModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -35,13 +36,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (bindingContext.ModelType != typeof(IFormFile) && !typeof(IEnumerable).IsAssignableFrom(bindingContext.ModelType)) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return BindModelCoreAsync(bindingContext); } - private async Task BindModelCoreAsync(ModelBindingContext bindingContext) + private async Task BindModelCoreAsync(ModelBindingContext bindingContext) { // If we're at the top level, then use the FieldName (paramter or property name). // This handles the fact that there will be nothing in the ValueProviders for this parameter @@ -65,12 +66,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // This binder does not support the requested type. Debug.Fail("We shouldn't be called without a matching type."); - return ModelBindingResult.NoResult; + return; } if (value == null) { - return ModelBindingResult.Failed(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return; } else { @@ -85,7 +87,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding rawValue: null, attemptedValue: null); - return ModelBindingResult.Success(bindingContext.ModelName, value); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, value); + return; } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/GenericModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/GenericModelBinder.cs index d6776c31b3..99eb8eb1cb 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/GenericModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/GenericModelBinder.cs @@ -8,14 +8,20 @@ using System.Diagnostics; using System.Reflection; #endif using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { public class GenericModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task. @@ -23,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binderType = ResolveBinderType(bindingContext); if (binderType == null) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } var binder = (IModelBinder)Activator.CreateInstance(binderType); @@ -34,24 +40,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding !collectionBinder.CanCreateInstance(bindingContext.ModelType)) { // Able to resolve a binder type but need a new model instance and that binder cannot create it. - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return BindModelCoreAsync(bindingContext, binder); } - private async Task BindModelCoreAsync(ModelBindingContext bindingContext, IModelBinder binder) + private async Task BindModelCoreAsync(ModelBindingContext bindingContext, IModelBinder binder) { Debug.Assert(binder != null); - var result = await binder.BindModelAsync(bindingContext); - var modelBindingResult = result != ModelBindingResult.NoResult ? - result : - ModelBindingResult.Failed(bindingContext.ModelName); - - // Were able to resolve a binder type. - // Always tell the model binding system to skip other model binders. - return modelBindingResult; + await binder.BindModelAsync(bindingContext); + if (bindingContext.Result == null) + { + // Always tell the model binding system to skip other model binders. + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + } } private static Type ResolveBinderType(ModelBindingContext context) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/HeaderModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/HeaderModelBinder.cs index e3b3ba3353..e32c0505a5 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/HeaderModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/HeaderModelBinder.cs @@ -1,12 +1,15 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Diagnostics; #if DOTNET5_4 using System.Reflection; #endif using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { @@ -17,8 +20,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class HeaderModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task. @@ -29,7 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Headers are opt-in. This model either didn't specify [FromHeader] or specified something // incompatible so let other binders run. - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } var request = bindingContext.OperationBindingContext.HttpContext.Request; @@ -59,7 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (model == null) { - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } else { @@ -68,7 +77,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding request.Headers.GetCommaSeparatedValues(headerName), request.Headers[headerName]); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return TaskCache.CompletedTask; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs index 4d272121f5..42719e10a6 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/KeyValuePairModelBinder.cs @@ -1,15 +1,22 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading.Tasks; namespace Microsoft.AspNetCore.Mvc.ModelBinding { public sealed class KeyValuePairModelBinder : IModelBinder { - public async Task BindModelAsync(ModelBindingContext bindingContext) + public async Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(KeyValuePair), allowNullModel: true); @@ -23,9 +30,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding ModelBindingHelper.CastOrDefault(keyResult.Model), ModelBindingHelper.CastOrDefault(valueResult.Model)); - return ModelBindingResult.Success(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return; } - else if (!keyResult.IsModelSet && valueResult.IsModelSet) + + if (!keyResult.IsModelSet && valueResult.IsModelSet) { bindingContext.ModelState.TryAddModelError( keyResult.Key, @@ -33,9 +42,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Were able to get some data for this model. // Always tell the model binding system to skip other model binders. - return ModelBindingResult.Failed(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return; } - else if (keyResult.IsModelSet && !valueResult.IsModelSet) + + if (keyResult.IsModelSet && !valueResult.IsModelSet) { bindingContext.ModelState.TryAddModelError( valueResult.Key, @@ -43,46 +54,46 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Were able to get some data for this model. // Always tell the model binding system to skip other model binders. - return ModelBindingResult.Failed(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return; } - else - { - // If we failed to find data for a top-level model, then generate a - // default 'empty' model and return it. - if (bindingContext.IsTopLevelObject) - { - var model = new KeyValuePair(); - return ModelBindingResult.Success(bindingContext.ModelName, model); - } - return ModelBindingResult.NoResult; + // If we failed to find data for a top-level model, then generate a + // default 'empty' model and return it. + if (bindingContext.IsTopLevelObject) + { + var model = new KeyValuePair(); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); } } internal async Task TryBindStrongModel( - ModelBindingContext parentBindingContext, + ModelBindingContext bindingContext, string propertyName) { var propertyModelMetadata = - parentBindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(typeof(TModel)); + bindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(typeof(TModel)); var propertyModelName = - ModelNames.CreatePropertyModelName(parentBindingContext.ModelName, propertyName); - var propertyBindingContext = ModelBindingContext.CreateChildBindingContext( - parentBindingContext, - propertyModelMetadata, - propertyName, - propertyModelName, - model: null); + ModelNames.CreatePropertyModelName(bindingContext.ModelName, propertyName); - var result = await propertyBindingContext.OperationBindingContext.ModelBinder.BindModelAsync( - propertyBindingContext); - if (result.IsModelSet) + using (bindingContext.EnterNestedScope( + modelMetadata: propertyModelMetadata, + fieldName: propertyName, + modelName: propertyModelName, + model: null)) { - return result; - } - else - { - return ModelBindingResult.Failed(propertyModelName); + + await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync( + bindingContext); + var result = bindingContext.Result; + if (result != null && result.Value.IsModelSet) + { + return result.Value; + } + else + { + return ModelBindingResult.Failed(propertyModelName); + } } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/DefaultModelMetadata.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/DefaultModelMetadata.cs index 8d22c36ef8..84b146f45e 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/DefaultModelMetadata.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/DefaultModelMetadata.cs @@ -2,16 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Diagnostics; using System.Linq; -using Microsoft.AspNetCore.Mvc.Internal; -#if DOTNET5_4 -using System.Reflection; -#endif -using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata { diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs index 6b2f64f1e5..b5d018418e 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ModelBindingHelper.cs @@ -528,7 +528,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding ValueProvider = valueProvider, }; - var modelBindingContext = ModelBindingContext.CreateBindingContext( + var modelBindingContext = DefaultModelBindingContext.CreateBindingContext( operationBindingContext, modelMetadata, bindingInfo: null, @@ -536,15 +536,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding modelBindingContext.Model = model; modelBindingContext.PropertyFilter = predicate; - var modelBindingResult = await modelBinder.BindModelAsync(modelBindingContext); - if (modelBindingResult.IsModelSet) + await modelBinder.BindModelAsync(modelBindingContext); + var modelBindingResult = modelBindingContext.Result; + if (modelBindingResult != null && modelBindingResult.Value.IsModelSet) { objectModelValidator.Validate( operationBindingContext.ActionContext, operationBindingContext.ValidatorProvider, modelBindingContext.ValidationState, - modelBindingResult.Key, - modelBindingResult.Model); + modelBindingResult.Value.Key, + modelBindingResult.Value.Model); return modelState.IsValid; } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs index b773a4aa6b..7bf7234cb4 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { @@ -18,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding typeof(MutableObjectModelBinder).GetTypeInfo().GetDeclaredMethod(nameof(CallPropertyAddRange)); /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { @@ -28,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding ModelBindingHelper.ValidateBindingContext(bindingContext); if (!CanBindType(bindingContext.ModelMetadata)) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } var mutableObjectBinderContext = new MutableObjectBinderContext() @@ -39,13 +40,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (!(CanCreateModel(mutableObjectBinderContext))) { - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } return BindModelCoreAsync(bindingContext, mutableObjectBinderContext); } - private async Task BindModelCoreAsync( + private async Task BindModelCoreAsync( ModelBindingContext bindingContext, MutableObjectBinderContext mutableObjectBinderContext) { @@ -58,7 +59,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding bindingContext.Model = model; ProcessResults(bindingContext, results); - return ModelBindingResult.Success(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); } /// @@ -170,17 +171,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding context.ModelBindingContext.ModelName, fieldName); - var propertyModelBindingContext = ModelBindingContext.CreateChildBindingContext( - context.ModelBindingContext, - propertyMetadata, + using (context.ModelBindingContext.EnterNestedScope( + modelMetadata: propertyMetadata, fieldName: fieldName, modelName: modelName, - model: null); - - // If any property can return a true value. - if (CanBindValue(propertyModelBindingContext)) + model: null)) { - return true; + // If any property can return a true value. + if (CanBindValue(context.ModelBindingContext)) + { + return true; + } } } } @@ -298,21 +299,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var fieldName = propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName; var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName); - var propertyContext = ModelBindingContext.CreateChildBindingContext( - bindingContext, - propertyMetadata, + using (bindingContext.EnterNestedScope( + modelMetadata: propertyMetadata, fieldName: fieldName, modelName: modelName, - model: model); - - var result = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(propertyContext); - if (result == ModelBindingResult.NoResult) + model: model)) { - // Could not bind. Let ProcessResult() know explicitly. - result = ModelBindingResult.Failed(propertyContext.ModelName); - } + await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(bindingContext); + var result = bindingContext.Result; + if (result == null) + { + // Could not bind. Let ProcessResult() know explicitly. + result = ModelBindingResult.Failed(bindingContext.ModelName); + } - results[propertyMetadata] = result; + results[propertyMetadata] = result.Value; + } } return results; @@ -444,7 +446,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // exceptions as necessary. foreach (var entry in results) { - if (entry.Value != ModelBindingResult.NoResult) + if (entry.Value != null) { var result = entry.Value; var propertyMetadata = entry.Key; diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ServicesModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ServicesModelBinder.cs index 0a38fa2b33..26020e9090 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ServicesModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/ServicesModelBinder.cs @@ -1,7 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; +using System.Diagnostics; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.Extensions.DependencyInjection; @@ -14,8 +17,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public class ServicesModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task. @@ -26,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Services are opt-in. This model either didn't specify [FromService] or specified something // incompatible so let other binders run. - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; @@ -34,7 +42,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return TaskCache.CompletedTask; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs index 09b4a8c4b1..8e683d5726 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs @@ -3,13 +3,19 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; namespace Microsoft.AspNetCore.Mvc.ModelBinding { public class SimpleTypeModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task. @@ -17,14 +23,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding if (bindingContext.ModelMetadata.IsComplexType) { // this type cannot be converted - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { // no entry - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); @@ -53,11 +59,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding bindingContext.ModelMetadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor( valueProviderResult.ToString())); - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } else { - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + return TaskCache.CompletedTask; } } catch (Exception exception) @@ -69,7 +77,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Were able to find a converter for the type but conversion failed. // Tell the model binding system to skip other model binders. - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } } } diff --git a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/HttpRequestMessage/HttpRequestMessageModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/HttpRequestMessage/HttpRequestMessageModelBinder.cs index fea443b041..3e738b8a62 100644 --- a/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/HttpRequestMessage/HttpRequestMessageModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/HttpRequestMessage/HttpRequestMessageModelBinder.cs @@ -3,6 +3,7 @@ using System.Net.Http; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; @@ -14,16 +15,16 @@ namespace Microsoft.AspNetCore.Mvc.WebApiCompatShim public class HttpRequestMessageModelBinder : IModelBinder { /// - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(HttpRequestMessage)) { var model = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage(); bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); } - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/BindAttributeTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/BindAttributeTest.cs index 07204c1905..e36ad3ed86 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/BindAttributeTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/BindAttributeTest.cs @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Arrange var bind = new BindAttribute(new string[] { "UserName", "FirstName", "LastName, MiddleName, ,foo,bar " }); - var context = new ModelBindingContext(); + var context = new DefaultModelBindingContext(); // Act var predicate = bind.PropertyFilter; @@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Arrange var bind = new BindAttribute(typeof(TestProvider)); - var context = new ModelBindingContext(); + var context = new DefaultModelBindingContext(); context.OperationBindingContext = new OperationBindingContext() { ActionContext = new ActionContext() @@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Arrange var bind = new BindAttribute(typeof(TestProvider)); - var context = new ModelBindingContext(); + var context = new DefaultModelBindingContext(); context.OperationBindingContext = new OperationBindingContext() { ActionContext = new ActionContext() diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs index f43ac38536..6584fe2068 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ControllerBaseTest.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Mvc.ModelBinding.Test; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.TestCommon; using Microsoft.AspNetCore.Routing; @@ -1096,29 +1097,25 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test // Arrange var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var valueProvider = Mock.Of(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Empty(context.ModelName); - Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); + var binder = new StubModelBinder(context => + { + Assert.Empty(context.ModelName); + Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); - // Include and exclude should be null, resulting in property - // being included. - Assert.True(context.PropertyFilter(context, "Property1")); - Assert.True(context.PropertyFilter(context, "Property2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + // Include and exclude should be null, resulting in property + // being included. + Assert.True(context.PropertyFilter(context, "Property1")); + Assert.True(context.PropertyFilter(context, "Property2")); + }); - var controller = GetController(binder.Object, valueProvider); + var controller = GetController(binder, valueProvider); var model = new MyModel(); // Act var result = await controller.TryUpdateModelAsync(model); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1129,28 +1126,24 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var valueProvider = Mock.Of(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); - // Include and exclude should be null, resulting in property - // being included. - Assert.True(context.PropertyFilter(context, "Property1")); - Assert.True(context.PropertyFilter(context, "Property2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + // Include and exclude should be null, resulting in property + // being included. + Assert.True(context.PropertyFilter(context, "Property1")); + Assert.True(context.PropertyFilter(context, "Property2")); + }); - var controller = GetController(binder.Object, valueProvider); + var controller = GetController(binder, valueProvider); var model = new MyModel(); // Act var result = await controller.TryUpdateModelAsync(model, modelName); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1160,9 +1153,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test var modelName = "mymodel"; var valueProvider = Mock.Of(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => + var binder = new StubModelBinder(context => { Assert.Same(valueProvider, context.ValueProvider); @@ -1170,18 +1161,16 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test // being included. Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + }); - var controller = GetController(binder.Object, valueProvider: null); + var controller = GetController(binder, valueProvider: null); var model = new MyModel(); // Act var result = await controller.TryUpdateModelAsync(model, modelName, valueProvider); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1194,30 +1183,26 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) || string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase); - var binder = new Mock(); var valueProvider = Mock.Of(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); - Assert.True(context.PropertyFilter(context, "include1")); - Assert.True(context.PropertyFilter(context, "include2")); + Assert.True(context.PropertyFilter(context, "include1")); + Assert.True(context.PropertyFilter(context, "include2")); - Assert.False(context.PropertyFilter(context, "exclude1")); - Assert.False(context.PropertyFilter(context, "exclude2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + Assert.False(context.PropertyFilter(context, "exclude1")); + Assert.False(context.PropertyFilter(context, "exclude2")); + }); - var controller = GetController(binder.Object, valueProvider); + var controller = GetController(binder, valueProvider); var model = new MyModel(); // Act await controller.TryUpdateModelAsync(model, modelName, includePredicate); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1230,23 +1215,18 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test (context, propertyName) => string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) || string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase); - var binder = new Mock(); var valueProvider = Mock.Of(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider, context.ValueProvider); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider, context.ValueProvider); - Assert.True(context.PropertyFilter(context, "include1")); - Assert.True(context.PropertyFilter(context, "include2")); + Assert.True(context.PropertyFilter(context, "include1")); + Assert.True(context.PropertyFilter(context, "include2")); - Assert.False(context.PropertyFilter(context, "exclude1")); - Assert.False(context.PropertyFilter(context, "exclude2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); - - var controller = GetController(binder.Object, valueProvider: null); + Assert.False(context.PropertyFilter(context, "exclude1")); + Assert.False(context.PropertyFilter(context, "exclude2")); + }); + var controller = GetController(binder, valueProvider: null); var model = new MyModel(); @@ -1254,7 +1234,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test await controller.TryUpdateModelAsync(model, modelName, valueProvider, includePredicate); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Theory] @@ -1268,32 +1248,28 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test .Setup(v => v.ContainsPrefix(prefix)) .Returns(true); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same( + var binder = new StubModelBinder(context => + { + Assert.Same( valueProvider.Object, Assert.IsType(context.ValueProvider)[0]); - Assert.True(context.PropertyFilter(context, "Property1")); - Assert.True(context.PropertyFilter(context, "Property2")); + Assert.True(context.PropertyFilter(context, "Property1")); + Assert.True(context.PropertyFilter(context, "Property2")); - Assert.False(context.PropertyFilter(context, "exclude1")); - Assert.False(context.PropertyFilter(context, "exclude2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + Assert.False(context.PropertyFilter(context, "exclude1")); + Assert.False(context.PropertyFilter(context, "exclude2")); + }); - var controller = GetController(binder.Object, valueProvider.Object); + var controller = GetController(binder, valueProvider.Object); var model = new MyModel(); // Act await controller.TryUpdateModelAsync(model, prefix, m => m.Property1, m => m.Property2); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Theory] @@ -1308,29 +1284,25 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test .Setup(v => v.ContainsPrefix(prefix)) .Returns(true); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider.Object, context.ValueProvider); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider.Object, context.ValueProvider); - Assert.True(context.PropertyFilter(context, "Property1")); - Assert.True(context.PropertyFilter(context, "Property2")); + Assert.True(context.PropertyFilter(context, "Property1")); + Assert.True(context.PropertyFilter(context, "Property2")); - Assert.False(context.PropertyFilter(context, "exclude1")); - Assert.False(context.PropertyFilter(context, "exclude2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + Assert.False(context.PropertyFilter(context, "exclude1")); + Assert.False(context.PropertyFilter(context, "exclude2")); + }); - var controller = GetController(binder.Object, valueProvider: null); + var controller = GetController(binder, valueProvider: null); var model = new MyModel(); // Act await controller.TryUpdateModelAsync(model, prefix, valueProvider.Object, m => m.Property1, m => m.Property2); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1345,22 +1317,18 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test var valueProvider = Mock.Of(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider, context.ValueProvider); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider, context.ValueProvider); - Assert.True(context.PropertyFilter(context, "include1")); - Assert.True(context.PropertyFilter(context, "include2")); + Assert.True(context.PropertyFilter(context, "include1")); + Assert.True(context.PropertyFilter(context, "include2")); - Assert.False(context.PropertyFilter(context, "exclude1")); - Assert.False(context.PropertyFilter(context, "exclude2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + Assert.False(context.PropertyFilter(context, "exclude1")); + Assert.False(context.PropertyFilter(context, "exclude2")); + }); - var controller = GetController(binder.Object, valueProvider: null); + var controller = GetController(binder, valueProvider: null); var model = new MyModel(); @@ -1368,7 +1336,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test await controller.TryUpdateModelAsync(model, model.GetType(), modelName, valueProvider, includePredicate); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1379,28 +1347,24 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var valueProvider = Mock.Of(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); - // Include and exclude should be null, resulting in property - // being included. - Assert.True(context.PropertyFilter(context, "Property1")); - Assert.True(context.PropertyFilter(context, "Property2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + // Include and exclude should be null, resulting in property + // being included. + Assert.True(context.PropertyFilter(context, "Property1")); + Assert.True(context.PropertyFilter(context, "Property2")); + }); - var controller = GetController(binder.Object, valueProvider); + var controller = GetController(binder, valueProvider); var model = new MyModel(); // Act var result = await controller.TryUpdateModelAsync(model, model.GetType(), modelName); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1411,28 +1375,24 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var valueProvider = Mock.Of(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Callback((ModelBindingContext context) => - { - Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); + var binder = new StubModelBinder(context => + { + Assert.Same(valueProvider, Assert.IsType(context.ValueProvider)[0]); - // Include and exclude should be null, resulting in property - // being included. - Assert.True(context.PropertyFilter(context, "Property1")); - Assert.True(context.PropertyFilter(context, "Property2")); - }) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + // Include and exclude should be null, resulting in property + // being included. + Assert.True(context.PropertyFilter(context, "Property1")); + Assert.True(context.PropertyFilter(context, "Property2")); + }); - var controller = GetController(binder.Object, valueProvider); + var controller = GetController(binder, valueProvider); MyModel model = new MyDerivedModel(); // Act var result = await controller.TryUpdateModelAsync(model, model.GetType(), modelName); // Assert - binder.Verify(); + Assert.NotEqual(0, binder.BindModelCount); } [Fact] @@ -1515,8 +1475,8 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test public void TryValidateModelWithValidModel_ReturnsTrue() { // Arrange - var binder = new Mock(); - var controller = GetController(binder.Object, valueProvider: null); + var binder = new StubModelBinder(); + var controller = GetController(binder, valueProvider: null); controller.ControllerContext.ValidatorProviders = new List() { Mock.Of(), @@ -1552,8 +1512,8 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test provider.Setup(v => v.GetValidators(It.IsAny())) .Callback(c => c.Results.Add(validator1)); - var binder = new Mock(); - var controller = GetController(binder.Object, valueProvider: null); + var binder = new StubModelBinder(); + var controller = GetController(binder, valueProvider: null); controller.ControllerContext.ValidatorProviders = new List() { provider.Object, @@ -1589,8 +1549,8 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test provider.Setup(v => v.GetValidators(It.IsAny())) .Callback(c => c.Results.Add(validator1)); - var binder = new Mock(); - var controller = GetController(binder.Object, valueProvider: null); + var binder = new StubModelBinder(); + var controller = GetController(binder, valueProvider: null); controller.ControllerContext.ValidatorProviders = new List() { provider.Object, diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionInvokerTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionInvokerTest.cs index 52e4a19bcd..4defb687e0 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionInvokerTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerActionInvokerTest.cs @@ -2090,8 +2090,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal }; var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + binder.Setup(b => b.BindModelAsync(It.IsAny())) + .Returns(TaskCache.CompletedTask); var context = new Mock(); context.SetupGet(c => c.Items) .Returns(new Dictionary()); diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerArgumentBinderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerArgumentBinderTests.cs index 20aa2fa100..366140c95a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerArgumentBinderTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ControllerArgumentBinderTests.cs @@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal var binder = new Mock(); binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + .Setup(b => b.BindModelAsync(It.IsAny())) + .Returns(TaskCache.CompletedTask); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.ModelBinders.Add(binder.Object); @@ -67,8 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal var binder = new Mock(); binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.FailedAsync(string.Empty)); + .Setup(b => b.BindModelAsync(It.IsAny())) + .Returns(TaskCache.CompletedTask); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.ModelBinders.Add(binder.Object); @@ -104,12 +104,13 @@ namespace Microsoft.AspNetCore.Mvc.Internal var binder = new Mock(); binder - .Setup(b => b.BindModelAsync(It.IsAny())) + .Setup(b => b.BindModelAsync(It.IsAny())) .Callback((ModelBindingContext context) => { context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(string)); + context.Result = ModelBindingResult.Success(string.Empty, value); }) - .Returns(ModelBindingResult.SuccessAsync(string.Empty, value)); + .Returns(TaskCache.CompletedTask); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.ModelBinders.Add(binder.Object); @@ -181,8 +182,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal var binder = new Mock(); binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + .Setup(b => b.BindModelAsync(It.IsAny())) + .Returns(TaskCache.CompletedTask); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.ModelBinders.Add(binder.Object); @@ -267,8 +268,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal var binder = new Mock(); binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + .Setup(b => b.BindModelAsync(It.IsAny())) + .Returns(TaskCache.CompletedTask); var controllerContext = GetControllerContext(actionDescriptor); controllerContext.ModelBinders.Add(binder.Object); @@ -368,13 +369,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal ParameterType = typeof(int) }); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.SuccessAsync(string.Empty, model: null)); + var binder = new StubModelBinder(ModelBindingResult.Success(string.Empty, model: null)); var controllerContext = GetControllerContext(actionDescriptor); - controllerContext.ModelBinders.Add(binder.Object); + controllerContext.ModelBinders.Add(binder); controllerContext.ValueProviders.Add(new SimpleValueProvider()); var argumentBinder = GetArgumentBinder(); @@ -403,13 +401,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal ParameterType = typeof(int?) }); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.SuccessAsync(key: string.Empty, model: null)); + var binder = new StubModelBinder(ModelBindingResult.Success(key: string.Empty, model: null)); var controllerContext = GetControllerContext(actionDescriptor); - controllerContext.ModelBinders.Add(binder.Object); + controllerContext.ModelBinders.Add(binder); controllerContext.ValueProviders.Add(new SimpleValueProvider()); var argumentBinder = GetArgumentBinder(); @@ -541,23 +536,20 @@ namespace Microsoft.AspNetCore.Mvc.Internal var argumentBinder = GetArgumentBinder(); var controller = new TestController(); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(bindingContext => + var binder = new StubModelBinder(bindingContext => + { + // BindingContext.ModelName will be string.Empty here. This is a 'fallback to empty prefix' + // because the value providers have no data. + object model; + if (inputPropertyValues.TryGetValue(bindingContext.FieldName, out model)) { - // BindingContext.ModelName will be string.Empty here. This is a 'fallback to empty prefix' - // because the value providers have no data. - object model; - if (inputPropertyValues.TryGetValue(bindingContext.FieldName, out model)) - { - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); - } - else - { - return ModelBindingResult.FailedAsync(bindingContext.ModelName); - } - }); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model); + } + else + { + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + } + }); controllerContext.ModelBinders.Add(binder.Object); controllerContext.ValueProviders.Add(new SimpleValueProvider()); @@ -607,10 +599,11 @@ namespace Microsoft.AspNetCore.Mvc.Internal }; var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(mbc => + binder.Setup(b => b.BindModelAsync(It.IsAny())) + .Returns(mbc => { - return ModelBindingResult.SuccessAsync(string.Empty, model); + mbc.Result = ModelBindingResult.Success(string.Empty, model); + return TaskCache.CompletedTask; }); context.ModelBinders.Add(binder.Object); @@ -642,7 +635,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal It.IsAny())); return mockValidator.Object; } - + // No need for bind-related attributes on properties in this controller class. Properties are added directly // to the BoundProperties collection, bypassing usual requirements. private class TestController diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ModelBinderExtensions.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ModelBinderExtensions.cs new file mode 100644 index 0000000000..41d67e4d31 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/ModelBinderExtensions.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.Mvc.ModelBinding +{ + public static class ModelBinderExtensions + { + public static async Task BindModelResultAsync( + this IModelBinder binder, + ModelBindingContext context) + { + await binder.BindModelAsync(context); + return context.Result ?? default(ModelBindingResult); + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs index cd76383e40..d66d9a1a74 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Internal; -using Moq; +using Microsoft.AspNetCore.Mvc.Internal; using Xunit; namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test @@ -25,10 +25,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ArrayModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var array = Assert.IsType(result.Model); Assert.Equal(new[] { 42, 84 }, array); @@ -53,10 +53,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Empty(Assert.IsType(result.Model)); Assert.Equal("modelName", result.Key); @@ -82,10 +82,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } public static TheoryData ArrayModelData @@ -117,10 +117,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ArrayModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } // Here "fails silently" means the call does not update the array but also does not throw or set an error. @@ -142,10 +142,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ArrayModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Same(model, result.Model); @@ -159,23 +159,19 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test private static IModelBinder CreateIntBinder() { - var mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext mbc) => + return new StubModelBinder(mbc => + { + var value = mbc.ValueProvider.GetValue(mbc.ModelName); + if (value != ValueProviderResult.None) { - var value = mbc.ValueProvider.GetValue(mbc.ModelName); - if (value != ValueProviderResult.None) - { - var model = value.ConvertTo(mbc.ModelType); - return ModelBindingResult.SuccessAsync(mbc.ModelName, model); - } - return ModelBindingResult.NoResultAsync; - }); - return mockIntBinder.Object; + var model = value.ConvertTo(mbc.ModelType); + return ModelBindingResult.Success(mbc.ModelName, model); + } + return null; + }); } - private static ModelBindingContext GetBindingContext( + private static DefaultModelBindingContext GetBindingContext( IValueProvider valueProvider, bool isReadOnly = false) { @@ -187,7 +183,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var modelMetadata = metadataProvider.GetMetadataForProperty( typeof(ModelWithIntArrayProperty), nameof(ModelWithIntArrayProperty.ArrayProperty)); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, ModelName = "someName", @@ -202,9 +198,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test return bindingContext; } - private static ModelBindingContext CreateContext() + private static DefaultModelBindingContext CreateContext() { - var modelBindingContext = new ModelBindingContext() + var modelBindingContext = new DefaultModelBindingContext() { OperationBindingContext = new OperationBindingContext() { diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BinderTypeBasedModelBinderModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BinderTypeBasedModelBinderModelBinderTest.cs index 1a28f2aa76..9ceca93e1a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BinderTypeBasedModelBinderModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BinderTypeBasedModelBinderModelBinderTest.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test public class BinderTypeBasedModelBinderModelBinderTest { [Fact] - public async Task BindModel_ReturnsNoResult_IfNoBinderTypeIsSet() + public async Task BindModel_ReturnsNothing_IfNoBinderTypeIsSet() { // Arrange var bindingContext = GetBindingContext(typeof(Person)); @@ -22,10 +22,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new BinderTypeBasedModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, binderResult); + Assert.Equal(default(ModelBindingResult), binderResult); } [Fact] @@ -37,10 +37,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new BinderTypeBasedModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, binderResult); + Assert.NotEqual(default(ModelBindingResult), binderResult); Assert.False(binderResult.IsModelSet); } @@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new BinderTypeBasedModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert var p = (Person)binderResult.Model; @@ -80,13 +80,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test // Act var ex = await Assert.ThrowsAsync( - () => binder.BindModelAsync(bindingContext)); + () => binder.BindModelResultAsync(bindingContext)); // Assert Assert.Equal(expected, ex.Message); } - private static ModelBindingContext GetBindingContext(Type modelType, Type binderType = null) + private static DefaultModelBindingContext GetBindingContext(Type modelType, Type binderType = null) { var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType(modelType).BindingDetails(bd => bd.BinderType = binderType); @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test ValidatorProvider = Mock.Of(), }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "someName", @@ -123,9 +123,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test private class NullModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { - return ModelBindingResult.NoResultAsync; + return Task.FromResult(0); } } @@ -138,9 +138,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test _model = new Person(); } - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, _model); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, _model); + return Task.FromResult(0); } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs index 757b7cce60..b49a518293 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs @@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new BodyModelBinder(new TestHttpRequestStreamReaderFactory()); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert mockInputFormatter.Verify(v => v.CanRead(It.IsAny()), Times.Once); @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert @@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert @@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(binderResult); @@ -138,10 +138,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, binderResult); + Assert.Equal(default(ModelBindingResult), binderResult); } [Fact] @@ -157,10 +157,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, binderResult); + Assert.Equal(default(ModelBindingResult), binderResult); } [Fact] @@ -183,7 +183,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert @@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert @@ -253,14 +253,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = bindingContext.OperationBindingContext.ModelBinder; // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert Assert.True(binderResult.IsModelSet); Assert.Same(canReadFormatter1, binderResult.Model); } - private static ModelBindingContext GetBindingContext( + private static DefaultModelBindingContext GetBindingContext( Type modelType, IEnumerable inputFormatters = null, HttpContext httpContext = null, @@ -292,7 +292,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding MetadataProvider = metadataProvider, }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FieldName = "someField", IsTopLevelObject = true, diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ByteArrayModelBinderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ByteArrayModelBinderTests.cs index c5f32d578f..c7c6c49296 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ByteArrayModelBinderTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ByteArrayModelBinderTests.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ByteArrayModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(binderResult); @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ByteArrayModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(binderResult); @@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ByteArrayModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(binderResult); @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ByteArrayModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(binderResult); @@ -114,16 +114,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new ByteArrayModelBinder(); // Act - var binderResult = await binder.BindModelAsync(bindingContext); + var binderResult = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, binderResult); + Assert.Equal(default(ModelBindingResult), binderResult); } - private static ModelBindingContext GetBindingContext(IValueProvider valueProvider, Type modelType) + private static DefaultModelBindingContext GetBindingContext(IValueProvider valueProvider, Type modelType) { var metadataProvider = new EmptyModelMetadataProvider(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "foo", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CancellationTokenModelBinderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CancellationTokenModelBinderTests.cs index 73afe109b1..05918d63de 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CancellationTokenModelBinderTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CancellationTokenModelBinderTests.cs @@ -20,10 +20,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new CancellationTokenModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(bindingContext.OperationBindingContext.HttpContext.RequestAborted, result.Model); } @@ -39,16 +39,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new CancellationTokenModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } - private static ModelBindingContext GetBindingContext(Type modelType) + private static DefaultModelBindingContext GetBindingContext(Type modelType) { var metadataProvider = new EmptyModelMetadataProvider(); - ModelBindingContext bindingContext = new ModelBindingContext + DefaultModelBindingContext bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "someName", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs index 36cc988616..fdc17cf9f8 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs @@ -83,10 +83,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new CollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var list = Assert.IsAssignableFrom>(result.Model); @@ -115,10 +115,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new CollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Same(list, result.Model); @@ -142,10 +142,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new CollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var list = Assert.IsAssignableFrom>(result.Model); @@ -169,10 +169,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new CollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Same(list, result.Model); @@ -192,10 +192,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var modelState = bindingContext.ModelState; // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.NotNull(result.Model); @@ -236,10 +236,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Empty(Assert.IsType>(result.Model)); Assert.Equal("modelName", result.Key); @@ -269,10 +269,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Same(list, result.Model); Assert.Empty(list); @@ -299,10 +299,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } // Model type -> can create instance. @@ -345,13 +345,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var culture = new CultureInfo("fr-FR"); var bindingContext = GetModelBindingContext(new SimpleValueProvider()); - Mock.Get(bindingContext.OperationBindingContext.ModelBinder) - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext mbc) => - { - Assert.Equal("someName", mbc.ModelName); - return ModelBindingResult.SuccessAsync(mbc.ModelName, 42); - }); + bindingContext.OperationBindingContext.ModelBinder = new StubModelBinder(mbc => + { + Assert.Equal("someName", mbc.ModelName); + mbc.Result = ModelBindingResult.Success(mbc.ModelName, 42); + }); + var modelBinder = new CollectionModelBinder(); // Act @@ -363,14 +362,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray()); } - private static ModelBindingContext GetModelBindingContext( + private static DefaultModelBindingContext GetModelBindingContext( IValueProvider valueProvider, bool isReadOnly = false) { var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType>().BindingDetails(bd => bd.IsReadOnly = isReadOnly); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(typeof(IList)), ModelName = "someName", @@ -390,33 +389,29 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding private static IModelBinder CreateIntBinder() { - Mock mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext mbc) => + return new StubModelBinder(mbc => + { + var value = mbc.ValueProvider.GetValue(mbc.ModelName); + if (value == ValueProviderResult.None) { - var value = mbc.ValueProvider.GetValue(mbc.ModelName); - if (value == ValueProviderResult.None) - { - return ModelBindingResult.NoResultAsync; - } + return null; + } - var model = value.ConvertTo(mbc.ModelType); - if (model == null) - { - return ModelBindingResult.FailedAsync(mbc.ModelName); - } - else - { - return ModelBindingResult.SuccessAsync(mbc.ModelName, model); - } - }); - return mockIntBinder.Object; + var model = value.ConvertTo(mbc.ModelType); + if (model == null) + { + return ModelBindingResult.Failed(mbc.ModelName); + } + else + { + return ModelBindingResult.Success(mbc.ModelName, model); + } + }); } - private static ModelBindingContext CreateContext() + private static DefaultModelBindingContext CreateContext() { - var modelBindingContext = new ModelBindingContext() + var modelBindingContext = new DefaultModelBindingContext() { OperationBindingContext = new OperationBindingContext() { diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CompositeModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CompositeModelBinderTest.cs index 1d036c61ed..a00d9f4c6e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CompositeModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/CompositeModelBinderTest.cs @@ -7,7 +7,6 @@ using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; -using Moq; using Xunit; namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test @@ -18,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test public async Task BindModel_SuccessfulBind_ReturnsModel() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)), @@ -33,25 +32,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns( - delegate (ModelBindingContext context) - { - Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata); - Assert.Equal("someName", context.ModelName); - Assert.Same(bindingContext.ValueProvider, context.ValueProvider); + var mockIntBinder = new StubModelBinder(context => + { + Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata); + Assert.Equal("someName", context.ModelName); + Assert.Same(bindingContext.ValueProvider, context.ValueProvider); - return ModelBindingResult.SuccessAsync("someName", 42); - }); - var shimBinder = CreateCompositeBinder(mockIntBinder.Object); + context.Result = ModelBindingResult.Success("someName", 42); + }); + var shimBinder = CreateCompositeBinder(mockIntBinder); // Act - var result = await shimBinder.BindModelAsync(bindingContext); + var result = await shimBinder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(42, result.Model); } @@ -60,7 +55,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test public async Task BindModel_SuccessfulBind_SetsValidationStateAtTopLevel() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, IsTopLevelObject = true, @@ -76,25 +71,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns( - delegate (ModelBindingContext context) - { - Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata); - Assert.Equal("someName", context.ModelName); - Assert.Same(bindingContext.ValueProvider, context.ValueProvider); + var mockIntBinder = new StubModelBinder(context => + { + Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata); + Assert.Equal("someName", context.ModelName); + Assert.Same(bindingContext.ValueProvider, context.ValueProvider); - return ModelBindingResult.SuccessAsync("someName", 42); - }); - var shimBinder = CreateCompositeBinder(mockIntBinder.Object); + context.Result = ModelBindingResult.Success("someName", 42); + }); + var shimBinder = CreateCompositeBinder(mockIntBinder); // Act - var result = await shimBinder.BindModelAsync(bindingContext); + var result = await shimBinder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(42, result.Model); @@ -108,7 +99,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test public async Task BindModel_SuccessfulBind_DoesNotSetValidationState_WhenNotTopLevel() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)), @@ -123,25 +114,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns( - delegate (ModelBindingContext context) - { - Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata); - Assert.Equal("someName", context.ModelName); - Assert.Same(bindingContext.ValueProvider, context.ValueProvider); + var mockIntBinder = new StubModelBinder(context => + { + Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata); + Assert.Equal("someName", context.ModelName); + Assert.Same(bindingContext.ValueProvider, context.ValueProvider); - return ModelBindingResult.SuccessAsync("someName", 42); - }); - var shimBinder = CreateCompositeBinder(mockIntBinder.Object); + context.Result = ModelBindingResult.Success("someName", 42); + }); + var shimBinder = CreateCompositeBinder(mockIntBinder); // Act - var result = await shimBinder.BindModelAsync(bindingContext); + var result = await shimBinder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(42, result.Model); @@ -154,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test // Arrange var expectedModel = new List { 1, 2, 3, 4, 5 }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, IsTopLevelObject = true, @@ -170,41 +157,37 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns( - delegate (ModelBindingContext mbc) - { - if (!string.IsNullOrEmpty(mbc.ModelName)) - { - return ModelBindingResult.NoResultAsync; - } + var mockIntBinder = new StubModelBinder(mbc => + { + if (!string.IsNullOrEmpty(mbc.ModelName)) + { + return; + } - Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata); - Assert.Equal("", mbc.ModelName); - Assert.Same(bindingContext.ValueProvider, mbc.ValueProvider); + Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata); + Assert.Equal("", mbc.ModelName); + Assert.Same(bindingContext.ValueProvider, mbc.ValueProvider); - return ModelBindingResult.SuccessAsync(string.Empty, expectedModel); - }); + mbc.Result = ModelBindingResult.Success(string.Empty, expectedModel); + }); - var shimBinder = CreateCompositeBinder(mockIntBinder.Object); + var shimBinder = CreateCompositeBinder(mockIntBinder); // Act - var result = await shimBinder.BindModelAsync(bindingContext); + var result = await shimBinder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(string.Empty, result.Key); Assert.Equal(expectedModel, result.Model); } [Fact] - public async Task ModelBinder_ReturnsNoResult_IfBinderMatchesButDoesNotSetModel() + public async Task ModelBinder_ReturnsNothing_IfBinderMatchesButDoesNotSetModel() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List)), @@ -218,25 +201,25 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var modelBinder = new Mock(); - modelBinder - .Setup(mb => mb.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.FailedAsync("someName")); + var mockIntBinder = new StubModelBinder(context => + { + context.Result = ModelBindingResult.Failed("someName"); + }); - var composite = CreateCompositeBinder(modelBinder.Object); + var composite = CreateCompositeBinder(mockIntBinder); // Act - var result = await composite.BindModelAsync(bindingContext); + var result = await composite.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] public async Task ModelBinder_DoesNotFallBackToEmpty_IfFallbackToEmptyPrefixFalse() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = false, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List)), @@ -250,28 +233,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var modelBinder = new Mock(); - modelBinder - .Setup(mb => mb.BindModelAsync(It.IsAny())) - .Callback(context => - { - Assert.Equal("someName", context.ModelName); - }) - .Returns(ModelBindingResult.FailedAsync("someName")) - .Verifiable(); + var mockIntBinder = new StubModelBinder(context => + { + Assert.Equal("someName", context.ModelName); + context.Result = ModelBindingResult.Failed("someName"); + }); - var composite = CreateCompositeBinder(modelBinder.Object); + var composite = CreateCompositeBinder(mockIntBinder); // Act & Assert - var result = await composite.BindModelAsync(bindingContext); - modelBinder.Verify(mb => mb.BindModelAsync(It.IsAny()), Times.Once); + var result = await composite.BindModelResultAsync(bindingContext); + Assert.Equal(1, mockIntBinder.BindModelCount); } [Fact] public async Task ModelBinder_DoesNotFallBackToEmpty_IfErrorsAreAdded() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = false, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List)), @@ -285,29 +264,25 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var modelBinder = new Mock(); - modelBinder - .Setup(mb => mb.BindModelAsync(It.IsAny())) - .Callback(context => - { - Assert.Equal("someName", context.ModelName); - context.ModelState.AddModelError(context.ModelName, "this is an error message"); - }) - .Returns(ModelBindingResult.FailedAsync("someName")) - .Verifiable(); + var mockIntBinder = new StubModelBinder(context => + { + Assert.Equal("someName", context.ModelName); + context.ModelState.AddModelError(context.ModelName, "this is an error message"); + context.Result = ModelBindingResult.Failed("someName"); + }); - var composite = CreateCompositeBinder(modelBinder.Object); + var composite = CreateCompositeBinder(mockIntBinder); // Act & Assert - var result = await composite.BindModelAsync(bindingContext); - modelBinder.Verify(mb => mb.BindModelAsync(It.IsAny()), Times.Once); + var result = await composite.BindModelResultAsync(bindingContext); + Assert.Equal(1, mockIntBinder.BindModelCount); } [Fact] public async Task ModelBinder_ReturnsNonEmptyResult_SetsNullValue_SetsModelStateKey() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List)), @@ -321,58 +296,30 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test FieldName = "someName", }; - var modelBinder = new Mock(); - modelBinder - .Setup(mb => mb.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.SuccessAsync("someName", model: null)); + var mockIntBinder = new StubModelBinder(context => + { + context.Result = ModelBindingResult.Success("someName", model: null); + }); - var composite = CreateCompositeBinder(modelBinder.Object); + var composite = CreateCompositeBinder(mockIntBinder); // Act - var result = await composite.BindModelAsync(bindingContext); + var result = await composite.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal("someName", result.Key); Assert.Null(result.Model); } [Fact] - public async Task BindModel_UnsuccessfulBind_BinderFails_ReturnsNoResult() + public async Task BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNothing() { // Arrange - var mockListBinder = new Mock(); - mockListBinder.Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync) - .Verifiable(); + var shimBinder = CreateCompositeBinder(new StubModelBinder()); - var shimBinder = mockListBinder.Object; - - var bindingContext = new ModelBindingContext - { - FallbackToEmptyPrefix = false, - ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List)), - ModelState = new ModelStateDictionary(), - }; - - // Act - var result = await shimBinder.BindModelAsync(bindingContext); - - // Assert - Assert.Equal(ModelBindingResult.NoResult, result); - Assert.True(bindingContext.ModelState.IsValid); - mockListBinder.Verify(); - } - - [Fact] - public async Task BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNoResult() - { - // Arrange - var innerBinder = Mock.Of(); - var shimBinder = CreateCompositeBinder(innerBinder); - - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)), @@ -383,10 +330,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test }; // Act - var result = await shimBinder.BindModelAsync(bindingContext); + var result = await shimBinder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] @@ -403,10 +350,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var model = Assert.IsType(result.Model); Assert.Equal("firstName-value", model.FirstName); Assert.Equal("lastName-value", model.LastName); @@ -433,10 +380,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person)); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var model = Assert.IsType(result.Model); Assert.Equal("firstName-value", model.FirstName); Assert.Equal("lastName-value", model.LastName); @@ -455,41 +402,32 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test { // Arrange var valueProvider = new SimpleValueProvider(); - var mockBinder = new Mock(); - mockBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext context) => - { - return ModelBindingResult.FailedAsync("someName"); - }); + var mockBinder = new StubModelBinder(ModelBindingResult.Failed("someName")); - var binder = CreateCompositeBinder(mockBinder.Object); + var binder = CreateCompositeBinder(mockBinder); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] - public async Task BindModel_DoesNotAddAValidationNode_IfModelBindingResultIsNoResult() + public async Task BindModel_DoesNotAddAValidationNode_IfModelBindingResultIsNothing() { // Arrange - var mockBinder = new Mock(); - mockBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); - var binder = CreateCompositeBinder(mockBinder.Object); + var mockBinder = new StubModelBinder(); + var binder = CreateCompositeBinder(mockBinder); var valueProvider = new SimpleValueProvider(); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] @@ -498,32 +436,26 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test // Arrange var valueProvider = new SimpleValueProvider(); - var mockBinder = new Mock(); - mockBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext context) => - { - return ModelBindingResult.SuccessAsync("someName", 42); - }); + var mockBinder = new StubModelBinder(ModelBindingResult.Success("someName", 42)); - var binder = CreateCompositeBinder(mockBinder.Object); + var binder = CreateCompositeBinder(mockBinder); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); } - private static ModelBindingContext CreateBindingContext( + private static DefaultModelBindingContext CreateBindingContext( IModelBinder binder, IValueProvider valueProvider, Type type) { var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { FallbackToEmptyPrefix = true, IsTopLevelObject = true, diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DefaultModelBindingContextTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DefaultModelBindingContextTest.cs new file mode 100644 index 0000000000..2d0eb5d238 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DefaultModelBindingContextTest.cs @@ -0,0 +1,96 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ModelBinding.Test; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.ModelBinding +{ + public class DefaultModelBindingContextTest + { + [Fact] + public void EnterNestedScope_CopiesProperties() + { + // Arrange + var bindingContext = new DefaultModelBindingContext + { + Model = new object(), + ModelMetadata = new TestModelMetadataProvider().GetMetadataForType(typeof(object)), + ModelName = "theName", + OperationBindingContext = new OperationBindingContext(), + ValueProvider = new SimpleValueProvider(), + ModelState = new ModelStateDictionary(), + }; + + var metadataProvider = new TestModelMetadataProvider(); + metadataProvider.ForType().BindingDetails(d => + { + d.BindingSource = BindingSource.Custom; + d.BinderType = typeof(TestModelBinder); + d.BinderModelName = "custom"; + }); + + var newModelMetadata = metadataProvider.GetMetadataForType(typeof(object)); + + // Act + var originalBinderModelName = bindingContext.BinderModelName; + var originalBinderType = bindingContext.BinderType; + var originalBindingSource = bindingContext.BindingSource; + var originalModelState = bindingContext.ModelState; + var originalOperationBindingContext = bindingContext.OperationBindingContext; + var originalValueProvider = bindingContext.ValueProvider; + + var disposable = bindingContext.EnterNestedScope( + modelMetadata: newModelMetadata, + fieldName: "fieldName", + modelName: "modelprefix.fieldName", + model: null); + + // Assert + Assert.Same(newModelMetadata.BinderModelName, bindingContext.BinderModelName); + Assert.Same(newModelMetadata.BinderType, bindingContext.BinderType); + Assert.Same(newModelMetadata.BindingSource, bindingContext.BindingSource); + Assert.False(bindingContext.FallbackToEmptyPrefix); + Assert.Equal("fieldName", bindingContext.FieldName); + Assert.False(bindingContext.IsTopLevelObject); + Assert.Null(bindingContext.Model); + Assert.Same(newModelMetadata, bindingContext.ModelMetadata); + Assert.Equal("modelprefix.fieldName", bindingContext.ModelName); + Assert.Same(originalModelState, bindingContext.ModelState); + Assert.Same(originalOperationBindingContext, bindingContext.OperationBindingContext); + Assert.Same(originalValueProvider, bindingContext.ValueProvider); + + disposable.Dispose(); + } + + [Fact] + public void ModelTypeAreFedFromModelMetadata() + { + // Act + var bindingContext = new DefaultModelBindingContext + { + ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)) + }; + + // Assert + Assert.Equal(typeof(int), bindingContext.ModelType); + } + + private class TestModelBinder : IModelBinder + { + public Task BindModelAsync(ModelBindingContext bindingContext) + { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + + throw new NotImplementedException(); + } + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DictionaryModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DictionaryModelBinderTest.cs index 100d95f2bf..50c086eabd 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DictionaryModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/DictionaryModelBinderTest.cs @@ -34,10 +34,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new DictionaryModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var dictionary = Assert.IsAssignableFrom>(result.Model); Assert.True(modelState.IsValid); @@ -70,10 +70,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new DictionaryModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Same(dictionary, result.Model); Assert.True(modelState.IsValid); @@ -137,10 +137,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test nameof(ModelWithDictionaryProperties.DictionaryProperty)); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(modelName, result.Key); @@ -174,10 +174,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test nameof(ModelWithDictionaryProperties.DictionaryProperty)); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal("prefix", result.Key); @@ -225,10 +225,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test nameof(ModelWithDictionaryProperties.DictionaryWithValueTypesProperty)); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal("prefix", result.Key); @@ -266,10 +266,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test nameof(ModelWithDictionaryProperties.DictionaryWithComplexValuesProperty)); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal("prefix", result.Key); @@ -312,10 +312,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test nameof(ModelWithDictionaryProperties.CustomDictionaryProperty)); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.Equal(modelName, result.Key); @@ -341,10 +341,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Empty(Assert.IsType>(result.Model)); Assert.Equal("modelName", result.Key); @@ -370,10 +370,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } // Model type -> can create instance. @@ -409,9 +409,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test Assert.Equal(expectedResult, result); } - private static ModelBindingContext CreateContext() + private static DefaultModelBindingContext CreateContext() { - var modelBindingContext = new ModelBindingContext() + var modelBindingContext = new DefaultModelBindingContext() { ModelState = new ModelStateDictionary(), OperationBindingContext = new OperationBindingContext() @@ -447,7 +447,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var backingStore = dictionary.ToDictionary( kvp => string.Format(keyFormat, kvp.Key), kvp => (StringValues)kvp.Value); - + var formCollection = new FormCollection(backingStore); return new FormValueProvider( @@ -467,28 +467,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test return new TestValueProvider(BindingSource.Form, backingStore); } - private static ModelBindingContext GetModelBindingContext( + private static DefaultModelBindingContext GetModelBindingContext( bool isReadOnly, IDictionary> values) { var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType>().BindingDetails(bd => bd.IsReadOnly = isReadOnly); - var binder = new Mock(); - binder - .Setup(mb => mb.BindModelAsync(It.IsAny())) - .Returns(mbc => + var binder = new StubModelBinder(mbc => + { + KeyValuePair value; + if (values.TryGetValue(mbc.ModelName, out value)) { - KeyValuePair value; - if (values.TryGetValue(mbc.ModelName, out value)) - { - return ModelBindingResult.SuccessAsync(mbc.ModelName, value); - } - else - { - return ModelBindingResult.NoResultAsync; - } - }); + mbc.Result = ModelBindingResult.Success(mbc.ModelName, value); + } + }); var valueProvider = new SimpleValueProvider(); foreach (var kvp in values) @@ -496,7 +489,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test valueProvider.Add(kvp.Key, string.Empty); } - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(typeof(IDictionary)), ModelName = "someName", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormCollectionModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormCollectionModelBinderTest.cs index 5146606797..ceb925883a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormCollectionModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormCollectionModelBinderTest.cs @@ -30,10 +30,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormCollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var entry = bindingContext.ValidationState[result.Model]; @@ -61,10 +61,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormCollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } // We only support IFormCollection here. Using the concrete type won't work. @@ -82,10 +82,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormCollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] @@ -97,10 +97,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormCollectionModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var form = Assert.IsAssignableFrom(result.Model); Assert.Empty(form); } @@ -114,10 +114,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding return httpContext.Object; } - private static ModelBindingContext GetBindingContext(Type modelType, HttpContext httpContext) + private static DefaultModelBindingContext GetBindingContext(Type modelType, HttpContext httpContext) { var metadataProvider = new EmptyModelMetadataProvider(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "file", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormFileModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormFileModelBinderTest.cs index 73ba91af60..d384f7e7cd 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormFileModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/FormFileModelBinderTest.cs @@ -27,10 +27,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var entry = bindingContext.ValidationState[result.Model]; @@ -51,10 +51,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var entry = bindingContext.ValidationState[result.Model]; @@ -78,10 +78,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var files = Assert.IsAssignableFrom>(result.Model); Assert.Equal(2, files.Count); } @@ -98,17 +98,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var file = Assert.IsAssignableFrom(result.Model); Assert.Equal("form-data; name=file; filename=file1.txt", file.ContentDisposition); } [Fact] - public async Task FormFileModelBinder_ReturnsNoResult_WhenNoFilePosted() + public async Task FormFileModelBinder_ReturnsNothing_WhenNoFilePosted() { // Arrange var formFiles = new FormFileCollection(); @@ -117,15 +117,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Null(result.Model); } [Fact] - public async Task FormFileModelBinder_ReturnsNoResult_WhenNamesDontMatch() + public async Task FormFileModelBinder_ReturnsNothing_WhenNamesDontMatch() { // Arrange var formFiles = new FormFileCollection(); @@ -135,10 +135,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Null(result.Model); } @@ -161,10 +161,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); var file = Assert.IsAssignableFrom(result.Model); @@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } [Fact] - public async Task FormFileModelBinder_ReturnsNoResult_WithEmptyContentDisposition() + public async Task FormFileModelBinder_ReturnsNothing_WithEmptyContentDisposition() { // Arrange var formFiles = new FormFileCollection(); @@ -184,15 +184,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Null(result.Model); } [Fact] - public async Task FormFileModelBinder_ReturnsNoResult_WithNoFileNameAndZeroLength() + public async Task FormFileModelBinder_ReturnsNothing_WithNoFileNameAndZeroLength() { // Arrange var formFiles = new FormFileCollection(); @@ -202,17 +202,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var binder = new FormFileModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Null(result.Model); } - private static ModelBindingContext GetBindingContext(Type modelType, HttpContext httpContext) + private static DefaultModelBindingContext GetBindingContext(Type modelType, HttpContext httpContext) { var metadataProvider = new EmptyModelMetadataProvider(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "file", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/HeaderModelBinderTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/HeaderModelBinderTests.cs index 2aa4b0ee7d..7925c67f12 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/HeaderModelBinderTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/HeaderModelBinderTests.cs @@ -24,10 +24,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var modelBindingContext = GetBindingContext(type); // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); } [Fact] @@ -44,10 +44,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Equal(headerValue.Split(','), result.Model); } @@ -65,15 +65,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Equal(headerValue, result.Model); } [Fact] - public async Task HeaderBinder_ReturnsNoResult_ForNullBindingSource() + public async Task HeaderBinder_ReturnsNothing_ForNullBindingSource() { // Arrange var type = typeof(string); @@ -88,14 +88,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] - public async Task HeaderBinder_ReturnsNoResult_ForNonHeaderBindingSource() + public async Task HeaderBinder_ReturnsNothing_ForNonHeaderBindingSource() { // Arrange var type = typeof(string); @@ -110,18 +110,18 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } - private static ModelBindingContext GetBindingContext(Type modelType) + private static DefaultModelBindingContext GetBindingContext(Type modelType) { var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Header); var modelMetadata = metadataProvider.GetMetadataForType(modelType); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, ModelName = "modelName", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/KeyValuePairModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/KeyValuePairModelBinderTest.cs index bc204a1ea3..854701fde7 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/KeyValuePairModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/KeyValuePairModelBinderTest.cs @@ -26,10 +26,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new KeyValuePairModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Null(result.Model); Assert.False(bindingContext.ModelState.IsValid); Assert.Equal("someName", bindingContext.ModelName); @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new KeyValuePairModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert Assert.Null(result.Model); @@ -68,18 +68,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test // Create int binder to create the value but not the key. var bindingContext = GetBindingContext(valueProvider); - var mockBinder = new Mock(); - mockBinder.Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + var mockBinder = new StubModelBinder(); - bindingContext.OperationBindingContext.ModelBinder = mockBinder.Object; + bindingContext.OperationBindingContext.ModelBinder = mockBinder; var binder = new KeyValuePairModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); Assert.True(bindingContext.ModelState.IsValid); Assert.Equal(0, bindingContext.ModelState.ErrorCount); } @@ -95,10 +93,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new KeyValuePairModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Equal(new KeyValuePair(42, "some-value"), result.Model); } @@ -111,7 +109,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test bool isSuccess) { // Arrange - ModelBindingResult innerResult; + ModelBindingResult? innerResult; if (isSuccess) { innerResult = ModelBindingResult.Success("somename.key", model); @@ -121,23 +119,19 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test innerResult = ModelBindingResult.Failed("somename.key"); } - var innerBinder = new Mock(); - innerBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext context) => - { - Assert.Equal("someName.key", context.ModelName); - return Task.FromResult(innerResult); - }); - var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder.Object); + var innerBinder = new StubModelBinder(context => + { + Assert.Equal("someName.key", context.ModelName); + return innerResult; + }); + var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder); var binder = new KeyValuePairModelBinder(); // Act var result = await binder.TryBindStrongModel(bindingContext, "key"); - // Assert - Assert.Equal(innerResult, result); + Assert.Equal(innerResult.Value, result); Assert.Empty(bindingContext.ModelState); } @@ -159,10 +153,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); var model = Assert.IsType>(result.Model); Assert.Equal(default(KeyValuePair), model); @@ -189,15 +183,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test context.ValueProvider = new TestValueProvider(new Dictionary()); // Act - var result = await binder.BindModelAsync(context); + var result = await binder.BindModelResultAsync(context); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } - private static ModelBindingContext CreateContext() + private static DefaultModelBindingContext CreateContext() { - var modelBindingContext = new ModelBindingContext() + var modelBindingContext = new DefaultModelBindingContext() { OperationBindingContext = new OperationBindingContext() { @@ -214,13 +208,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test return modelBindingContext; } - private static ModelBindingContext GetBindingContext( + private static DefaultModelBindingContext GetBindingContext( IValueProvider valueProvider, IModelBinder innerBinder = null, Type keyValuePairType = null) { var metataProvider = new EmptyModelMetadataProvider(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = metataProvider.GetMetadataForType( keyValuePairType ?? typeof(KeyValuePair)), @@ -242,36 +236,29 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test private static IModelBinder CreateIntBinder() { - var mockIntBinder = new Mock(); - mockIntBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext mbc) => + var mockIntBinder = new StubModelBinder(mbc => + { + if (mbc.ModelType == typeof(int)) { - if (mbc.ModelType == typeof(int)) - { - var model = 42; - return ModelBindingResult.SuccessAsync(mbc.ModelName, model); - } - return ModelBindingResult.NoResultAsync; - }); - return mockIntBinder.Object; + var model = 42; + return ModelBindingResult.Success(mbc.ModelName, model); + } + return null; + }); + return mockIntBinder; } private static IModelBinder CreateStringBinder() { - var mockStringBinder = new Mock(); - mockStringBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns((ModelBindingContext mbc) => + return new StubModelBinder(mbc => + { + if (mbc.ModelType == typeof(string)) { - if (mbc.ModelType == typeof(string)) - { - var model = "some-value"; - return ModelBindingResult.SuccessAsync(mbc.ModelName, model); - } - return ModelBindingResult.NoResultAsync; - }); - return mockStringBinder.Object; + var model = "some-value"; + return ModelBindingResult.Success(mbc.ModelName, model); + } + return null; + }); } private class ModelWithKeyValuePairProperty diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingContextTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingContextTest.cs deleted file mode 100644 index ea45587f7e..0000000000 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingContextTest.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test -{ - public class ModelBindingContextTest - { - [Fact] - public void CreateChildBindingContext_CopiesProperties() - { - // Arrange - var originalBindingContext = new ModelBindingContext - { - Model = new object(), - ModelMetadata = new TestModelMetadataProvider().GetMetadataForType(typeof(object)), - ModelName = "theName", - OperationBindingContext = new OperationBindingContext(), - ValueProvider = new SimpleValueProvider(), - ModelState = new ModelStateDictionary(), - }; - - var metadataProvider = new TestModelMetadataProvider(); - metadataProvider.ForType().BindingDetails(d => - { - d.BindingSource = BindingSource.Custom; - d.BinderType = typeof(TestModelBinder); - d.BinderModelName = "custom"; - }); - - var newModelMetadata = metadataProvider.GetMetadataForType(typeof(object)); - - // Act - var newBindingContext = ModelBindingContext.CreateChildBindingContext( - originalBindingContext, - newModelMetadata, - fieldName: "fieldName", - modelName: "modelprefix.fieldName", - model: null); - - // Assert - Assert.Same(newModelMetadata.BinderModelName, newBindingContext.BinderModelName); - Assert.Same(newModelMetadata.BinderType, newBindingContext.BinderType); - Assert.Same(newModelMetadata.BindingSource, newBindingContext.BindingSource); - Assert.False(newBindingContext.FallbackToEmptyPrefix); - Assert.Equal("fieldName", newBindingContext.FieldName); - Assert.False(newBindingContext.IsTopLevelObject); - Assert.Null(newBindingContext.Model); - Assert.Same(newModelMetadata, newBindingContext.ModelMetadata); - Assert.Equal("modelprefix.fieldName", newBindingContext.ModelName); - Assert.Same(originalBindingContext.ModelState, newBindingContext.ModelState); - Assert.Same(originalBindingContext.OperationBindingContext, newBindingContext.OperationBindingContext); - Assert.Same(originalBindingContext.ValueProvider, newBindingContext.ValueProvider); - } - - [Fact] - public void ModelTypeAreFedFromModelMetadata() - { - // Act - var bindingContext = new ModelBindingContext - { - ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)) - }; - - // Assert - Assert.Equal(typeof(int), bindingContext.ModelType); - } - - private class TestModelBinder : IModelBinder - { - public Task BindModelAsync(ModelBindingContext bindingContext) - { - throw new NotImplementedException(); - } - } - } -} diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingHelperTest.cs index 37a5bc6f12..443a74819e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingHelperTest.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; +using Microsoft.AspNetCore.Mvc.ModelBinding.Test; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Routing; using Moq; @@ -22,13 +23,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { public class ModelBindingHelperTest { - public static TheoryData UnsuccessfulModelBindingData + public static TheoryData UnsuccessfulModelBindingData { get { - return new TheoryData + return new TheoryData { - ModelBindingResult.NoResult, + null, ModelBindingResult.Failed("someKey"), }; } @@ -36,14 +37,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding [Theory] [MemberData(nameof(UnsuccessfulModelBindingData))] - public async Task TryUpdateModel_ReturnsFalse_IfBinderIsUnsuccessful(ModelBindingResult binderResult) + public async Task TryUpdateModel_ReturnsFalse_IfBinderIsUnsuccessful(ModelBindingResult? binderResult) { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(Task.FromResult(binderResult)); + var binder = new StubModelBinder(binderResult); var model = new MyModel(); // Act @@ -52,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding string.Empty, new ActionContext() { HttpContext = new DefaultHttpContext() }, metadataProvider, - GetCompositeBinder(binder.Object), + GetCompositeBinder(binder), Mock.Of(), new List(), new Mock(MockBehavior.Strict).Object, @@ -153,14 +151,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding [Theory] [MemberData(nameof(UnsuccessfulModelBindingData))] public async Task TryUpdateModel_UsingIncludePredicateOverload_ReturnsFalse_IfBinderIsUnsuccessful( - ModelBindingResult binderResult) + ModelBindingResult? binderResult) { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(Task.FromResult(binderResult)); + var binder = new StubModelBinder(binderResult); var model = new MyModel(); Func includePredicate = (context, propertyName) => true; @@ -170,7 +165,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding string.Empty, new ActionContext() { HttpContext = new DefaultHttpContext() }, metadataProvider, - GetCompositeBinder(binder.Object), + GetCompositeBinder(binder), Mock.Of(), new List(), new Mock(MockBehavior.Strict).Object, @@ -243,14 +238,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding [Theory] [MemberData(nameof(UnsuccessfulModelBindingData))] public async Task TryUpdateModel_UsingIncludeExpressionOverload_ReturnsFalse_IfBinderIsUnsuccessful( - ModelBindingResult binderResult) + ModelBindingResult? binderResult) { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(Task.FromResult(binderResult)); + var binder = new StubModelBinder(binderResult); var model = new MyModel(); // Act @@ -259,7 +251,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding string.Empty, new ActionContext() { HttpContext = new DefaultHttpContext() }, metadataProvider, - GetCompositeBinder(binder.Object), + GetCompositeBinder(binder), Mock.Of(), new List(), new Mock(MockBehavior.Strict).Object, @@ -500,14 +492,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding [Theory] [MemberData(nameof(UnsuccessfulModelBindingData))] public async Task TryUpdateModelNonGeneric_PredicateOverload_ReturnsFalse_IfBinderIsUnsuccessful( - ModelBindingResult binderResult) + ModelBindingResult? binderResult) { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(Task.FromResult(binderResult)); + var binder = new StubModelBinder(binderResult); var model = new MyModel(); Func includePredicate = (context, propertyName) => true; @@ -518,7 +507,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding prefix: "", actionContext: new ActionContext() { HttpContext = new DefaultHttpContext() }, metadataProvider: metadataProvider, - modelBinder: GetCompositeBinder(binder.Object), + modelBinder: GetCompositeBinder(binder), valueProvider: Mock.Of(), inputFormatters: new List(), objectModelValidator: new Mock(MockBehavior.Strict).Object, @@ -593,14 +582,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding [Theory] [MemberData(nameof(UnsuccessfulModelBindingData))] public async Task TryUpdateModelNonGeneric_ModelTypeOverload_ReturnsFalse_IfBinderIsUnsuccessful( - ModelBindingResult binderResult) + ModelBindingResult? binderResult) { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var binder = new Mock(); - binder - .Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(Task.FromResult(binderResult)); + var binder = new StubModelBinder(binderResult); + var model = new MyModel(); // Act @@ -669,9 +656,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var binder = new Mock(); - binder.Setup(b => b.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + var binder = new StubModelBinder(); var model = new MyModel(); Func includePredicate = (context, propertyName) => true; diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingResultTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingResultTest.cs index 49da898c23..07998f9734 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingResultTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ModelBindingResultTest.cs @@ -23,23 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test Assert.True(result.IsModelSet); Assert.Same(model, result.Model); } - - [Fact] - public async Task SuccessAsync_SetsProperties() - { - // Arrange - var key = "someName"; - var model = "some model"; - - // Act - var result = await ModelBindingResult.SuccessAsync(key, model); - - // Assert - Assert.Same(key, result.Key); - Assert.True(result.IsModelSet); - Assert.Same(model, result.Model); - } - + [Fact] public void Failed_SetsProperties() { @@ -54,44 +38,5 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test Assert.False(result.IsModelSet); Assert.Null(result.Model); } - - [Fact] - public async Task FailedAsync_SetsProperties() - { - // Arrange - var key = "someName"; - - // Act - var result = await ModelBindingResult.FailedAsync(key); - - // Assert - Assert.Same(key, result.Key); - Assert.False(result.IsModelSet); - Assert.Null(result.Model); - } - - [Fact] - public void NoResult_SetsProperties() - { - // Arrange & Act - var result = ModelBindingResult.NoResult; - - // Assert - Assert.Null(result.Key); - Assert.False(result.IsModelSet); - Assert.Null(result.Model); - } - - [Fact] - public async Task NoResultAsync_SetsProperties() - { - // Arrange & Act - var result = await ModelBindingResult.NoResultAsync; - - // Assert - Assert.Null(result.Key); - Assert.False(result.IsModelSet); - Assert.Null(result.Model); - } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs index 8b2beae942..4efefcc29e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Internal; +using Microsoft.AspNetCore.Mvc.ModelBinding.Test; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Testing; using Moq; @@ -33,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var metadataProvider = new TestModelMetadataProvider(); var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { IsTopLevelObject = isTopLevelObject, @@ -70,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding .First(metadata => metadata.PropertyName == nameof(Document.SubDocument)); var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, OperationBindingContext = new OperationBindingContext @@ -97,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { // Here the metadata represents a top level object. IsTopLevelObject = true, @@ -130,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(BinderMetadataPocoType)), ValueProvider = mockValueProvider.Object, @@ -174,7 +175,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var modelMetadata = typeMetadata.Properties[nameof(SimpleContainer.Simple)]; var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, ModelName = "SimpleContainer.Simple", @@ -206,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Arrange var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { IsTopLevelObject = false, @@ -231,7 +232,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding // Arrange var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { IsTopLevelObject = true, ModelMetadata = GetMetadataForType(typeof(PersonWithNoProperties)) @@ -266,7 +267,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(modelType), ValueProvider = mockValueProvider.Object, @@ -325,7 +326,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var modelMetadata = GetMetadataForType(modelType); var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, ValueProvider = mockValueProvider.Object, @@ -374,7 +375,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var bindingContext = new MutableObjectBinderContext { - ModelBindingContext = new ModelBindingContext + ModelBindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(modelType), ValueProvider = mockValueProvider.Object, @@ -411,19 +412,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding .Returns(true); // Mock binder fails to bind all properties. - var mockBinder = new Mock(); - mockBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + var mockBinder = new StubModelBinder(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(Person)), ModelName = "someName", ValueProvider = mockValueProvider.Object, OperationBindingContext = new OperationBindingContext { - ModelBinder = mockBinder.Object, + ModelBinder = mockBinder, MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), ValidatorProvider = Mock.Of() }, @@ -442,7 +440,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding .Returns(new ModelMetadata[0]); // Act - var retValue = await testableBinder.Object.BindModelAsync(bindingContext); + var retValue = await testableBinder.Object.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(retValue); @@ -462,12 +460,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding .Returns(false); // Mock binder fails to bind all properties. - var mockBinder = new Mock(); - mockBinder - .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(ModelBindingResult.NoResultAsync); + var mockBinder = new StubModelBinder(); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { IsTopLevelObject = true, ModelMetadata = GetMetadataForType(typeof(Person)), @@ -475,7 +470,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding ValueProvider = mockValueProvider.Object, OperationBindingContext = new OperationBindingContext { - ModelBinder = mockBinder.Object, + ModelBinder = mockBinder, MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), ValidatorProvider = Mock.Of() }, @@ -495,7 +490,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding .Returns(new ModelMetadata[0]); // Act - var retValue = await testableBinder.Object.BindModelAsync(bindingContext); + var retValue = await testableBinder.Object.BindModelResultAsync(bindingContext); // Assert Assert.NotNull(retValue); @@ -548,7 +543,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public void CreateModel_InstantiatesInstanceOfMetadataType() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(Person)) }; @@ -566,7 +561,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public void GetModel_ModelIsNotNull_DoesNothing() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { Model = new Person(), ModelMetadata = GetMetadataForType(typeof(Person)) @@ -588,7 +583,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public void GetModel_ModelIsNull_CallsCreateModel() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(Person)) }; @@ -614,7 +609,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Arrange var expectedPropertyNames = new[] { "FirstName", "LastName" }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(PersonWithBindExclusion)), OperationBindingContext = new OperationBindingContext @@ -650,7 +645,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding nameof(Person.PropertyWithInitializedValue), nameof(Person.PropertyWithInitializedValueAndDefault), }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(Person)), OperationBindingContext = new OperationBindingContext @@ -675,7 +670,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Arrange var expectedPropertyNames = new[] { "IncludedByDefault1", "IncludedByDefault2" }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(TypeWithExcludedPropertiesUsingBindAttribute)), OperationBindingContext = new OperationBindingContext @@ -707,7 +702,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { // Arrange var expectedPropertyNames = new[] { "IncludedExplicitly1", "IncludedExplicitly2" }; - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(TypeWithIncludedPropertiesUsingBindAttribute)), OperationBindingContext = new OperationBindingContext @@ -731,7 +726,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public void GetRequiredPropertiesCollection_MixedAttributes() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(ModelWithMixedBindingBehaviors)), OperationBindingContext = new OperationBindingContext @@ -752,7 +747,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public void GetPropertyValidationInfo_WithIndexerProperties_Succeeds() { // Arrange - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = GetMetadataForType(typeof(PersonCollection)), OperationBindingContext = new OperationBindingContext @@ -781,7 +776,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding }; var containerMetadata = GetMetadataForType(model.GetType()); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { Model = model, ModelMetadata = containerMetadata, @@ -831,7 +826,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding }; var containerMetadata = GetMetadataForType(model.GetType()); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { Model = model, ModelMetadata = containerMetadata, @@ -881,7 +876,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding }; var containerMetadata = GetMetadataForType(model.GetType()); - var bindingContext = new ModelBindingContext() + var bindingContext = new DefaultModelBindingContext() { Model = model, ModelMetadata = containerMetadata, @@ -1566,9 +1561,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding bindingContext.ModelState["foo.NameNoAttribute"].Errors[0].Exception.Message); } - private static ModelBindingContext CreateContext(ModelMetadata metadata, object model) + private static DefaultModelBindingContext CreateContext(ModelMetadata metadata, object model) { - return new ModelBindingContext + return new DefaultModelBindingContext { Model = model, ModelMetadata = metadata, diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ServicesModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ServicesModelBinderTest.cs index bed2f50cc3..ab7e6079c7 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ServicesModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/ServicesModelBinderTest.cs @@ -22,10 +22,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var modelBindingContext = GetBindingContext(type); // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.True(result.IsModelSet); Assert.NotNull(result.Model); Assert.Equal("modelName", result.Key); @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } [Fact] - public async Task ServiceModelBinder_ReturnsNoResult_ForNullBindingSource() + public async Task ServiceModelBinder_ReturnsNothing_ForNullBindingSource() { // Arrange var type = typeof(IService); @@ -47,14 +47,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding modelBindingContext.BindingSource = null; // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } [Fact] - public async Task ServiceModelBinder_ReturnsNoResult_ForNonServiceBindingSource() + public async Task ServiceModelBinder_ReturnsNothing_ForNonServiceBindingSource() { // Arrange var type = typeof(IService); @@ -64,13 +64,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding modelBindingContext.BindingSource = BindingSource.Body; // Act - var result = await binder.BindModelAsync(modelBindingContext); + var result = await binder.BindModelResultAsync(modelBindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } - private static ModelBindingContext GetBindingContext(Type modelType) + private static DefaultModelBindingContext GetBindingContext(Type modelType) { var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Services); @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding var services = new ServiceCollection(); services.AddSingleton(new Service()); - var bindingContext = new ModelBindingContext + var bindingContext = new DefaultModelBindingContext { ModelMetadata = modelMetadata, ModelName = "modelName", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/SimpleTypeModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/SimpleTypeModelBinderTest.cs index 209a8107ae..bcdf9c767a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/SimpleTypeModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/SimpleTypeModelBinderTest.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test [InlineData(typeof(object))] [InlineData(typeof(Calendar))] [InlineData(typeof(TestClass))] - public async Task BindModel_ReturnsNoResult_IfTypeCannotBeConverted(Type destinationType) + public async Task BindModel_ReturnsNothing_IfTypeCannotBeConverted(Type destinationType) { // Arrange var bindingContext = GetBindingContext(destinationType); @@ -27,10 +27,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); } public static TheoryData ConvertableTypeData @@ -72,10 +72,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.False(result.IsModelSet); } @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert Assert.False(result.IsModelSet); @@ -123,10 +123,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.NotEqual(default(ModelBindingResult), result); Assert.Null(result.Model); Assert.False(bindingContext.ModelState.IsValid); var error = Assert.Single(bindingContext.ModelState["theModelName"].Errors); @@ -141,10 +141,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.Equal(default(ModelBindingResult), result); Assert.Empty(bindingContext.ModelState); } @@ -161,7 +161,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert Assert.Null(result.Model); @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert Assert.True(result.IsModelSet); @@ -207,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test var binder = new SimpleTypeModelBinder(); // Act - var result = await binder.BindModelAsync(bindingContext); + var result = await binder.BindModelResultAsync(bindingContext); // Assert Assert.True(result.IsModelSet); @@ -215,9 +215,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test Assert.Equal((FlagsEnum)expected, boundModel); } - private static ModelBindingContext GetBindingContext(Type modelType) + private static DefaultModelBindingContext GetBindingContext(Type modelType) { - return new ModelBindingContext + return new DefaultModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType), ModelName = "theModelName", diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/StubModelBinder.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/StubModelBinder.cs new file mode 100644 index 0000000000..b61e0738d0 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/StubModelBinder.cs @@ -0,0 +1,74 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Internal; + +namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test +{ + public class StubModelBinder : IModelBinder + { + private readonly Func _callback; + + public StubModelBinder() + { + _callback = context => TaskCache.CompletedTask; + } + + public StubModelBinder(ModelBindingResult? result) + { + _callback = context => + { + context.Result = result; + return TaskCache.CompletedTask; + }; + } + + public StubModelBinder(Action callback) + { + _callback = context => + { + callback(context); + return TaskCache.CompletedTask; + }; + } + + public StubModelBinder(Func callback) + { + _callback = context => + { + var result = callback.Invoke(context); + context.Result = result; + return TaskCache.CompletedTask; + }; + } + + public StubModelBinder(Func> callback) + { + _callback = async context => + { + var result = await callback.Invoke(context); + context.Result = result; + }; + } + + public int BindModelCount { get; set; } + + public IModelBinder Object => this; + + public virtual async Task BindModelAsync(ModelBindingContext bindingContext) + { + BindModelCount += 1; + + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + + await _callback.Invoke(bindingContext); + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs index 4f49c0d808..e7d8ab032a 100644 --- a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal var type = typeof(User); var provider = CreateProvider(); - var context = new ModelBindingContext(); + var context = new DefaultModelBindingContext(); var expected = new[] { "IsAdmin", "UserName" }; diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs index bb5d6879db..3249bd5fdc 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs @@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var model = new Person3(); // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; var model = new Person4(); // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -229,7 +229,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ArrayModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ArrayModelBinderIntegrationTest.cs index d359b46d6f..81ce99b50d 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ArrayModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ArrayModelBinderIntegrationTest.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -276,7 +276,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -317,7 +317,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs index 8d41962de0..d68f211697 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs @@ -1,9 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Globalization; +using System; +using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Testing; using Xunit; @@ -34,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -71,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); + Assert.Equal(null, modelBindingResult); // ModelState (not set unless inner binder sets it) Assert.True(modelState.IsValid); @@ -108,7 +110,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests // Assert // ModelBindingResult - Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); + Assert.Equal(null, modelBindingResult); // ModelState Assert.True(modelState.IsValid); @@ -144,7 +146,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests // Assert // ModelBindingResult - Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); + Assert.Equal(null, modelBindingResult); // ModelState Assert.True(modelState.IsValid); @@ -174,7 +176,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -217,7 +219,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -258,7 +260,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -280,11 +282,17 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests private class AddressModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + if (bindingContext.ModelType != typeof(Address)) { - return null; + return TaskCache.CompletedTask; } var address = new Address() { Street = "SomeStreet" }; @@ -294,45 +302,73 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests new string[] { address.Street }, address.Street); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, address); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, address); + return TaskCache.CompletedTask; } } private class SuccessModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + var model = "Success"; bindingContext.ModelState.SetModelValue( bindingContext.ModelName, new string[] { model }, model); - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); + bindingContext.Result =ModelBindingResult.Success(bindingContext.ModelName, model); + return TaskCache.CompletedTask; } } private class NullModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model: null); + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model: null); + return TaskCache.CompletedTask; } } private class NullModelNotSetModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { - return ModelBindingResult.FailedAsync(bindingContext.ModelName); + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + + bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName); + return TaskCache.CompletedTask; } } private class NullResultModelBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { - return ModelBindingResult.NoResultAsync; + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + + return TaskCache.CompletedTask; } } } diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs index 9edfd1e322..4a5f65df79 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -258,7 +258,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -301,7 +301,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -379,7 +379,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -421,7 +421,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -480,7 +480,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -518,7 +518,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -582,7 +582,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -639,7 +639,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ByteArrayModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ByteArrayModelBinderIntegrationTest.cs index 316a4e546c..950c0ca7dd 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ByteArrayModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ByteArrayModelBinderIntegrationTest.cs @@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -90,12 +90,12 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult - Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); + Assert.Equal(default(ModelBindingResult), modelBindingResult); // ModelState Assert.True(modelState.IsValid); @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CancellationTokenModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CancellationTokenModelBinderIntegrationTest.cs index b125bb6b0c..aee2d1b944 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CancellationTokenModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CancellationTokenModelBinderIntegrationTest.cs @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs index cf40d06d87..a096de6188 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -230,7 +230,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -263,7 +263,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -301,7 +301,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -360,7 +360,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -463,7 +463,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -506,7 +506,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -557,7 +557,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -607,7 +607,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -664,7 +664,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -703,7 +703,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -927,7 +927,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs index 09354e5613..7f24cee875 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -164,7 +164,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -292,7 +292,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -332,7 +332,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -371,7 +371,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -522,7 +522,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormCollectionModelBindingIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormCollectionModelBindingIntegrationTest.cs index 20dc43ef2b..a12f3c40d8 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormCollectionModelBindingIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormCollectionModelBindingIntegrationTest.cs @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult @@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormFileModelBindingIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormFileModelBindingIntegrationTest.cs index 52a4f39442..ac72c3dab9 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormFileModelBindingIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/FormFileModelBindingIntegrationTest.cs @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult @@ -149,10 +149,10 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert - Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); + Assert.Equal(default(ModelBindingResult), modelBindingResult); // ModelState Assert.True(modelState.IsValid); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs index 1216a7d4ca..081bab15e1 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding; using Xunit; @@ -40,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -78,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -117,7 +119,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -150,18 +152,25 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests private class AddressBinder : IModelBinder { - public Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { + if (bindingContext == null) + { + throw new ArgumentNullException(nameof(bindingContext)); + } + Debug.Assert(bindingContext.Result == null); + var allowedBindingSource = bindingContext.BindingSource; - if (allowedBindingSource == null || + if (allowedBindingSource == null || !allowedBindingSource.CanAcceptDataFrom(BindAddressAttribute.Source)) { // Binding Sources are opt-in. This model either didn't specify one or specified something // incompatible so let other binders run. - return ModelBindingResult.NoResultAsync; + return TaskCache.CompletedTask; } - return ModelBindingResult.SuccessAsync(bindingContext.ModelName, new Address()); + bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, new Address()); + return TaskCache.CompletedTask; } } @@ -186,7 +195,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -220,7 +229,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -255,7 +264,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -300,7 +309,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -345,7 +354,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -380,7 +389,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -424,7 +433,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -468,7 +477,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -504,7 +513,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -552,7 +561,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -600,7 +609,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/HeaderModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/HeaderModelBinderIntegrationTest.cs index c50d2f13b3..07774a8dd3 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/HeaderModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/HeaderModelBinderIntegrationTest.cs @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs index 1012378f5b..7f5007b583 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.False(modelBindingResult.IsModelSet); @@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.False(modelBindingResult.IsModelSet); @@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.False(modelBindingResult.IsModelSet); @@ -201,7 +201,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.False(modelBindingResult.IsModelSet); @@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -324,7 +324,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -360,7 +360,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -405,7 +405,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -446,7 +446,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -487,7 +487,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelPrefixSelectionIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelPrefixSelectionIntegrationTest.cs index e96ca74cd9..38ccaf9e02 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelPrefixSelectionIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelPrefixSelectionIntegrationTest.cs @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs index e070aa0b74..1f3c7cfb63 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -280,7 +280,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -366,7 +366,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -420,7 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -464,7 +464,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -509,7 +509,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -555,7 +555,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -596,7 +596,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -637,7 +637,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -683,7 +683,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -729,7 +729,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -767,7 +767,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -809,7 +809,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -855,7 +855,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -901,7 +901,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -939,7 +939,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -981,7 +981,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1027,7 +1027,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1073,7 +1073,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1111,7 +1111,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1153,7 +1153,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1199,7 +1199,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1245,7 +1245,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1283,7 +1283,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1331,7 +1331,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1375,7 +1375,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1421,7 +1421,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1473,7 +1473,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1518,7 +1518,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1567,7 +1567,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1618,7 +1618,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1661,7 +1661,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1700,7 +1700,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1743,7 +1743,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1786,7 +1786,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1825,7 +1825,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1869,7 +1869,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1913,7 +1913,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs index 998add04b3..c5549acdb2 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult @@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs index 250211fefb..2d350d3537 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -276,7 +276,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -325,7 +325,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -377,7 +377,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult @@ -420,7 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert @@ -458,12 +458,12 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult - Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); + Assert.Equal(default(ModelBindingResult), modelBindingResult); // ModelState Assert.True(modelState.IsValid); @@ -512,7 +512,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert // ModelBindingResult diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs index 9ad992e286..8862dacc35 100644 --- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -314,7 +314,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -353,7 +353,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -401,7 +401,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -439,7 +439,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -487,7 +487,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -524,7 +524,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -575,7 +575,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -612,7 +612,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -652,7 +652,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -710,7 +710,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -747,7 +747,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -817,7 +817,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -854,7 +854,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -905,7 +905,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -942,7 +942,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -982,7 +982,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1022,7 +1022,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1062,7 +1062,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests var modelState = operationContext.ActionContext.ModelState; // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1193,7 +1193,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests modelState.SetModelValue("CustomParameter.message", "Hello", "Hello"); // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1236,7 +1236,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests modelState.SetModelValue("message", "Hello", "Hello"); // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1281,7 +1281,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests modelState.SetModelValue("other.key", "1", "1"); // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); @@ -1328,7 +1328,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests modelState.SetModelValue("other.key", "1", "1"); // Act - var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); + var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult); // Assert Assert.True(modelBindingResult.IsModelSet); diff --git a/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/HttpRequestMessage/HttpRequestMessageModelBinderTest.cs b/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/HttpRequestMessage/HttpRequestMessageModelBinderTest.cs index 643ab53e53..10261297e8 100644 --- a/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/HttpRequestMessage/HttpRequestMessageModelBinderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.WebApiCompatShimTest/HttpRequestMessage/HttpRequestMessageModelBinderTest.cs @@ -22,10 +22,12 @@ namespace Microsoft.AspNetCore.Mvc.WebApiCompatShim var expectedModel = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage(); // Act - var result = await binder.BindModelAsync(bindingContext); + await binder.BindModelAsync(bindingContext); // Assert - Assert.NotEqual(ModelBindingResult.NoResult, result); + Assert.True(bindingContext.Result.HasValue); + + var result = bindingContext.Result.Value; Assert.True(result.IsModelSet); Assert.Same(expectedModel, result.Model); @@ -46,16 +48,16 @@ namespace Microsoft.AspNetCore.Mvc.WebApiCompatShim var bindingContext = GetBindingContext(type); // Act - var result = await binder.BindModelAsync(bindingContext); + await binder.BindModelAsync(bindingContext); // Assert - Assert.Equal(ModelBindingResult.NoResult, result); + Assert.False(bindingContext.Result.HasValue); } - private static ModelBindingContext GetBindingContext(Type modelType) + private static DefaultModelBindingContext GetBindingContext(Type modelType) { var metadataProvider = new EmptyModelMetadataProvider(); - ModelBindingContext bindingContext = new ModelBindingContext + DefaultModelBindingContext bindingContext = new DefaultModelBindingContext { ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelName = "someName",