Reducing ModelBindingContext allocations

Closes #4007, Fixes #3622, Fixes #3621

Squashed commit of the following:

commit 4b3095671d945ae79baa4fc4ba22a2ce5ebe488e
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Mon Feb 1 14:47:28 2016 -0800

    PR Feedback #4007

    End these new guys with a period.

commit f4c745a0a805b960234cd4d810378bc40b8e5c8c
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Mon Feb 1 14:44:10 2016 -0800

    Fixing unit tests

    Also fixes rebase error in CancellationTokenModelBinder

commit f3874cc27388552e863d99d8e6631a2901f8e000
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Mon Feb 1 13:01:02 2016 -0800

    PR Feedback #4007

    Remove commented-out code.

commit 44ec1a5a3bd4fdeb4d1c4de9f0b402ff0fd34ffe
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Mon Feb 1 12:22:04 2016 -0800

    PR Feedback #4007

    Why now public?

commit 9aa45eda42ec9b11b7e6b73a14e887f1be8cb130
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Mon Feb 1 12:18:19 2016 -0800

    PR Feedback #4007

    Leave out .Test

commit 58d32d809797d25cc9b5b4c0516ae9e5992fa66e
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Fri Jan 29 15:30:54 2016 -0800

    PR Feedback #4007

    Don't need extra line

commit cf26f3e5125792d6af0ca2afda672e241fe0e164
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Fri Jan 29 15:12:50 2016 -0800

    PR Feedback #4007

    Suggest Microsoft.AspNetCore.Mvc.Internal.

commit 5360599e9c09ab97b8136977ee0917fd88f51f76
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Fri Jan 29 14:57:28 2016 -0800

    PR Feedback #4007

    Remove this line.

commit ce63edba51721412684a54886109e6b2225c6c99
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Fri Jan 29 14:14:02 2016 -0800

    PR Feedback #4007

    incorrect mentions of DefaultModelBindingContext in doc comments

commit bbc738ca2304243839e8d68615ff4bbf14f3279c
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Fri Jan 29 11:02:00 2016 -0800

    PR Feedback #4007

    remove the file

commit 3dd0d10d7f16c94df5f6d34ecb5f2efda62bccd8
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Thu Jan 28 12:37:18 2016 -0800

    PR Feedback

    DefaultModelBindingContext should not be in Abstractions

commit 5e3b6a1486283f45867830693d4fd23cc967f06f
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Thu Jan 28 10:54:28 2016 -0800

    PR Feedback

    remove the other static constructors for Task<ModelBindingResult>
    they don't have a purpose anymore

commit d0e15211530668ec21406121342715b0d0f606a6
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Thu Jan 28 10:48:25 2016 -0800

    PR Feedback

    * coding standards...
    * yea
    * private readonly

commit 6c2c640611686a554a8c417a407fe169c45a690e
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Thu Jan 28 10:46:12 2016 -0800

    PR Feedback

    * disposable -> <see cref="ModelBindingContextDisposable"/>
    * Fill in the blanks.

commit df07891c798627ac9c8fce6a7598d9386e979615
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Wed Jan 27 23:34:42 2016 -0800

    PR Feedback

    Add a using for the Internal namespace.

commit bef09536f881d400f15a83b7788c828903679a38
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Wed Jan 27 23:27:30 2016 -0800

    PR Feedback

    needs lots of /// doc love and blank lines

commit 4173488112f2889d662d5a7c55f249aefa821c22
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Wed Jan 27 23:06:49 2016 -0800

    PR Feedback

    Temp file accidentally added. Oops.

commit 6790d6104d5bd72ce7eab270bfe9a360cacf74f2
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Wed Jan 27 23:04:40 2016 -0800

    PR Feedback

    please remove the else bits after returns

commit 8d077ee27109133d18c5cddfe3b9b6c6e9a40e0e
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Wed Jan 27 20:29:50 2016 -0800

    PR Feedback

    Why not use the Task helper used elsewhere?

commit eb5fe6f95a463eb2f162f51649ffea57db87e286
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Wed Jan 27 20:28:31 2016 -0800

    PR Feedback

    Sort usings

commit df3bd00c4b59d2434e3a7be28e637d3c8008ae32
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Wed Jan 27 20:27:38 2016 -0800

    PR Feedback

    Dead code

commit fe7ec17fbb5209f2904f067ec1f91169ab05fb33
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Wed Jan 27 20:26:04 2016 -0800

    PR Feedback

    Putting internal back in place

commit 496f1f97ac48b2e95572dd6d463ced3366f8d36c
Author: Louis DeJardin <lodejard@microsoft.com>
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 <lodejard@microsoft.com>
Date:   Wed Jan 27 19:38:15 2016 -0800

    Renames to asp.net core

commit e1cf523119084e35b70f11f67f64f651c39e1c8b
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Thu Jan 21 21:21:44 2016 -0800

    Removing NoResult and fixing tests

commit 5af6223a4d60b6c4139c1fc62ebf297ab0e5454f
Author: Louis DeJardin <lodejard@microsoft.com>
Date:   Thu Dec 17 11:49:08 2015 -0800

    Reducing ModelBindingContext allocations
This commit is contained in:
Louis DeJardin 2016-02-02 12:10:43 -08:00
parent 2aca8810d3
commit c116a38c87
70 changed files with 1794 additions and 1632 deletions

View File

@ -28,6 +28,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
global.json = global.json global.json = global.json
NuGet.config = NuGet.config
NuGetPackageVerifier.json = NuGetPackageVerifier.json NuGetPackageVerifier.json = NuGetPackageVerifier.json
EndProjectSection EndProjectSection
EndProject EndProject

View File

@ -24,9 +24,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// with <see cref="ModelBindingResult.Success"/>. If model binding failed, the /// with <see cref="ModelBindingResult.Success"/>. If model binding failed, the
/// <see cref="ModelBindingResult"/> should be a value created with <see cref="ModelBindingResult.Failed"/>. /// <see cref="ModelBindingResult"/> should be a value created with <see cref="ModelBindingResult.Failed"/>.
/// If there was no data, or this model binder cannot handle the operation, the /// If there was no data, or this model binder cannot handle the operation, the
/// <see cref="ModelBindingResult"/> should be <see cref="ModelBindingResult.NoResult"/>. /// <see cref="ModelBindingContext.Result"/> should be null.
/// </para> /// </para>
/// </returns> /// </returns>
Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext); Task BindModelAsync(ModelBindingContext bindingContext);
} }
} }

View File

@ -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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -9,248 +9,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// <summary> /// <summary>
/// A context that contains operating information for model binding and validation. /// A context that contains operating information for model binding and validation.
/// </summary> /// </summary>
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;
/// <summary>
/// Initializes a new instance of the <see cref="ModelBindingContext"/> class.
/// </summary>
public ModelBindingContext()
{
}
/// <summary>
/// Creates a new <see cref="ModelBindingContext"/> for top-level model binding operation.
/// </summary>
/// <param name="operationBindingContext">
/// The <see cref="OperationBindingContext"/> associated with the binding operation.
/// </param>
/// <param name="metadata"><see cref="ModelMetadata"/> associated with the model.</param>
/// <param name="bindingInfo"><see cref="BindingInfo"/> associated with the model.</param>
/// <param name="modelName">The name of the property or parameter being bound.</param>
/// <returns>A new instance of <see cref="ModelBindingContext"/>.</returns>
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,
};
}
/// <summary>
/// Represents the <see cref="OperationBindingContext"/> associated with this context.
/// </summary>
public OperationBindingContext OperationBindingContext
{
get { return _operationBindingContext; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_operationBindingContext = value;
}
}
/// <summary>
/// Gets or sets the name of the current field being bound.
/// </summary>
public string FieldName
{
get { return _fieldName; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_fieldName = value;
}
}
/// <summary>
/// Gets or sets the model value for the current operation.
/// </summary>
/// <remarks>
/// The <see cref="Model"/> will typically be set for a binding operation that works
/// against a pre-existing model object to update certain properties.
/// </remarks>
public object Model { get; set; }
/// <summary>
/// Gets or sets the metadata for the model associated with this context.
/// </summary>
public ModelMetadata ModelMetadata
{
get { return _modelMetadata; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_modelMetadata = value;
}
}
/// <summary>
/// Gets or sets the name of the model. This property is used as a key for looking up values in
/// <see cref="IValueProvider"/> during model binding.
/// </summary>
public string ModelName
{
get { return _modelName; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_modelName = value;
}
}
/// <summary>
/// Gets or sets the <see cref="ModelStateDictionary"/> used to capture <see cref="ModelState"/> values
/// for properties in the object graph of the model when binding.
/// </summary>
public ModelStateDictionary ModelState
{
get { return _modelState; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_modelState = value;
}
}
/// <summary>
/// Gets the type of the model.
/// </summary>
/// <remarks>
/// The <see cref="ModelMetadata"/> property must be set to access this property.
/// </remarks>
public Type ModelType => ModelMetadata?.ModelType;
/// <summary> /// <summary>
/// Gets or sets a model name which is explicitly set using an <see cref="IModelNameProvider"/>. /// Gets or sets a model name which is explicitly set using an <see cref="IModelNameProvider"/>.
/// <see cref="Model"/>.
/// </summary> /// </summary>
public string BinderModelName { get; set; } public abstract string BinderModelName { get; set; }
/// <summary>
/// Gets or sets a value which represents the <see cref="BindingSource"/> associated with the
/// <see cref="Model"/>.
/// </summary>
public BindingSource BindingSource { get; set; }
/// <summary> /// <summary>
/// Gets the <see cref="Type"/> of an <see cref="IModelBinder"/> associated with the /// Gets the <see cref="Type"/> of an <see cref="IModelBinder"/> associated with the
/// <see cref="Model"/>. /// <see cref="Model"/>.
/// </summary> /// </summary>
public Type BinderType { get; set; } public abstract Type BinderType { get; set; }
/// <summary>
/// Gets or sets a value which represents the <see cref="ModelBinding.BindingSource"/> associated with the
/// <see cref="Model"/>.
/// </summary>
public abstract BindingSource BindingSource { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value that indicates whether the binder should use an empty prefix to look up /// 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 <c>true</c> when <see cref="IsTopLevelObject"/> is /// Passed into the model binding system. Should not be <c>true</c> when <see cref="IsTopLevelObject"/> is
/// <c>false</c>. /// <c>false</c>.
/// </remarks> /// </remarks>
public bool FallbackToEmptyPrefix { get; set; } public abstract bool FallbackToEmptyPrefix { get; set; }
/// <summary>
/// Gets or sets the name of the current field being bound.
/// </summary>
public abstract string FieldName { get; set; }
/// <summary> /// <summary>
/// Gets or sets an indication that the current binder is handling the top-level object. /// Gets or sets an indication that the current binder is handling the top-level object.
/// </summary> /// </summary>
/// <remarks>Passed into the model binding system.</remarks> /// <remarks>Passed into the model binding system.</remarks>
public bool IsTopLevelObject { get; set; } public abstract bool IsTopLevelObject { get; set; }
/// <summary> /// <summary>
/// Gets or sets the <see cref="IValueProvider"/> associated with this context. /// Gets or sets the model value for the current operation.
/// </summary> /// </summary>
public IValueProvider ValueProvider /// <remarks>
{ /// The <see cref="Model"/> will typically be set for a binding operation that works
get { return _valueProvider; } /// against a pre-existing model object to update certain properties.
set /// </remarks>
{ public abstract object Model { get; set; }
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_valueProvider = value; /// <summary>
} /// Gets or sets the metadata for the model associated with this context.
} /// </summary>
public abstract ModelMetadata ModelMetadata { get; set; }
/// <summary>
/// Gets or sets the name of the model. This property is used as a key for looking up values in
/// <see cref="IValueProvider"/> during model binding.
/// </summary>
public abstract string ModelName { get; set; }
/// <summary>
/// Gets or sets the <see cref="ModelStateDictionary"/> used to capture <see cref="ModelState"/> values
/// for properties in the object graph of the model when binding.
/// </summary>
public abstract ModelStateDictionary ModelState { get; set; }
/// <summary>
/// Gets the type of the model.
/// </summary>
/// <remarks>
/// The <see cref="ModelMetadata"/> property must be set to access this property.
/// </remarks>
public abstract Type ModelType { get; }
/// <summary>
/// Represents the <see cref="ModelBinding.OperationBindingContext"/> associated with this context.
/// </summary>
public abstract OperationBindingContext OperationBindingContext { get; set; }
/// <summary> /// <summary>
/// Gets or sets a predicate which will be evaluated for each property to determine if the property /// Gets or sets a predicate which will be evaluated for each property to determine if the property
/// is eligible for model binding. /// is eligible for model binding.
/// </summary> /// </summary>
public Func<ModelBindingContext, string, bool> PropertyFilter { get; set; } public abstract Func<ModelBindingContext, string, bool> PropertyFilter { get; set; }
/// <summary> /// <summary>
/// Gets or sets the <see cref="ValidationStateDictionary"/>. Used for tracking validation state to /// Gets or sets the <see cref="ValidationStateDictionary"/>. Used for tracking validation state to
/// customize validation behavior for a model object. /// customize validation behavior for a model object.
/// </summary> /// </summary>
public ValidationStateDictionary ValidationState { get; set; } public abstract ValidationStateDictionary ValidationState { get; set; }
/// <summary>
/// Gets or sets the <see cref="IValueProvider"/> associated with this context.
/// </summary>
public abstract IValueProvider ValueProvider { get; set; }
/// <summary>
/// <para>
/// On completion returns a <see cref="ModelBindingResult"/> which
/// represents the result of the model binding process.
/// </para>
/// <para>
/// If model binding was successful, the <see cref="ModelBindingResult"/> should be a value created
/// with <see cref="ModelBindingResult.Success"/>. If model binding failed, the
/// <see cref="ModelBindingResult"/> should be a value created with <see cref="ModelBindingResult.Failed"/>.
/// If there was no data, or this model binder cannot handle the operation, the
/// <see cref="ModelBindingResult"/> should be null.
/// </para>
/// </summary>
public abstract ModelBindingResult? Result { get; set; }
/// <summary>
/// Pushes a layer of state onto this context. Model binders will call this as part of recursion when binding properties
/// or collection items.
/// </summary>
/// <param name="modelMetadata"><see cref="ModelBinding.ModelMetadata"/> to assign to the <see cref="ModelMetadata"/> property.</param>
/// <param name="fieldName">Name to assign to the <see cref="FieldName"/> property.</param>
/// <param name="modelName">Name to assign to the <see cref="ModelName"/> property.</param>
/// <param name="model">Instance to assign to the <see cref="Model"/> property.</param>
/// <returns>A <see cref="NestedScope"/> scope object which should be used in a using statement where PushContext is called.</returns>
public abstract NestedScope EnterNestedScope(ModelMetadata modelMetadata, string fieldName, string modelName, object model);
/// <summary>
/// Pushes a layer of state onto this context. Model binders will call this as part of recursion when binding properties
/// or collection items.
/// </summary>
/// <returns>A <see cref="NestedScope"/> scope object which should be used in a using statement where PushContext is called.</returns>
public abstract NestedScope EnterNestedScope();
/// <summary>
/// Removes a layer of state pushed by calling <see cref="EnterNestedScope"/>.
/// </summary>
protected abstract void ExitNestedScope();
/// <summary>
/// Return value of <see cref="ModelBindingContext.EnterNestedScope"/>. Should be disposed
/// by caller when child binding context state should be popped off of
/// the <see cref="ModelBindingContext"/>.
/// </summary>
public struct NestedScope : IDisposable
{
private readonly ModelBindingContext _context;
/// <summary>
/// Initializes the <see cref="NestedScope"/> for a <see cref="ModelBindingContext"/>.
/// </summary>
/// <param name="context"></param>
public NestedScope(ModelBindingContext context)
{
_context = context;
}
/// <summary>
/// Exits the <see cref="NestedScope"/> created by calling <see cref="ModelBindingContext.EnterNestedScope"/>.
/// </summary>
public void Dispose()
{
_context.ExitNestedScope();
}
}
} }
} }

View File

@ -12,18 +12,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// </summary> /// </summary>
public struct ModelBindingResult : IEquatable<ModelBindingResult> public struct ModelBindingResult : IEquatable<ModelBindingResult>
{ {
/// <summary>
/// A <see cref="ModelBinding"/> representing the lack of a result. The model binding
/// system will continue to execute other model binders.
/// </summary>
public static readonly ModelBindingResult NoResult = new ModelBindingResult();
/// <summary>
/// Returns a completed <see cref="Task{ModelBindingResult}"/> representing the lack of a result. The model
/// binding system will continue to execute other model binders.
/// </summary>
public static readonly Task<ModelBindingResult> NoResultAsync = Task.FromResult(NoResult);
/// <summary> /// <summary>
/// Creates a <see cref="ModelBindingResult"/> representing a failed model binding operation. /// Creates a <see cref="ModelBindingResult"/> representing a failed model binding operation.
/// </summary> /// </summary>
@ -38,22 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return new ModelBindingResult(key, model: null, isModelSet: false); return new ModelBindingResult(key, model: null, isModelSet: false);
} }
/// <summary>
/// Creates a completed <see cref="Task{ModelBindingResult}"/> representing a failed model binding operation.
/// </summary>
/// <param name="key">The key of the current model binding operation.</param>
/// <returns>A completed <see cref="Task{ModelBindingResult}"/> representing a failed model binding operation.</returns>
public static Task<ModelBindingResult> FailedAsync(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return Task.FromResult(Failed(key));
}
/// <summary> /// <summary>
/// Creates a <see cref="ModelBindingResult"/> representing a successful model binding operation. /// Creates a <see cref="ModelBindingResult"/> representing a successful model binding operation.
/// </summary> /// </summary>
@ -72,25 +45,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return new ModelBindingResult(key, model, isModelSet: true); return new ModelBindingResult(key, model, isModelSet: true);
} }
/// <summary>
/// Creates a completed <see cref="Task{ModelBindingResult}"/> representing a successful model binding
/// operation.
/// </summary>
/// <param name="key">The key of the current model binding operation.</param>
/// <param name="model">The model value. May be <c>null.</c></param>
/// <returns>A completed <see cref="Task{ModelBindingResult}"/> representing a successful model bind.</returns>
public static Task<ModelBindingResult> 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) private ModelBindingResult(string key, object model, bool isModelSet)
{ {
Key = key; Key = key;

View File

@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
return actionArguments; return actionArguments;
} }
public async Task<ModelBindingResult> BindModelAsync( public async Task<ModelBindingResult?> BindModelAsync(
ParameterDescriptor parameter, ParameterDescriptor parameter,
OperationBindingContext operationContext) OperationBindingContext operationContext)
{ {
@ -112,21 +112,22 @@ namespace Microsoft.AspNetCore.Mvc.Internal
} }
var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType); var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
var modelBindingContext = ModelBindingContext.CreateBindingContext( var modelBindingContext = DefaultModelBindingContext.CreateBindingContext(
operationContext, operationContext,
metadata, metadata,
parameter.BindingInfo, parameter.BindingInfo,
parameter.Name); parameter.Name);
var modelBindingResult = await operationContext.ModelBinder.BindModelAsync(modelBindingContext); await operationContext.ModelBinder.BindModelAsync(modelBindingContext);
if (modelBindingResult.IsModelSet) var modelBindingResult = modelBindingContext.Result;
if (modelBindingResult != null && modelBindingResult.Value.IsModelSet)
{ {
_validator.Validate( _validator.Validate(
operationContext.ActionContext, operationContext.ActionContext,
operationContext.ValidatorProvider, operationContext.ValidatorProvider,
modelBindingContext.ValidationState, modelBindingContext.ValidationState,
modelBindingResult.Key, modelBindingResult.Value.Key,
modelBindingResult.Model); modelBindingResult.Value.Model);
} }
return modelBindingResult; return modelBindingResult;
@ -225,9 +226,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{ {
var parameter = parameterMetadata[i]; var parameter = parameterMetadata[i];
var modelBindingResult = await BindModelAsync(parameter, operationContext); 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;
} }
} }

View File

@ -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
{
/// <summary>
/// A context that contains operating information for model binding and validation.
/// </summary>
public class DefaultModelBindingContext : ModelBindingContext
{
private State _state;
private readonly Stack<State> _stack = new Stack<State>();
/// <summary>
/// Initializes a new instance of the <see cref="DefaultModelBindingContext"/> class.
/// </summary>
public DefaultModelBindingContext()
{
}
/// <summary>
/// Creates a new <see cref="DefaultModelBindingContext"/> for top-level model binding operation.
/// </summary>
/// <param name="operationBindingContext">
/// The <see cref="OperationBindingContext"/> associated with the binding operation.
/// </param>
/// <param name="metadata"><see cref="ModelMetadata"/> associated with the model.</param>
/// <param name="bindingInfo"><see cref="BindingInfo"/> associated with the model.</param>
/// <param name="modelName">The name of the property or parameter being bound.</param>
/// <returns>A new instance of <see cref="DefaultModelBindingContext"/>.</returns>
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(),
};
}
/// <inheritdoc />
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;
}
/// <inheritdoc />
public override NestedScope EnterNestedScope()
{
_stack.Push(_state);
Result = null;
return new NestedScope(this);
}
/// <inheritdoc />
protected override void ExitNestedScope()
{
_state = _stack.Pop();
}
/// <inheritdoc />
public override OperationBindingContext OperationBindingContext
{
get { return _state.OperationBindingContext; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_state.OperationBindingContext = value;
}
}
/// <inheritdoc />
public override string FieldName
{
get { return _state.FieldName; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_state.FieldName = value;
}
}
/// <inheritdoc />
public override object Model
{
get { return _state.Model; }
set { _state.Model = value; }
}
/// <inheritdoc />
public override ModelMetadata ModelMetadata
{
get { return _state.ModelMetadata; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_state.ModelMetadata = value;
}
}
/// <inheritdoc />
public override string ModelName
{
get { return _state.ModelName; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_state.ModelName = value;
}
}
/// <inheritdoc />
public override ModelStateDictionary ModelState
{
get { return _state.ModelState; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_state.ModelState = value;
}
}
/// <inheritdoc />
public override Type ModelType => ModelMetadata?.ModelType;
/// <inheritdoc />
public override string BinderModelName
{
get { return _state.BinderModelName; }
set { _state.BinderModelName = value; }
}
/// <inheritdoc />
public override BindingSource BindingSource
{
get { return _state.BindingSource; }
set { _state.BindingSource = value; }
}
/// <inheritdoc />
public override Type BinderType
{
get { return _state.BinderType; }
set { _state.BinderType = value; }
}
/// <inheritdoc />
public override bool FallbackToEmptyPrefix
{
get { return _state.FallbackToEmptyPrefix; }
set { _state.FallbackToEmptyPrefix = value; }
}
/// <inheritdoc />
public override bool IsTopLevelObject
{
get { return _state.IsTopLevelObject; }
set { _state.IsTopLevelObject = value; }
}
/// <inheritdoc />
public override IValueProvider ValueProvider
{
get { return _state.ValueProvider; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_state.ValueProvider = value;
}
}
/// <inheritdoc />
public override Func<ModelBindingContext, string, bool> PropertyFilter
{
get { return _state.PropertyFilter; }
set { _state.PropertyFilter = value; }
}
/// <inheritdoc />
public override ValidationStateDictionary ValidationState
{
get { return _state.ValidationState; }
set { _state.ValidationState = value; }
}
/// <inheritdoc />
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<ModelBindingContext, string, bool> 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;
};
}
}

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class ArrayModelBinder<TElement> : CollectionModelBinder<TElement> public class ArrayModelBinder<TElement> : CollectionModelBinder<TElement>
{ {
/// <inheritdoc /> /// <inheritdoc />
public override Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public override Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (bindingContext.ModelMetadata.IsReadOnly) if (bindingContext.ModelMetadata.IsReadOnly)
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
return base.BindModelAsync(bindingContext); return base.BindModelAsync(bindingContext);

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
@ -21,23 +22,28 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private readonly ConcurrentDictionary<Type, ObjectFactory> _typeActivatorCache = private readonly ConcurrentDictionary<Type, ObjectFactory> _typeActivatorCache =
new ConcurrentDictionary<Type, ObjectFactory>(); new ConcurrentDictionary<Type, ObjectFactory>();
public Task<ModelBindingResult> 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 // 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 // using Task.FromResult. If you need to make changes of this nature, profile
// allocations afterwards and look for Task<ModelBindingResult>. // allocations afterwards and look for Task<ModelBindingResult>.
if (bindingContext.BinderType == null) 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. // if there is no specific model binder provided.
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
return BindModelCoreAsync(bindingContext); return BindModelCoreAsync(bindingContext);
} }
private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext) private async Task BindModelCoreAsync(ModelBindingContext bindingContext)
{ {
var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
var createFactory = _typeActivatorCache.GetOrAdd(bindingContext.BinderType, _createFactory); var createFactory = _typeActivatorCache.GetOrAdd(bindingContext.BinderType, _createFactory);
@ -52,15 +58,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
typeof(IModelBinder).FullName)); typeof(IModelBinder).FullName));
} }
var result = await modelBinder.BindModelAsync(bindingContext); await modelBinder.BindModelAsync(bindingContext);
var modelBindingResult = result != ModelBindingResult.NoResult ?
result :
ModelBindingResult.Failed(bindingContext.ModelName);
// A model binder was specified by metadata and this binder handles all such cases. // 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. // 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);
}
} }
} }
} }

View File

@ -33,8 +33,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> 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 // 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 // using Task.FromResult. If you need to make changes of this nature, profile
// allocations afterwards and look for Task<ModelBindingResult>. // allocations afterwards and look for Task<ModelBindingResult>.
@ -45,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
// Formatters are opt-in. This model either didn't specify [FromBody] or specified something // Formatters are opt-in. This model either didn't specify [FromBody] or specified something
// incompatible so let other binders run. // incompatible so let other binders run.
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
return BindModelCoreAsync(bindingContext); return BindModelCoreAsync(bindingContext);
@ -58,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// <returns> /// <returns>
/// A <see cref="Task{ModelBindingResult}"/> which when completed returns a <see cref="ModelBindingResult"/>. /// A <see cref="Task{ModelBindingResult}"/> which when completed returns a <see cref="ModelBindingResult"/>.
/// </returns> /// </returns>
private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext) private async Task BindModelCoreAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) 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 // 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 // tell the model binding system to skip other model binders and never to fall back i.e. indicate a
// fatal error. // fatal error.
return ModelBindingResult.Failed(modelBindingKey); bindingContext.Result = ModelBindingResult.Failed(modelBindingKey);
return;
} }
try 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 // 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. // 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) 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 // 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 // tell the model binding system to skip other model binders and never to fall back i.e. indicate a
// fatal error. // fatal error.
return ModelBindingResult.Failed(modelBindingKey); bindingContext.Result = ModelBindingResult.Failed(modelBindingKey);
return;
} }
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class ByteArrayModelBinder : IModelBinder public class ByteArrayModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
@ -26,14 +27,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Check if this binder applies. // Check if this binder applies.
if (bindingContext.ModelType != typeof(byte[])) if (bindingContext.ModelType != typeof(byte[]))
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
// Check for missing data case 1: There was no <input ... /> element containing this data. // Check for missing data case 1: There was no <input ... /> element containing this data.
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult == ValueProviderResult.None) if (valueProviderResult == ValueProviderResult.None)
{ {
return ModelBindingResult.FailedAsync(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return TaskCache.CompletedTask;
} }
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
@ -42,13 +44,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var value = valueProviderResult.FirstValue; var value = valueProviderResult.FirstValue;
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
return ModelBindingResult.FailedAsync(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return TaskCache.CompletedTask;
} }
try try
{ {
var model = Convert.FromBase64String(value); var model = Convert.FromBase64String(value);
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
return TaskCache.CompletedTask;
} }
catch (Exception exception) 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 // 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. // 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;
} }
} }
} }

View File

@ -1,9 +1,11 @@
// 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. // 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;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Mvc.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -13,8 +15,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class CancellationTokenModelBinder : IModelBinder public class CancellationTokenModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
if (bindingContext.ModelType == typeof(CancellationToken)) if (bindingContext.ModelType == typeof(CancellationToken))
{ {
// We need to force boxing now, so we can insert the same reference to the boxed 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. // DO NOT simplify this code by removing the cast.
var model = (object)bindingContext.OperationBindingContext.HttpContext.RequestAborted; var model = (object)bindingContext.OperationBindingContext.HttpContext.RequestAborted;
bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); 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;
} }
} }
} }

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class CollectionModelBinder<TElement> : ICollectionModelBinder public class CollectionModelBinder<TElement> : ICollectionModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public virtual async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public virtual async Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
@ -44,10 +44,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
model = CreateEmptyCollection(bindingContext.ModelType); 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); var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
@ -91,7 +92,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
valueProviderResult); valueProviderResult);
} }
return ModelBindingResult.Success(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
return;
} }
/// <inheritdoc /> /// <inheritdoc />
@ -147,16 +149,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
var elementMetadata = metadataProvider.GetMetadataForType(typeof(TElement)); 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) foreach (var value in values)
{ {
innerBindingContext.ValueProvider = new CompositeValueProvider bindingContext.ValueProvider = new CompositeValueProvider
{ {
// our temporary provider goes at the front of the list // our temporary provider goes at the front of the list
new ElementalValueProvider(bindingContext.ModelName, value, values.Culture), new ElementalValueProvider(bindingContext.ModelName, value, values.Culture),
@ -164,12 +160,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
}; };
object boundValue = null; object boundValue = null;
var result =
await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(innerBindingContext); using (bindingContext.EnterNestedScope(
if (result != null && result.IsModelSet) elementMetadata,
fieldName: bindingContext.FieldName,
modelName: bindingContext.ModelName,
model: null))
{ {
boundValue = result.Model; await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(bindingContext);
boundCollection.Add(ModelBindingHelper.CastOrDefault<TElement>(boundValue));
if (bindingContext.Result != null && bindingContext.Result.Value.IsModelSet)
{
boundValue = bindingContext.Result.Value.Model;
boundCollection.Add(ModelBindingHelper.CastOrDefault<TElement>(boundValue));
}
} }
} }
@ -214,23 +218,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
foreach (var indexName in indexNames) foreach (var indexName in indexNames)
{ {
var fullChildName = ModelNames.CreateIndexModelName(bindingContext.ModelName, indexName); var fullChildName = ModelNames.CreateIndexModelName(bindingContext.ModelName, indexName);
var childBindingContext = ModelBindingContext.CreateChildBindingContext(
bindingContext,
elementMetadata,
fieldName: indexName,
modelName: fullChildName,
model: null);
var didBind = false; var didBind = false;
object boundValue = null; 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 = if (result != null && result.Value.IsModelSet)
await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(childBindingContext);
if (result != null && result.IsModelSet)
{ {
didBind = true; didBind = true;
boundValue = result.Model; boundValue = result.Value.Model;
} }
// infinite size collection stops on first bind failure // infinite size collection stops on first bind failure

View File

@ -36,70 +36,78 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// <inheritdoc /> /// <inheritdoc />
public IList<IModelBinder> ModelBinders { get; } public IList<IModelBinder> ModelBinders { get; }
public virtual Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public virtual Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
throw new ArgumentNullException(nameof(bindingContext)); throw new ArgumentNullException(nameof(bindingContext));
} }
var newBindingContext = CreateNewBindingContext(bindingContext); return RunModelBinders(bindingContext);
if (newBindingContext == null)
{
// Unable to find a value provider for this binding source. Binding will fail.
return ModelBindingResult.NoResultAsync;
}
return RunModelBinders(newBindingContext);
} }
private async Task<ModelBindingResult> RunModelBinders(ModelBindingContext bindingContext) private async Task RunModelBinders(ModelBindingContext bindingContext)
{ {
RuntimeHelpers.EnsureSufficientExecutionStack(); RuntimeHelpers.EnsureSufficientExecutionStack();
// Perf: Avoid allocations ModelBindingResult? overallResult = null;
for (var i = 0; i < ModelBinders.Count; i++) try
{ {
var binder = ModelBinders[i]; using (bindingContext.EnterNestedScope())
var result = await binder.BindModelAsync(bindingContext);
if (result != ModelBindingResult.NoResult)
{ {
// This condition is necessary because the ModelState entry would never be validated if if (PrepareBindingContext(bindingContext))
// 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 (bindingContext.IsTopLevelObject && result.Model != null) // Perf: Avoid allocations
for (var i = 0; i < ModelBinders.Count; i++)
{ {
ValidationStateEntry entry; var binder = ModelBinders[i];
if (!bindingContext.ValidationState.TryGetValue(result.Model, out entry)) 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, if (bindingContext.IsTopLevelObject && result.Model != null)
Metadata = bindingContext.ModelMetadata, {
}; ValidationStateEntry entry;
bindingContext.ValidationState.Add(result.Model, 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;
} }
} }
finally
// Either we couldn't find a binder, or the binder couldn't bind. Distinction is not important. {
return ModelBindingResult.NoResult; 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 // 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 // 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) { } // public IActionResult UpdatePerson([FromForm] Person person) { }
// //
// In this example, [FromQuery] overrides the ambient data source (form). // 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) if (bindingSource != null && !bindingSource.IsGreedy)
{ {
var bindingSourceValueProvider = valueProvider as IBindingSourceValueProvider; var bindingSourceValueProvider = valueProvider as IBindingSourceValueProvider;
@ -130,43 +142,30 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (valueProvider == null) if (valueProvider == null)
{ {
// Unable to find a value provider for this binding source. // 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) if (bindingSource != null && bindingSource.IsGreedy)
{ {
newBindingContext.ModelName = oldBindingContext.ModelName; bindingContext.ModelName = modelName;
} }
else if ( else if (
!oldBindingContext.FallbackToEmptyPrefix || !fallbackToEmptyPrefix ||
newBindingContext.ValueProvider.ContainsPrefix(oldBindingContext.ModelName)) valueProvider.ContainsPrefix(bindingContext.ModelName))
{ {
newBindingContext.ModelName = oldBindingContext.ModelName; bindingContext.ModelName = modelName;
} }
else else
{ {
newBindingContext.ModelName = string.Empty; bindingContext.ModelName = string.Empty;
} }
return newBindingContext; bindingContext.ValueProvider = valueProvider;
bindingContext.FallbackToEmptyPrefix = false;
return true;
} }
} }
} }

View File

@ -22,26 +22,28 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class DictionaryModelBinder<TKey, TValue> : CollectionModelBinder<KeyValuePair<TKey, TValue>> public class DictionaryModelBinder<TKey, TValue> : CollectionModelBinder<KeyValuePair<TKey, TValue>>
{ {
/// <inheritdoc /> /// <inheritdoc />
public override async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public override async Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
throw new ArgumentNullException(nameof(bindingContext)); throw new ArgumentNullException(nameof(bindingContext));
} }
var result = await base.BindModelAsync(bindingContext); await base.BindModelAsync(bindingContext);
if (!result.IsModelSet) if (bindingContext.Result == null || !bindingContext.Result.Value.IsModelSet)
{ {
// No match for the prefix at all. // No match for the prefix at all.
return result; return;
} }
var result = bindingContext.Result.Value;
Debug.Assert(result.Model != null); Debug.Assert(result.Model != null);
var model = (IDictionary<TKey, TValue>)result.Model; var model = (IDictionary<TKey, TValue>)result.Model;
if (model.Count != 0) if (model.Count != 0)
{ {
// ICollection<KeyValuePair<TKey, TValue>> approach was successful. // ICollection<KeyValuePair<TKey, TValue>> approach was successful.
return result; return;
} }
var enumerableValueProvider = bindingContext.ValueProvider as IEnumerableValueProvider; 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 // No IEnumerableValueProvider available for the fallback approach. For example the user may have
// replaced the ValueProvider with something other than a CompositeValueProvider. // 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. // 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()) if (!keys.Any())
{ {
// No entries with the expected keys. // No entries with the expected keys.
return result; return;
} }
// Update the existing successful but empty ModelBindingResult. // Update the existing successful but empty ModelBindingResult.
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider; var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
var valueMetadata = metadataProvider.GetMetadataForType(typeof(TValue)); 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; var modelBinder = bindingContext.OperationBindingContext.ModelBinder;
@ -79,21 +75,26 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// that culture when rendering a form. // that culture when rendering a form.
var convertedKey = ModelBindingHelper.ConvertTo<TKey>(kvp.Key, culture: null); var convertedKey = ModelBindingHelper.ConvertTo<TKey>(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. // Always add an entry to the dictionary but validate only if binding was successful.
model[convertedKey] = ModelBindingHelper.CastOrDefault<TValue>(valueResult.Model); model[convertedKey] = ModelBindingHelper.CastOrDefault<TValue>(valueResult.Value.Model);
keyMappings.Add(kvp.Key, convertedKey); keyMappings.Add(kvp.Key, convertedKey);
}
} }
bindingContext.ValidationState.Add(model, new ValidationStateEntry() bindingContext.ValidationState.Add(model, new ValidationStateEntry()
{ {
Strategy = new ShortFormDictionaryValidationStrategy<TKey, TValue>(keyMappings, valueMetadata), Strategy = new ShortFormDictionaryValidationStrategy<TKey, TValue>(keyMappings, valueMetadata),
}); });
return result;
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
@ -18,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class FormCollectionModelBinder : IModelBinder public class FormCollectionModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
@ -31,13 +32,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (bindingContext.ModelType != typeof(IFormCollection)) if (bindingContext.ModelType != typeof(IFormCollection))
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
return BindModelCoreAsync(bindingContext); return BindModelCoreAsync(bindingContext);
} }
private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext) private async Task BindModelCoreAsync(ModelBindingContext bindingContext)
{ {
object model; object model;
var request = bindingContext.OperationBindingContext.HttpContext.Request; var request = bindingContext.OperationBindingContext.HttpContext.Request;
@ -52,7 +53,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); 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 private class EmptyFormCollection : IFormCollection

View File

@ -10,6 +10,7 @@ using System.Reflection;
#endif #endif
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
@ -21,7 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class FormFileModelBinder : IModelBinder public class FormFileModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
@ -35,13 +36,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (bindingContext.ModelType != typeof(IFormFile) && if (bindingContext.ModelType != typeof(IFormFile) &&
!typeof(IEnumerable<IFormFile>).IsAssignableFrom(bindingContext.ModelType)) !typeof(IEnumerable<IFormFile>).IsAssignableFrom(bindingContext.ModelType))
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
return BindModelCoreAsync(bindingContext); return BindModelCoreAsync(bindingContext);
} }
private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext) private async Task BindModelCoreAsync(ModelBindingContext bindingContext)
{ {
// If we're at the top level, then use the FieldName (paramter or property name). // 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 // 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. // This binder does not support the requested type.
Debug.Fail("We shouldn't be called without a matching type."); Debug.Fail("We shouldn't be called without a matching type.");
return ModelBindingResult.NoResult; return;
} }
if (value == null) if (value == null)
{ {
return ModelBindingResult.Failed(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return;
} }
else else
{ {
@ -85,7 +87,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
rawValue: null, rawValue: null,
attemptedValue: null); attemptedValue: null);
return ModelBindingResult.Success(bindingContext.ModelName, value); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, value);
return;
} }
} }

View File

@ -8,14 +8,20 @@ using System.Diagnostics;
using System.Reflection; using System.Reflection;
#endif #endif
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
public class GenericModelBinder : IModelBinder public class GenericModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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 // 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 // using Task.FromResult. If you need to make changes of this nature, profile
// allocations afterwards and look for Task<ModelBindingResult>. // allocations afterwards and look for Task<ModelBindingResult>.
@ -23,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binderType = ResolveBinderType(bindingContext); var binderType = ResolveBinderType(bindingContext);
if (binderType == null) if (binderType == null)
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
var binder = (IModelBinder)Activator.CreateInstance(binderType); var binder = (IModelBinder)Activator.CreateInstance(binderType);
@ -34,24 +40,22 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
!collectionBinder.CanCreateInstance(bindingContext.ModelType)) !collectionBinder.CanCreateInstance(bindingContext.ModelType))
{ {
// Able to resolve a binder type but need a new model instance and that binder cannot create it. // 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); return BindModelCoreAsync(bindingContext, binder);
} }
private async Task<ModelBindingResult> BindModelCoreAsync(ModelBindingContext bindingContext, IModelBinder binder) private async Task BindModelCoreAsync(ModelBindingContext bindingContext, IModelBinder binder)
{ {
Debug.Assert(binder != null); Debug.Assert(binder != null);
var result = await binder.BindModelAsync(bindingContext); await binder.BindModelAsync(bindingContext);
var modelBindingResult = result != ModelBindingResult.NoResult ? if (bindingContext.Result == null)
result : {
ModelBindingResult.Failed(bindingContext.ModelName); // Always tell the model binding system to skip other model binders.
bindingContext.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;
} }
private static Type ResolveBinderType(ModelBindingContext context) private static Type ResolveBinderType(ModelBindingContext context)

View File

@ -1,12 +1,15 @@
// 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. // 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.Collections.Generic;
using System.Diagnostics;
#if DOTNET5_4 #if DOTNET5_4
using System.Reflection; using System.Reflection;
#endif #endif
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -17,8 +20,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class HeaderModelBinder : IModelBinder public class HeaderModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> 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 // 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 // using Task.FromResult. If you need to make changes of this nature, profile
// allocations afterwards and look for Task<ModelBindingResult>. // allocations afterwards and look for Task<ModelBindingResult>.
@ -29,7 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
// Headers are opt-in. This model either didn't specify [FromHeader] or specified something // Headers are opt-in. This model either didn't specify [FromHeader] or specified something
// incompatible so let other binders run. // incompatible so let other binders run.
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
var request = bindingContext.OperationBindingContext.HttpContext.Request; var request = bindingContext.OperationBindingContext.HttpContext.Request;
@ -59,7 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (model == null) if (model == null)
{ {
return ModelBindingResult.FailedAsync(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return TaskCache.CompletedTask;
} }
else else
{ {
@ -68,7 +77,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
request.Headers.GetCommaSeparatedValues(headerName), request.Headers.GetCommaSeparatedValues(headerName),
request.Headers[headerName]); request.Headers[headerName]);
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
return TaskCache.CompletedTask;
} }
} }
} }

View File

@ -1,15 +1,22 @@
// 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. // 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.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
public sealed class KeyValuePairModelBinder<TKey, TValue> : IModelBinder public sealed class KeyValuePairModelBinder<TKey, TValue> : IModelBinder
{ {
public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public async Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
ModelBindingHelper.ValidateBindingContext(bindingContext, ModelBindingHelper.ValidateBindingContext(bindingContext,
typeof(KeyValuePair<TKey, TValue>), typeof(KeyValuePair<TKey, TValue>),
allowNullModel: true); allowNullModel: true);
@ -23,9 +30,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
ModelBindingHelper.CastOrDefault<TKey>(keyResult.Model), ModelBindingHelper.CastOrDefault<TKey>(keyResult.Model),
ModelBindingHelper.CastOrDefault<TValue>(valueResult.Model)); ModelBindingHelper.CastOrDefault<TValue>(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( bindingContext.ModelState.TryAddModelError(
keyResult.Key, keyResult.Key,
@ -33,9 +42,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Were able to get some data for this model. // Were able to get some data for this model.
// Always tell the model binding system to skip other model binders. // 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( bindingContext.ModelState.TryAddModelError(
valueResult.Key, valueResult.Key,
@ -43,46 +54,46 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Were able to get some data for this model. // Were able to get some data for this model.
// Always tell the model binding system to skip other model binders. // 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<TKey, TValue>();
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<TKey, TValue>();
bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
} }
} }
internal async Task<ModelBindingResult> TryBindStrongModel<TModel>( internal async Task<ModelBindingResult> TryBindStrongModel<TModel>(
ModelBindingContext parentBindingContext, ModelBindingContext bindingContext,
string propertyName) string propertyName)
{ {
var propertyModelMetadata = var propertyModelMetadata =
parentBindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(typeof(TModel)); bindingContext.OperationBindingContext.MetadataProvider.GetMetadataForType(typeof(TModel));
var propertyModelName = var propertyModelName =
ModelNames.CreatePropertyModelName(parentBindingContext.ModelName, propertyName); ModelNames.CreatePropertyModelName(bindingContext.ModelName, propertyName);
var propertyBindingContext = ModelBindingContext.CreateChildBindingContext(
parentBindingContext,
propertyModelMetadata,
propertyName,
propertyModelName,
model: null);
var result = await propertyBindingContext.OperationBindingContext.ModelBinder.BindModelAsync( using (bindingContext.EnterNestedScope(
propertyBindingContext); modelMetadata: propertyModelMetadata,
if (result.IsModelSet) fieldName: propertyName,
modelName: propertyModelName,
model: null))
{ {
return result;
} await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(
else bindingContext);
{ var result = bindingContext.Result;
return ModelBindingResult.Failed(propertyModelName); if (result != null && result.Value.IsModelSet)
{
return result.Value;
}
else
{
return ModelBindingResult.Failed(propertyModelName);
}
} }
} }
} }

View File

@ -2,16 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq; 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 namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{ {

View File

@ -528,7 +528,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
ValueProvider = valueProvider, ValueProvider = valueProvider,
}; };
var modelBindingContext = ModelBindingContext.CreateBindingContext( var modelBindingContext = DefaultModelBindingContext.CreateBindingContext(
operationBindingContext, operationBindingContext,
modelMetadata, modelMetadata,
bindingInfo: null, bindingInfo: null,
@ -536,15 +536,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
modelBindingContext.Model = model; modelBindingContext.Model = model;
modelBindingContext.PropertyFilter = predicate; modelBindingContext.PropertyFilter = predicate;
var modelBindingResult = await modelBinder.BindModelAsync(modelBindingContext); await modelBinder.BindModelAsync(modelBindingContext);
if (modelBindingResult.IsModelSet) var modelBindingResult = modelBindingContext.Result;
if (modelBindingResult != null && modelBindingResult.Value.IsModelSet)
{ {
objectModelValidator.Validate( objectModelValidator.Validate(
operationBindingContext.ActionContext, operationBindingContext.ActionContext,
operationBindingContext.ValidatorProvider, operationBindingContext.ValidatorProvider,
modelBindingContext.ValidationState, modelBindingContext.ValidationState,
modelBindingResult.Key, modelBindingResult.Value.Key,
modelBindingResult.Model); modelBindingResult.Value.Model);
return modelState.IsValid; return modelState.IsValid;
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
@ -18,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
typeof(MutableObjectModelBinder).GetTypeInfo().GetDeclaredMethod(nameof(CallPropertyAddRange)); typeof(MutableObjectModelBinder).GetTypeInfo().GetDeclaredMethod(nameof(CallPropertyAddRange));
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null) if (bindingContext == null)
{ {
@ -28,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
ModelBindingHelper.ValidateBindingContext(bindingContext); ModelBindingHelper.ValidateBindingContext(bindingContext);
if (!CanBindType(bindingContext.ModelMetadata)) if (!CanBindType(bindingContext.ModelMetadata))
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
var mutableObjectBinderContext = new MutableObjectBinderContext() var mutableObjectBinderContext = new MutableObjectBinderContext()
@ -39,13 +40,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (!(CanCreateModel(mutableObjectBinderContext))) if (!(CanCreateModel(mutableObjectBinderContext)))
{ {
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
return BindModelCoreAsync(bindingContext, mutableObjectBinderContext); return BindModelCoreAsync(bindingContext, mutableObjectBinderContext);
} }
private async Task<ModelBindingResult> BindModelCoreAsync( private async Task BindModelCoreAsync(
ModelBindingContext bindingContext, ModelBindingContext bindingContext,
MutableObjectBinderContext mutableObjectBinderContext) MutableObjectBinderContext mutableObjectBinderContext)
{ {
@ -58,7 +59,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
bindingContext.Model = model; bindingContext.Model = model;
ProcessResults(bindingContext, results); ProcessResults(bindingContext, results);
return ModelBindingResult.Success(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
} }
/// <summary> /// <summary>
@ -170,17 +171,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
context.ModelBindingContext.ModelName, context.ModelBindingContext.ModelName,
fieldName); fieldName);
var propertyModelBindingContext = ModelBindingContext.CreateChildBindingContext( using (context.ModelBindingContext.EnterNestedScope(
context.ModelBindingContext, modelMetadata: propertyMetadata,
propertyMetadata,
fieldName: fieldName, fieldName: fieldName,
modelName: modelName, modelName: modelName,
model: null); model: null))
// If any property can return a true value.
if (CanBindValue(propertyModelBindingContext))
{ {
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 fieldName = propertyMetadata.BinderModelName ?? propertyMetadata.PropertyName;
var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName); var modelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, fieldName);
var propertyContext = ModelBindingContext.CreateChildBindingContext( using (bindingContext.EnterNestedScope(
bindingContext, modelMetadata: propertyMetadata,
propertyMetadata,
fieldName: fieldName, fieldName: fieldName,
modelName: modelName, modelName: modelName,
model: model); model: model))
var result = await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(propertyContext);
if (result == ModelBindingResult.NoResult)
{ {
// Could not bind. Let ProcessResult() know explicitly. await bindingContext.OperationBindingContext.ModelBinder.BindModelAsync(bindingContext);
result = ModelBindingResult.Failed(propertyContext.ModelName); 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; return results;
@ -444,7 +446,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// exceptions as necessary. // exceptions as necessary.
foreach (var entry in results) foreach (var entry in results)
{ {
if (entry.Value != ModelBindingResult.NoResult) if (entry.Value != null)
{ {
var result = entry.Value; var result = entry.Value;
var propertyMetadata = entry.Key; var propertyMetadata = entry.Key;

View File

@ -1,7 +1,10 @@
// 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. // 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 System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -14,8 +17,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public class ServicesModelBinder : IModelBinder public class ServicesModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> 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 // 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 // using Task.FromResult. If you need to make changes of this nature, profile
// allocations afterwards and look for Task<ModelBindingResult>. // allocations afterwards and look for Task<ModelBindingResult>.
@ -26,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
// Services are opt-in. This model either didn't specify [FromService] or specified something // Services are opt-in. This model either didn't specify [FromService] or specified something
// incompatible so let other binders run. // incompatible so let other binders run.
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
@ -34,7 +42,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true });
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
return TaskCache.CompletedTask;
} }
} }
} }

View File

@ -3,13 +3,19 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
namespace Microsoft.AspNetCore.Mvc.ModelBinding namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
public class SimpleTypeModelBinder : IModelBinder public class SimpleTypeModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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 // 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 // using Task.FromResult. If you need to make changes of this nature, profile
// allocations afterwards and look for Task<ModelBindingResult>. // allocations afterwards and look for Task<ModelBindingResult>.
@ -17,14 +23,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
if (bindingContext.ModelMetadata.IsComplexType) if (bindingContext.ModelMetadata.IsComplexType)
{ {
// this type cannot be converted // this type cannot be converted
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult == ValueProviderResult.None) if (valueProviderResult == ValueProviderResult.None)
{ {
// no entry // no entry
return ModelBindingResult.NoResultAsync; return TaskCache.CompletedTask;
} }
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
@ -53,11 +59,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
bindingContext.ModelMetadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor( bindingContext.ModelMetadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(
valueProviderResult.ToString())); valueProviderResult.ToString()));
return ModelBindingResult.FailedAsync(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return TaskCache.CompletedTask;
} }
else else
{ {
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
return TaskCache.CompletedTask;
} }
} }
catch (Exception exception) catch (Exception exception)
@ -69,7 +77,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Were able to find a converter for the type but conversion failed. // Were able to find a converter for the type but conversion failed.
// Tell the model binding system to skip other model binders. // Tell the model binding system to skip other model binders.
return ModelBindingResult.FailedAsync(bindingContext.ModelName); bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return TaskCache.CompletedTask;
} }
} }
} }

View File

@ -3,6 +3,7 @@
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
@ -14,16 +15,16 @@ namespace Microsoft.AspNetCore.Mvc.WebApiCompatShim
public class HttpRequestMessageModelBinder : IModelBinder public class HttpRequestMessageModelBinder : IModelBinder
{ {
/// <inheritdoc /> /// <inheritdoc />
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext.ModelType == typeof(HttpRequestMessage)) if (bindingContext.ModelType == typeof(HttpRequestMessage))
{ {
var model = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage(); var model = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage();
bindingContext.ValidationState.Add(model, new ValidationStateEntry() { SuppressValidation = true }); 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;
} }
} }
} }

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Arrange // Arrange
var bind = new BindAttribute(new string[] { "UserName", "FirstName", "LastName, MiddleName, ,foo,bar " }); var bind = new BindAttribute(new string[] { "UserName", "FirstName", "LastName, MiddleName, ,foo,bar " });
var context = new ModelBindingContext(); var context = new DefaultModelBindingContext();
// Act // Act
var predicate = bind.PropertyFilter; var predicate = bind.PropertyFilter;
@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Arrange // Arrange
var bind = new BindAttribute(typeof(TestProvider)); var bind = new BindAttribute(typeof(TestProvider));
var context = new ModelBindingContext(); var context = new DefaultModelBindingContext();
context.OperationBindingContext = new OperationBindingContext() context.OperationBindingContext = new OperationBindingContext()
{ {
ActionContext = new ActionContext() ActionContext = new ActionContext()
@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Arrange // Arrange
var bind = new BindAttribute(typeof(TestProvider)); var bind = new BindAttribute(typeof(TestProvider));
var context = new ModelBindingContext(); var context = new DefaultModelBindingContext();
context.OperationBindingContext = new OperationBindingContext() context.OperationBindingContext = new OperationBindingContext()
{ {
ActionContext = new ActionContext() ActionContext = new ActionContext()

View File

@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Test;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Mvc.TestCommon; using Microsoft.AspNetCore.Mvc.TestCommon;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
@ -1096,29 +1097,25 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
// Arrange // Arrange
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Empty(context.ModelName);
{ Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
Assert.Empty(context.ModelName);
Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
// Include and exclude should be null, resulting in property // Include and exclude should be null, resulting in property
// being included. // being included.
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); Assert.True(context.PropertyFilter(context, "Property2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider); var controller = GetController(binder, valueProvider);
var model = new MyModel(); var model = new MyModel();
// Act // Act
var result = await controller.TryUpdateModelAsync(model); var result = await controller.TryUpdateModelAsync(model);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1129,28 +1126,24 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
{
Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
// Include and exclude should be null, resulting in property // Include and exclude should be null, resulting in property
// being included. // being included.
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); Assert.True(context.PropertyFilter(context, "Property2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider); var controller = GetController(binder, valueProvider);
var model = new MyModel(); var model = new MyModel();
// Act // Act
var result = await controller.TryUpdateModelAsync(model, modelName); var result = await controller.TryUpdateModelAsync(model, modelName);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1160,9 +1153,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var modelName = "mymodel"; var modelName = "mymodel";
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Callback((ModelBindingContext context) =>
{ {
Assert.Same(valueProvider, context.ValueProvider); Assert.Same(valueProvider, context.ValueProvider);
@ -1170,18 +1161,16 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
// being included. // being included.
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); 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(); var model = new MyModel();
// Act // Act
var result = await controller.TryUpdateModelAsync(model, modelName, valueProvider); var result = await controller.TryUpdateModelAsync(model, modelName, valueProvider);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1194,30 +1183,26 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) || string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) ||
string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase); string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase);
var binder = new Mock<IModelBinder>();
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) var binder = new StubModelBinder(context =>
.Callback((ModelBindingContext context) => {
{ Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
Assert.True(context.PropertyFilter(context, "include1")); Assert.True(context.PropertyFilter(context, "include1"));
Assert.True(context.PropertyFilter(context, "include2")); Assert.True(context.PropertyFilter(context, "include2"));
Assert.False(context.PropertyFilter(context, "exclude1")); Assert.False(context.PropertyFilter(context, "exclude1"));
Assert.False(context.PropertyFilter(context, "exclude2")); Assert.False(context.PropertyFilter(context, "exclude2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider); var controller = GetController(binder, valueProvider);
var model = new MyModel(); var model = new MyModel();
// Act // Act
await controller.TryUpdateModelAsync(model, modelName, includePredicate); await controller.TryUpdateModelAsync(model, modelName, includePredicate);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1230,23 +1215,18 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
(context, propertyName) => string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) || (context, propertyName) => string.Equals(propertyName, "include1", StringComparison.OrdinalIgnoreCase) ||
string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase); string.Equals(propertyName, "include2", StringComparison.OrdinalIgnoreCase);
var binder = new Mock<IModelBinder>();
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) var binder = new StubModelBinder(context =>
.Callback((ModelBindingContext context) => {
{ Assert.Same(valueProvider, context.ValueProvider);
Assert.Same(valueProvider, context.ValueProvider);
Assert.True(context.PropertyFilter(context, "include1")); Assert.True(context.PropertyFilter(context, "include1"));
Assert.True(context.PropertyFilter(context, "include2")); Assert.True(context.PropertyFilter(context, "include2"));
Assert.False(context.PropertyFilter(context, "exclude1")); Assert.False(context.PropertyFilter(context, "exclude1"));
Assert.False(context.PropertyFilter(context, "exclude2")); Assert.False(context.PropertyFilter(context, "exclude2"));
}) });
.Returns(ModelBindingResult.NoResultAsync) var controller = GetController(binder, valueProvider: null);
.Verifiable();
var controller = GetController(binder.Object, valueProvider: null);
var model = new MyModel(); var model = new MyModel();
@ -1254,7 +1234,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
await controller.TryUpdateModelAsync(model, modelName, valueProvider, includePredicate); await controller.TryUpdateModelAsync(model, modelName, valueProvider, includePredicate);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Theory] [Theory]
@ -1268,32 +1248,28 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
.Setup(v => v.ContainsPrefix(prefix)) .Setup(v => v.ContainsPrefix(prefix))
.Returns(true); .Returns(true);
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Same(
{
Assert.Same(
valueProvider.Object, valueProvider.Object,
Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]); Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); Assert.True(context.PropertyFilter(context, "Property2"));
Assert.False(context.PropertyFilter(context, "exclude1")); Assert.False(context.PropertyFilter(context, "exclude1"));
Assert.False(context.PropertyFilter(context, "exclude2")); Assert.False(context.PropertyFilter(context, "exclude2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider.Object); var controller = GetController(binder, valueProvider.Object);
var model = new MyModel(); var model = new MyModel();
// Act // Act
await controller.TryUpdateModelAsync(model, prefix, m => m.Property1, m => m.Property2); await controller.TryUpdateModelAsync(model, prefix, m => m.Property1, m => m.Property2);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Theory] [Theory]
@ -1308,29 +1284,25 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
.Setup(v => v.ContainsPrefix(prefix)) .Setup(v => v.ContainsPrefix(prefix))
.Returns(true); .Returns(true);
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Same(valueProvider.Object, context.ValueProvider);
{
Assert.Same(valueProvider.Object, context.ValueProvider);
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); Assert.True(context.PropertyFilter(context, "Property2"));
Assert.False(context.PropertyFilter(context, "exclude1")); Assert.False(context.PropertyFilter(context, "exclude1"));
Assert.False(context.PropertyFilter(context, "exclude2")); Assert.False(context.PropertyFilter(context, "exclude2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider: null); var controller = GetController(binder, valueProvider: null);
var model = new MyModel(); var model = new MyModel();
// Act // Act
await controller.TryUpdateModelAsync(model, prefix, valueProvider.Object, m => m.Property1, m => m.Property2); await controller.TryUpdateModelAsync(model, prefix, valueProvider.Object, m => m.Property1, m => m.Property2);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1345,22 +1317,18 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Same(valueProvider, context.ValueProvider);
{
Assert.Same(valueProvider, context.ValueProvider);
Assert.True(context.PropertyFilter(context, "include1")); Assert.True(context.PropertyFilter(context, "include1"));
Assert.True(context.PropertyFilter(context, "include2")); Assert.True(context.PropertyFilter(context, "include2"));
Assert.False(context.PropertyFilter(context, "exclude1")); Assert.False(context.PropertyFilter(context, "exclude1"));
Assert.False(context.PropertyFilter(context, "exclude2")); Assert.False(context.PropertyFilter(context, "exclude2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider: null); var controller = GetController(binder, valueProvider: null);
var model = new MyModel(); var model = new MyModel();
@ -1368,7 +1336,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
await controller.TryUpdateModelAsync(model, model.GetType(), modelName, valueProvider, includePredicate); await controller.TryUpdateModelAsync(model, model.GetType(), modelName, valueProvider, includePredicate);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1379,28 +1347,24 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
{
Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
// Include and exclude should be null, resulting in property // Include and exclude should be null, resulting in property
// being included. // being included.
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); Assert.True(context.PropertyFilter(context, "Property2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider); var controller = GetController(binder, valueProvider);
var model = new MyModel(); var model = new MyModel();
// Act // Act
var result = await controller.TryUpdateModelAsync(model, model.GetType(), modelName); var result = await controller.TryUpdateModelAsync(model, model.GetType(), modelName);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1411,28 +1375,24 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
var valueProvider = Mock.Of<IValueProvider>(); var valueProvider = Mock.Of<IValueProvider>();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(context =>
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Callback((ModelBindingContext context) => Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
{
Assert.Same(valueProvider, Assert.IsType<CompositeValueProvider>(context.ValueProvider)[0]);
// Include and exclude should be null, resulting in property // Include and exclude should be null, resulting in property
// being included. // being included.
Assert.True(context.PropertyFilter(context, "Property1")); Assert.True(context.PropertyFilter(context, "Property1"));
Assert.True(context.PropertyFilter(context, "Property2")); Assert.True(context.PropertyFilter(context, "Property2"));
}) });
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var controller = GetController(binder.Object, valueProvider); var controller = GetController(binder, valueProvider);
MyModel model = new MyDerivedModel(); MyModel model = new MyDerivedModel();
// Act // Act
var result = await controller.TryUpdateModelAsync(model, model.GetType(), modelName); var result = await controller.TryUpdateModelAsync(model, model.GetType(), modelName);
// Assert // Assert
binder.Verify(); Assert.NotEqual(0, binder.BindModelCount);
} }
[Fact] [Fact]
@ -1515,8 +1475,8 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
public void TryValidateModelWithValidModel_ReturnsTrue() public void TryValidateModelWithValidModel_ReturnsTrue()
{ {
// Arrange // Arrange
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder();
var controller = GetController(binder.Object, valueProvider: null); var controller = GetController(binder, valueProvider: null);
controller.ControllerContext.ValidatorProviders = new List<IModelValidatorProvider>() controller.ControllerContext.ValidatorProviders = new List<IModelValidatorProvider>()
{ {
Mock.Of<IModelValidatorProvider>(), Mock.Of<IModelValidatorProvider>(),
@ -1552,8 +1512,8 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
provider.Setup(v => v.GetValidators(It.IsAny<ModelValidatorProviderContext>())) provider.Setup(v => v.GetValidators(It.IsAny<ModelValidatorProviderContext>()))
.Callback<ModelValidatorProviderContext>(c => c.Results.Add(validator1)); .Callback<ModelValidatorProviderContext>(c => c.Results.Add(validator1));
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder();
var controller = GetController(binder.Object, valueProvider: null); var controller = GetController(binder, valueProvider: null);
controller.ControllerContext.ValidatorProviders = new List<IModelValidatorProvider>() controller.ControllerContext.ValidatorProviders = new List<IModelValidatorProvider>()
{ {
provider.Object, provider.Object,
@ -1589,8 +1549,8 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
provider.Setup(v => v.GetValidators(It.IsAny<ModelValidatorProviderContext>())) provider.Setup(v => v.GetValidators(It.IsAny<ModelValidatorProviderContext>()))
.Callback<ModelValidatorProviderContext>(c => c.Results.Add(validator1)); .Callback<ModelValidatorProviderContext>(c => c.Results.Add(validator1));
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder();
var controller = GetController(binder.Object, valueProvider: null); var controller = GetController(binder, valueProvider: null);
controller.ControllerContext.ValidatorProviders = new List<IModelValidatorProvider>() controller.ControllerContext.ValidatorProviders = new List<IModelValidatorProvider>()
{ {
provider.Object, provider.Object,

View File

@ -2090,8 +2090,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}; };
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) binder.Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync); .Returns(TaskCache.CompletedTask);
var context = new Mock<HttpContext>(); var context = new Mock<HttpContext>();
context.SetupGet(c => c.Items) context.SetupGet(c => c.Items)
.Returns(new Dictionary<object, object>()); .Returns(new Dictionary<object, object>());

View File

@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) .Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync); .Returns(TaskCache.CompletedTask);
var controllerContext = GetControllerContext(actionDescriptor); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder.Object);
@ -67,8 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) .Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Returns(ModelBindingResult.FailedAsync(string.Empty)); .Returns(TaskCache.CompletedTask);
var controllerContext = GetControllerContext(actionDescriptor); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder.Object);
@ -104,12 +104,13 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) .Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Callback((ModelBindingContext context) => .Callback((ModelBindingContext context) =>
{ {
context.ModelMetadata = metadataProvider.GetMetadataForType(typeof(string)); 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); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder.Object);
@ -181,8 +182,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) .Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync); .Returns(TaskCache.CompletedTask);
var controllerContext = GetControllerContext(actionDescriptor); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder.Object);
@ -267,8 +268,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) .Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync); .Returns(TaskCache.CompletedTask);
var controllerContext = GetControllerContext(actionDescriptor); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder.Object);
@ -368,13 +369,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
ParameterType = typeof(int) ParameterType = typeof(int)
}); });
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(ModelBindingResult.Success(string.Empty, model: null));
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.SuccessAsync(string.Empty, model: null));
var controllerContext = GetControllerContext(actionDescriptor); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder);
controllerContext.ValueProviders.Add(new SimpleValueProvider()); controllerContext.ValueProviders.Add(new SimpleValueProvider());
var argumentBinder = GetArgumentBinder(); var argumentBinder = GetArgumentBinder();
@ -403,13 +401,10 @@ namespace Microsoft.AspNetCore.Mvc.Internal
ParameterType = typeof(int?) ParameterType = typeof(int?)
}); });
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(ModelBindingResult.Success(key: string.Empty, model: null));
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.SuccessAsync(key: string.Empty, model: null));
var controllerContext = GetControllerContext(actionDescriptor); var controllerContext = GetControllerContext(actionDescriptor);
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder);
controllerContext.ValueProviders.Add(new SimpleValueProvider()); controllerContext.ValueProviders.Add(new SimpleValueProvider());
var argumentBinder = GetArgumentBinder(); var argumentBinder = GetArgumentBinder();
@ -541,23 +536,20 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var argumentBinder = GetArgumentBinder(); var argumentBinder = GetArgumentBinder();
var controller = new TestController(); var controller = new TestController();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(bindingContext =>
binder {
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) // BindingContext.ModelName will be string.Empty here. This is a 'fallback to empty prefix'
.Returns<ModelBindingContext>(bindingContext => // 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' bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, model);
// because the value providers have no data. }
object model; else
if (inputPropertyValues.TryGetValue(bindingContext.FieldName, out model)) {
{ bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); }
} });
else
{
return ModelBindingResult.FailedAsync(bindingContext.ModelName);
}
});
controllerContext.ModelBinders.Add(binder.Object); controllerContext.ModelBinders.Add(binder.Object);
controllerContext.ValueProviders.Add(new SimpleValueProvider()); controllerContext.ValueProviders.Add(new SimpleValueProvider());
@ -607,10 +599,11 @@ namespace Microsoft.AspNetCore.Mvc.Internal
}; };
var binder = new Mock<IModelBinder>(); var binder = new Mock<IModelBinder>();
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>())) binder.Setup(b => b.BindModelAsync(It.IsAny<DefaultModelBindingContext>()))
.Returns<ModelBindingContext>(mbc => .Returns<DefaultModelBindingContext>(mbc =>
{ {
return ModelBindingResult.SuccessAsync(string.Empty, model); mbc.Result = ModelBindingResult.Success(string.Empty, model);
return TaskCache.CompletedTask;
}); });
context.ModelBinders.Add(binder.Object); context.ModelBinders.Add(binder.Object);
@ -642,7 +635,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
It.IsAny<object>())); It.IsAny<object>()));
return mockValidator.Object; return mockValidator.Object;
} }
// No need for bind-related attributes on properties in this controller class. Properties are added directly // No need for bind-related attributes on properties in this controller class. Properties are added directly
// to the BoundProperties collection, bypassing usual requirements. // to the BoundProperties collection, bypassing usual requirements.
private class TestController private class TestController

View File

@ -0,0 +1,15 @@
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
public static class ModelBinderExtensions
{
public static async Task<ModelBindingResult> BindModelResultAsync(
this IModelBinder binder,
ModelBindingContext context)
{
await binder.BindModelAsync(context);
return context.Result ?? default(ModelBindingResult);
}
}
}

View File

@ -4,7 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Internal; using Microsoft.AspNetCore.Http.Internal;
using Moq; using Microsoft.AspNetCore.Mvc.Internal;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
@ -25,10 +25,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ArrayModelBinder<int>(); var binder = new ArrayModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var array = Assert.IsType<int[]>(result.Model); var array = Assert.IsType<int[]>(result.Model);
Assert.Equal(new[] { 42, 84 }, array); Assert.Equal(new[] { 42, 84 }, array);
@ -53,10 +53,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Empty(Assert.IsType<string[]>(result.Model)); Assert.Empty(Assert.IsType<string[]>(result.Model));
Assert.Equal("modelName", result.Key); Assert.Equal("modelName", result.Key);
@ -82,10 +82,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
public static TheoryData<int[]> ArrayModelData public static TheoryData<int[]> ArrayModelData
@ -117,10 +117,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ArrayModelBinder<int>(); var binder = new ArrayModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // 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. // 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<int>(); var binder = new ArrayModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Same(model, result.Model); Assert.Same(model, result.Model);
@ -159,23 +159,19 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
private static IModelBinder CreateIntBinder() private static IModelBinder CreateIntBinder()
{ {
var mockIntBinder = new Mock<IModelBinder>(); return new StubModelBinder(mbc =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) var value = mbc.ValueProvider.GetValue(mbc.ModelName);
.Returns((ModelBindingContext mbc) => if (value != ValueProviderResult.None)
{ {
var value = mbc.ValueProvider.GetValue(mbc.ModelName); var model = value.ConvertTo(mbc.ModelType);
if (value != ValueProviderResult.None) return ModelBindingResult.Success(mbc.ModelName, model);
{ }
var model = value.ConvertTo(mbc.ModelType); return null;
return ModelBindingResult.SuccessAsync(mbc.ModelName, model); });
}
return ModelBindingResult.NoResultAsync;
});
return mockIntBinder.Object;
} }
private static ModelBindingContext GetBindingContext( private static DefaultModelBindingContext GetBindingContext(
IValueProvider valueProvider, IValueProvider valueProvider,
bool isReadOnly = false) bool isReadOnly = false)
{ {
@ -187,7 +183,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var modelMetadata = metadataProvider.GetMetadataForProperty( var modelMetadata = metadataProvider.GetMetadataForProperty(
typeof(ModelWithIntArrayProperty), typeof(ModelWithIntArrayProperty),
nameof(ModelWithIntArrayProperty.ArrayProperty)); nameof(ModelWithIntArrayProperty.ArrayProperty));
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = modelMetadata, ModelMetadata = modelMetadata,
ModelName = "someName", ModelName = "someName",
@ -202,9 +198,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
return bindingContext; return bindingContext;
} }
private static ModelBindingContext CreateContext() private static DefaultModelBindingContext CreateContext()
{ {
var modelBindingContext = new ModelBindingContext() var modelBindingContext = new DefaultModelBindingContext()
{ {
OperationBindingContext = new OperationBindingContext() OperationBindingContext = new OperationBindingContext()
{ {

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
public class BinderTypeBasedModelBinderModelBinderTest public class BinderTypeBasedModelBinderModelBinderTest
{ {
[Fact] [Fact]
public async Task BindModel_ReturnsNoResult_IfNoBinderTypeIsSet() public async Task BindModel_ReturnsNothing_IfNoBinderTypeIsSet()
{ {
// Arrange // Arrange
var bindingContext = GetBindingContext(typeof(Person)); var bindingContext = GetBindingContext(typeof(Person));
@ -22,10 +22,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new BinderTypeBasedModelBinder(); var binder = new BinderTypeBasedModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, binderResult); Assert.Equal(default(ModelBindingResult), binderResult);
} }
[Fact] [Fact]
@ -37,10 +37,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new BinderTypeBasedModelBinder(); var binder = new BinderTypeBasedModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, binderResult); Assert.NotEqual(default(ModelBindingResult), binderResult);
Assert.False(binderResult.IsModelSet); Assert.False(binderResult.IsModelSet);
} }
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new BinderTypeBasedModelBinder(); var binder = new BinderTypeBasedModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
var p = (Person)binderResult.Model; var p = (Person)binderResult.Model;
@ -80,13 +80,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
// Act // Act
var ex = await Assert.ThrowsAsync<InvalidOperationException>( var ex = await Assert.ThrowsAsync<InvalidOperationException>(
() => binder.BindModelAsync(bindingContext)); () => binder.BindModelResultAsync(bindingContext));
// Assert // Assert
Assert.Equal(expected, ex.Message); 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(); var metadataProvider = new TestModelMetadataProvider();
metadataProvider.ForType(modelType).BindingDetails(bd => bd.BinderType = binderType); metadataProvider.ForType(modelType).BindingDetails(bd => bd.BinderType = binderType);
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
ValidatorProvider = Mock.Of<IModelValidatorProvider>(), ValidatorProvider = Mock.Of<IModelValidatorProvider>(),
}; };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "someName", ModelName = "someName",
@ -123,9 +123,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
private class NullModelBinder : IModelBinder private class NullModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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(); _model = new Person();
} }
public Task<ModelBindingResult> 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);
} }
} }
} }

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new BodyModelBinder(new TestHttpRequestStreamReaderFactory()); var binder = new BodyModelBinder(new TestHttpRequestStreamReaderFactory());
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
mockInputFormatter.Verify(v => v.CanRead(It.IsAny<InputFormatterContext>()), Times.Once); mockInputFormatter.Verify(v => v.CanRead(It.IsAny<InputFormatterContext>()), Times.Once);
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(binderResult); Assert.NotNull(binderResult);
@ -138,10 +138,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, binderResult); Assert.Equal(default(ModelBindingResult), binderResult);
} }
[Fact] [Fact]
@ -157,10 +157,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, binderResult); Assert.Equal(default(ModelBindingResult), binderResult);
} }
[Fact] [Fact]
@ -183,7 +183,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
@ -253,14 +253,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = bindingContext.OperationBindingContext.ModelBinder; var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.True(binderResult.IsModelSet); Assert.True(binderResult.IsModelSet);
Assert.Same(canReadFormatter1, binderResult.Model); Assert.Same(canReadFormatter1, binderResult.Model);
} }
private static ModelBindingContext GetBindingContext( private static DefaultModelBindingContext GetBindingContext(
Type modelType, Type modelType,
IEnumerable<IInputFormatter> inputFormatters = null, IEnumerable<IInputFormatter> inputFormatters = null,
HttpContext httpContext = null, HttpContext httpContext = null,
@ -292,7 +292,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
MetadataProvider = metadataProvider, MetadataProvider = metadataProvider,
}; };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FieldName = "someField", FieldName = "someField",
IsTopLevelObject = true, IsTopLevelObject = true,

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ByteArrayModelBinder(); var binder = new ByteArrayModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(binderResult); Assert.NotNull(binderResult);
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ByteArrayModelBinder(); var binder = new ByteArrayModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(binderResult); Assert.NotNull(binderResult);
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ByteArrayModelBinder(); var binder = new ByteArrayModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(binderResult); Assert.NotNull(binderResult);
@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ByteArrayModelBinder(); var binder = new ByteArrayModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(binderResult); Assert.NotNull(binderResult);
@ -114,16 +114,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new ByteArrayModelBinder(); var binder = new ByteArrayModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelResultAsync(bindingContext);
// Assert // 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 metadataProvider = new EmptyModelMetadataProvider();
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "foo", ModelName = "foo",

View File

@ -20,10 +20,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new CancellationTokenModelBinder(); var binder = new CancellationTokenModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(bindingContext.OperationBindingContext.HttpContext.RequestAborted, result.Model); Assert.Equal(bindingContext.OperationBindingContext.HttpContext.RequestAborted, result.Model);
} }
@ -39,16 +39,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new CancellationTokenModelBinder(); var binder = new CancellationTokenModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // 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(); var metadataProvider = new EmptyModelMetadataProvider();
ModelBindingContext bindingContext = new ModelBindingContext DefaultModelBindingContext bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "someName", ModelName = "someName",

View File

@ -83,10 +83,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new CollectionModelBinder<int>(); var binder = new CollectionModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var list = Assert.IsAssignableFrom<IList<int>>(result.Model); var list = Assert.IsAssignableFrom<IList<int>>(result.Model);
@ -115,10 +115,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new CollectionModelBinder<int>(); var binder = new CollectionModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Same(list, result.Model); Assert.Same(list, result.Model);
@ -142,10 +142,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new CollectionModelBinder<int>(); var binder = new CollectionModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var list = Assert.IsAssignableFrom<IList<int>>(result.Model); var list = Assert.IsAssignableFrom<IList<int>>(result.Model);
@ -169,10 +169,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new CollectionModelBinder<int>(); var binder = new CollectionModelBinder<int>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Same(list, result.Model); Assert.Same(list, result.Model);
@ -192,10 +192,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var modelState = bindingContext.ModelState; var modelState = bindingContext.ModelState;
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.NotNull(result.Model); Assert.NotNull(result.Model);
@ -236,10 +236,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Empty(Assert.IsType<List<string>>(result.Model)); Assert.Empty(Assert.IsType<List<string>>(result.Model));
Assert.Equal("modelName", result.Key); Assert.Equal("modelName", result.Key);
@ -269,10 +269,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Same(list, result.Model); Assert.Same(list, result.Model);
Assert.Empty(list); Assert.Empty(list);
@ -299,10 +299,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
// Model type -> can create instance. // Model type -> can create instance.
@ -345,13 +345,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var culture = new CultureInfo("fr-FR"); var culture = new CultureInfo("fr-FR");
var bindingContext = GetModelBindingContext(new SimpleValueProvider()); var bindingContext = GetModelBindingContext(new SimpleValueProvider());
Mock.Get(bindingContext.OperationBindingContext.ModelBinder) bindingContext.OperationBindingContext.ModelBinder = new StubModelBinder(mbc =>
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) {
.Returns((ModelBindingContext mbc) => Assert.Equal("someName", mbc.ModelName);
{ mbc.Result = ModelBindingResult.Success(mbc.ModelName, 42);
Assert.Equal("someName", mbc.ModelName); });
return ModelBindingResult.SuccessAsync(mbc.ModelName, 42);
});
var modelBinder = new CollectionModelBinder<int>(); var modelBinder = new CollectionModelBinder<int>();
// Act // Act
@ -363,14 +362,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray()); Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray());
} }
private static ModelBindingContext GetModelBindingContext( private static DefaultModelBindingContext GetModelBindingContext(
IValueProvider valueProvider, IValueProvider valueProvider,
bool isReadOnly = false) bool isReadOnly = false)
{ {
var metadataProvider = new TestModelMetadataProvider(); var metadataProvider = new TestModelMetadataProvider();
metadataProvider.ForType<IList<int>>().BindingDetails(bd => bd.IsReadOnly = isReadOnly); metadataProvider.ForType<IList<int>>().BindingDetails(bd => bd.IsReadOnly = isReadOnly);
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(typeof(IList<int>)), ModelMetadata = metadataProvider.GetMetadataForType(typeof(IList<int>)),
ModelName = "someName", ModelName = "someName",
@ -390,33 +389,29 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private static IModelBinder CreateIntBinder() private static IModelBinder CreateIntBinder()
{ {
Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); return new StubModelBinder(mbc =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) var value = mbc.ValueProvider.GetValue(mbc.ModelName);
.Returns((ModelBindingContext mbc) => if (value == ValueProviderResult.None)
{ {
var value = mbc.ValueProvider.GetValue(mbc.ModelName); return null;
if (value == ValueProviderResult.None) }
{
return ModelBindingResult.NoResultAsync;
}
var model = value.ConvertTo(mbc.ModelType); var model = value.ConvertTo(mbc.ModelType);
if (model == null) if (model == null)
{ {
return ModelBindingResult.FailedAsync(mbc.ModelName); return ModelBindingResult.Failed(mbc.ModelName);
} }
else else
{ {
return ModelBindingResult.SuccessAsync(mbc.ModelName, model); return ModelBindingResult.Success(mbc.ModelName, model);
} }
}); });
return mockIntBinder.Object;
} }
private static ModelBindingContext CreateContext() private static DefaultModelBindingContext CreateContext()
{ {
var modelBindingContext = new ModelBindingContext() var modelBindingContext = new DefaultModelBindingContext()
{ {
OperationBindingContext = new OperationBindingContext() OperationBindingContext = new OperationBindingContext()
{ {

View File

@ -7,7 +7,6 @@ using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Moq;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
@ -18,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
public async Task BindModel_SuccessfulBind_ReturnsModel() public async Task BindModel_SuccessfulBind_ReturnsModel()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)),
@ -33,25 +32,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var mockIntBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata);
.Returns( Assert.Equal("someName", context.ModelName);
delegate (ModelBindingContext context) Assert.Same(bindingContext.ValueProvider, context.ValueProvider);
{
Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata);
Assert.Equal("someName", context.ModelName);
Assert.Same(bindingContext.ValueProvider, context.ValueProvider);
return ModelBindingResult.SuccessAsync("someName", 42); context.Result = ModelBindingResult.Success("someName", 42);
}); });
var shimBinder = CreateCompositeBinder(mockIntBinder.Object); var shimBinder = CreateCompositeBinder(mockIntBinder);
// Act // Act
var result = await shimBinder.BindModelAsync(bindingContext); var result = await shimBinder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(42, result.Model); Assert.Equal(42, result.Model);
} }
@ -60,7 +55,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
public async Task BindModel_SuccessfulBind_SetsValidationStateAtTopLevel() public async Task BindModel_SuccessfulBind_SetsValidationStateAtTopLevel()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
IsTopLevelObject = true, IsTopLevelObject = true,
@ -76,25 +71,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var mockIntBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata);
.Returns( Assert.Equal("someName", context.ModelName);
delegate (ModelBindingContext context) Assert.Same(bindingContext.ValueProvider, context.ValueProvider);
{
Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata);
Assert.Equal("someName", context.ModelName);
Assert.Same(bindingContext.ValueProvider, context.ValueProvider);
return ModelBindingResult.SuccessAsync("someName", 42); context.Result = ModelBindingResult.Success("someName", 42);
}); });
var shimBinder = CreateCompositeBinder(mockIntBinder.Object); var shimBinder = CreateCompositeBinder(mockIntBinder);
// Act // Act
var result = await shimBinder.BindModelAsync(bindingContext); var result = await shimBinder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(42, result.Model); Assert.Equal(42, result.Model);
@ -108,7 +99,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
public async Task BindModel_SuccessfulBind_DoesNotSetValidationState_WhenNotTopLevel() public async Task BindModel_SuccessfulBind_DoesNotSetValidationState_WhenNotTopLevel()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)),
@ -123,25 +114,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var mockIntBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata);
.Returns( Assert.Equal("someName", context.ModelName);
delegate (ModelBindingContext context) Assert.Same(bindingContext.ValueProvider, context.ValueProvider);
{
Assert.Same(bindingContext.ModelMetadata, context.ModelMetadata);
Assert.Equal("someName", context.ModelName);
Assert.Same(bindingContext.ValueProvider, context.ValueProvider);
return ModelBindingResult.SuccessAsync("someName", 42); context.Result = ModelBindingResult.Success("someName", 42);
}); });
var shimBinder = CreateCompositeBinder(mockIntBinder.Object); var shimBinder = CreateCompositeBinder(mockIntBinder);
// Act // Act
var result = await shimBinder.BindModelAsync(bindingContext); var result = await shimBinder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(42, result.Model); Assert.Equal(42, result.Model);
@ -154,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
// Arrange // Arrange
var expectedModel = new List<int> { 1, 2, 3, 4, 5 }; var expectedModel = new List<int> { 1, 2, 3, 4, 5 };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
IsTopLevelObject = true, IsTopLevelObject = true,
@ -170,41 +157,37 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var mockIntBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(mbc =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) if (!string.IsNullOrEmpty(mbc.ModelName))
.Returns( {
delegate (ModelBindingContext mbc) return;
{ }
if (!string.IsNullOrEmpty(mbc.ModelName))
{
return ModelBindingResult.NoResultAsync;
}
Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata); Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata);
Assert.Equal("", mbc.ModelName); Assert.Equal("", mbc.ModelName);
Assert.Same(bindingContext.ValueProvider, mbc.ValueProvider); 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 // Act
var result = await shimBinder.BindModelAsync(bindingContext); var result = await shimBinder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(string.Empty, result.Key); Assert.Equal(string.Empty, result.Key);
Assert.Equal(expectedModel, result.Model); Assert.Equal(expectedModel, result.Model);
} }
[Fact] [Fact]
public async Task ModelBinder_ReturnsNoResult_IfBinderMatchesButDoesNotSetModel() public async Task ModelBinder_ReturnsNothing_IfBinderMatchesButDoesNotSetModel()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
@ -218,25 +201,25 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var modelBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
modelBinder {
.Setup(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>())) context.Result = ModelBindingResult.Failed("someName");
.Returns(ModelBindingResult.FailedAsync("someName")); });
var composite = CreateCompositeBinder(modelBinder.Object); var composite = CreateCompositeBinder(mockIntBinder);
// Act // Act
var result = await composite.BindModelAsync(bindingContext); var result = await composite.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
public async Task ModelBinder_DoesNotFallBackToEmpty_IfFallbackToEmptyPrefixFalse() public async Task ModelBinder_DoesNotFallBackToEmpty_IfFallbackToEmptyPrefixFalse()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = false, FallbackToEmptyPrefix = false,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
@ -250,28 +233,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var modelBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
modelBinder {
.Setup(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>())) Assert.Equal("someName", context.ModelName);
.Callback<ModelBindingContext>(context => context.Result = ModelBindingResult.Failed("someName");
{ });
Assert.Equal("someName", context.ModelName);
})
.Returns(ModelBindingResult.FailedAsync("someName"))
.Verifiable();
var composite = CreateCompositeBinder(modelBinder.Object); var composite = CreateCompositeBinder(mockIntBinder);
// Act & Assert // Act & Assert
var result = await composite.BindModelAsync(bindingContext); var result = await composite.BindModelResultAsync(bindingContext);
modelBinder.Verify(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>()), Times.Once); Assert.Equal(1, mockIntBinder.BindModelCount);
} }
[Fact] [Fact]
public async Task ModelBinder_DoesNotFallBackToEmpty_IfErrorsAreAdded() public async Task ModelBinder_DoesNotFallBackToEmpty_IfErrorsAreAdded()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = false, FallbackToEmptyPrefix = false,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
@ -285,29 +264,25 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var modelBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
modelBinder {
.Setup(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>())) Assert.Equal("someName", context.ModelName);
.Callback<ModelBindingContext>(context => context.ModelState.AddModelError(context.ModelName, "this is an error message");
{ context.Result = ModelBindingResult.Failed("someName");
Assert.Equal("someName", context.ModelName); });
context.ModelState.AddModelError(context.ModelName, "this is an error message");
})
.Returns(ModelBindingResult.FailedAsync("someName"))
.Verifiable();
var composite = CreateCompositeBinder(modelBinder.Object); var composite = CreateCompositeBinder(mockIntBinder);
// Act & Assert // Act & Assert
var result = await composite.BindModelAsync(bindingContext); var result = await composite.BindModelResultAsync(bindingContext);
modelBinder.Verify(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>()), Times.Once); Assert.Equal(1, mockIntBinder.BindModelCount);
} }
[Fact] [Fact]
public async Task ModelBinder_ReturnsNonEmptyResult_SetsNullValue_SetsModelStateKey() public async Task ModelBinder_ReturnsNonEmptyResult_SetsNullValue_SetsModelStateKey()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
@ -321,58 +296,30 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
FieldName = "someName", FieldName = "someName",
}; };
var modelBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(context =>
modelBinder {
.Setup(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>())) context.Result = ModelBindingResult.Success("someName", model: null);
.Returns(ModelBindingResult.SuccessAsync("someName", model: null)); });
var composite = CreateCompositeBinder(modelBinder.Object); var composite = CreateCompositeBinder(mockIntBinder);
// Act // Act
var result = await composite.BindModelAsync(bindingContext); var result = await composite.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal("someName", result.Key); Assert.Equal("someName", result.Key);
Assert.Null(result.Model); Assert.Null(result.Model);
} }
[Fact] [Fact]
public async Task BindModel_UnsuccessfulBind_BinderFails_ReturnsNoResult() public async Task BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNothing()
{ {
// Arrange // Arrange
var mockListBinder = new Mock<IModelBinder>(); var shimBinder = CreateCompositeBinder(new StubModelBinder());
mockListBinder.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync)
.Verifiable();
var shimBinder = mockListBinder.Object; var bindingContext = new DefaultModelBindingContext
var bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = false,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
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<IModelBinder>();
var shimBinder = CreateCompositeBinder(innerBinder);
var bindingContext = new ModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)),
@ -383,10 +330,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
}; };
// Act // Act
var result = await shimBinder.BindModelAsync(bindingContext); var result = await shimBinder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
@ -403,10 +350,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var model = Assert.IsType<SimplePropertiesModel>(result.Model); var model = Assert.IsType<SimplePropertiesModel>(result.Model);
Assert.Equal("firstName-value", model.FirstName); Assert.Equal("firstName-value", model.FirstName);
Assert.Equal("lastName-value", model.LastName); Assert.Equal("lastName-value", model.LastName);
@ -433,10 +380,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person)); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person));
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var model = Assert.IsType<Person>(result.Model); var model = Assert.IsType<Person>(result.Model);
Assert.Equal("firstName-value", model.FirstName); Assert.Equal("firstName-value", model.FirstName);
Assert.Equal("lastName-value", model.LastName); Assert.Equal("lastName-value", model.LastName);
@ -455,41 +402,32 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
{ {
// Arrange // Arrange
var valueProvider = new SimpleValueProvider(); var valueProvider = new SimpleValueProvider();
var mockBinder = new Mock<IModelBinder>(); var mockBinder = new StubModelBinder(ModelBindingResult.Failed("someName"));
mockBinder
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns((ModelBindingContext context) =>
{
return ModelBindingResult.FailedAsync("someName");
});
var binder = CreateCompositeBinder(mockBinder.Object); var binder = CreateCompositeBinder(mockBinder);
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
public async Task BindModel_DoesNotAddAValidationNode_IfModelBindingResultIsNoResult() public async Task BindModel_DoesNotAddAValidationNode_IfModelBindingResultIsNothing()
{ {
// Arrange // Arrange
var mockBinder = new Mock<IModelBinder>(); var mockBinder = new StubModelBinder();
mockBinder var binder = CreateCompositeBinder(mockBinder);
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync);
var binder = CreateCompositeBinder(mockBinder.Object);
var valueProvider = new SimpleValueProvider(); var valueProvider = new SimpleValueProvider();
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
@ -498,32 +436,26 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
// Arrange // Arrange
var valueProvider = new SimpleValueProvider(); var valueProvider = new SimpleValueProvider();
var mockBinder = new Mock<IModelBinder>(); var mockBinder = new StubModelBinder(ModelBindingResult.Success("someName", 42));
mockBinder
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns((ModelBindingContext context) =>
{
return ModelBindingResult.SuccessAsync("someName", 42);
});
var binder = CreateCompositeBinder(mockBinder.Object); var binder = CreateCompositeBinder(mockBinder);
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel)); var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
} }
private static ModelBindingContext CreateBindingContext( private static DefaultModelBindingContext CreateBindingContext(
IModelBinder binder, IModelBinder binder,
IValueProvider valueProvider, IValueProvider valueProvider,
Type type) Type type)
{ {
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
FallbackToEmptyPrefix = true, FallbackToEmptyPrefix = true,
IsTopLevelObject = true, IsTopLevelObject = true,

View File

@ -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<object>().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();
}
}
}
}

View File

@ -34,10 +34,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new DictionaryModelBinder<int, string>(); var binder = new DictionaryModelBinder<int, string>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var dictionary = Assert.IsAssignableFrom<IDictionary<int, string>>(result.Model); var dictionary = Assert.IsAssignableFrom<IDictionary<int, string>>(result.Model);
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -70,10 +70,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new DictionaryModelBinder<int, string>(); var binder = new DictionaryModelBinder<int, string>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Same(dictionary, result.Model); Assert.Same(dictionary, result.Model);
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -137,10 +137,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
nameof(ModelWithDictionaryProperties.DictionaryProperty)); nameof(ModelWithDictionaryProperties.DictionaryProperty));
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(modelName, result.Key); Assert.Equal(modelName, result.Key);
@ -174,10 +174,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
nameof(ModelWithDictionaryProperties.DictionaryProperty)); nameof(ModelWithDictionaryProperties.DictionaryProperty));
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal("prefix", result.Key); Assert.Equal("prefix", result.Key);
@ -225,10 +225,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
nameof(ModelWithDictionaryProperties.DictionaryWithValueTypesProperty)); nameof(ModelWithDictionaryProperties.DictionaryWithValueTypesProperty));
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal("prefix", result.Key); Assert.Equal("prefix", result.Key);
@ -266,10 +266,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
nameof(ModelWithDictionaryProperties.DictionaryWithComplexValuesProperty)); nameof(ModelWithDictionaryProperties.DictionaryWithComplexValuesProperty));
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal("prefix", result.Key); Assert.Equal("prefix", result.Key);
@ -312,10 +312,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
nameof(ModelWithDictionaryProperties.CustomDictionaryProperty)); nameof(ModelWithDictionaryProperties.CustomDictionaryProperty));
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Equal(modelName, result.Key); Assert.Equal(modelName, result.Key);
@ -341,10 +341,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Empty(Assert.IsType<Dictionary<string, string>>(result.Model)); Assert.Empty(Assert.IsType<Dictionary<string, string>>(result.Model));
Assert.Equal("modelName", result.Key); Assert.Equal("modelName", result.Key);
@ -370,10 +370,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
// Model type -> can create instance. // Model type -> can create instance.
@ -409,9 +409,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
Assert.Equal(expectedResult, result); Assert.Equal(expectedResult, result);
} }
private static ModelBindingContext CreateContext() private static DefaultModelBindingContext CreateContext()
{ {
var modelBindingContext = new ModelBindingContext() var modelBindingContext = new DefaultModelBindingContext()
{ {
ModelState = new ModelStateDictionary(), ModelState = new ModelStateDictionary(),
OperationBindingContext = new OperationBindingContext() OperationBindingContext = new OperationBindingContext()
@ -447,7 +447,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var backingStore = dictionary.ToDictionary( var backingStore = dictionary.ToDictionary(
kvp => string.Format(keyFormat, kvp.Key), kvp => string.Format(keyFormat, kvp.Key),
kvp => (StringValues)kvp.Value); kvp => (StringValues)kvp.Value);
var formCollection = new FormCollection(backingStore); var formCollection = new FormCollection(backingStore);
return new FormValueProvider( return new FormValueProvider(
@ -467,28 +467,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
return new TestValueProvider(BindingSource.Form, backingStore); return new TestValueProvider(BindingSource.Form, backingStore);
} }
private static ModelBindingContext GetModelBindingContext( private static DefaultModelBindingContext GetModelBindingContext(
bool isReadOnly, bool isReadOnly,
IDictionary<string, KeyValuePair<int, string>> values) IDictionary<string, KeyValuePair<int, string>> values)
{ {
var metadataProvider = new TestModelMetadataProvider(); var metadataProvider = new TestModelMetadataProvider();
metadataProvider.ForType<IDictionary<int, string>>().BindingDetails(bd => bd.IsReadOnly = isReadOnly); metadataProvider.ForType<IDictionary<int, string>>().BindingDetails(bd => bd.IsReadOnly = isReadOnly);
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(mbc =>
binder {
.Setup(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>())) KeyValuePair<int, string> value;
.Returns<ModelBindingContext>(mbc => if (values.TryGetValue(mbc.ModelName, out value))
{ {
KeyValuePair<int, string> value; mbc.Result = ModelBindingResult.Success(mbc.ModelName, value);
if (values.TryGetValue(mbc.ModelName, out value)) }
{ });
return ModelBindingResult.SuccessAsync(mbc.ModelName, value);
}
else
{
return ModelBindingResult.NoResultAsync;
}
});
var valueProvider = new SimpleValueProvider(); var valueProvider = new SimpleValueProvider();
foreach (var kvp in values) foreach (var kvp in values)
@ -496,7 +489,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
valueProvider.Add(kvp.Key, string.Empty); valueProvider.Add(kvp.Key, string.Empty);
} }
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(typeof(IDictionary<int, string>)), ModelMetadata = metadataProvider.GetMetadataForType(typeof(IDictionary<int, string>)),
ModelName = "someName", ModelName = "someName",

View File

@ -30,10 +30,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormCollectionModelBinder(); var binder = new FormCollectionModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var entry = bindingContext.ValidationState[result.Model]; var entry = bindingContext.ValidationState[result.Model];
@ -61,10 +61,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormCollectionModelBinder(); var binder = new FormCollectionModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
// We only support IFormCollection here. Using the concrete type won't work. // 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(); var binder = new FormCollectionModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
@ -97,10 +97,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormCollectionModelBinder(); var binder = new FormCollectionModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var form = Assert.IsAssignableFrom<IFormCollection>(result.Model); var form = Assert.IsAssignableFrom<IFormCollection>(result.Model);
Assert.Empty(form); Assert.Empty(form);
} }
@ -114,10 +114,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
return httpContext.Object; return httpContext.Object;
} }
private static ModelBindingContext GetBindingContext(Type modelType, HttpContext httpContext) private static DefaultModelBindingContext GetBindingContext(Type modelType, HttpContext httpContext)
{ {
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "file", ModelName = "file",

View File

@ -27,10 +27,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var entry = bindingContext.ValidationState[result.Model]; var entry = bindingContext.ValidationState[result.Model];
@ -51,10 +51,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var entry = bindingContext.ValidationState[result.Model]; var entry = bindingContext.ValidationState[result.Model];
@ -78,10 +78,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var files = Assert.IsAssignableFrom<IList<IFormFile>>(result.Model); var files = Assert.IsAssignableFrom<IList<IFormFile>>(result.Model);
Assert.Equal(2, files.Count); Assert.Equal(2, files.Count);
} }
@ -98,17 +98,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var file = Assert.IsAssignableFrom<IFormFile>(result.Model); var file = Assert.IsAssignableFrom<IFormFile>(result.Model);
Assert.Equal("form-data; name=file; filename=file1.txt", Assert.Equal("form-data; name=file; filename=file1.txt",
file.ContentDisposition); file.ContentDisposition);
} }
[Fact] [Fact]
public async Task FormFileModelBinder_ReturnsNoResult_WhenNoFilePosted() public async Task FormFileModelBinder_ReturnsNothing_WhenNoFilePosted()
{ {
// Arrange // Arrange
var formFiles = new FormFileCollection(); var formFiles = new FormFileCollection();
@ -117,15 +117,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Null(result.Model); Assert.Null(result.Model);
} }
[Fact] [Fact]
public async Task FormFileModelBinder_ReturnsNoResult_WhenNamesDontMatch() public async Task FormFileModelBinder_ReturnsNothing_WhenNamesDontMatch()
{ {
// Arrange // Arrange
var formFiles = new FormFileCollection(); var formFiles = new FormFileCollection();
@ -135,10 +135,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Null(result.Model); Assert.Null(result.Model);
} }
@ -161,10 +161,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
var file = Assert.IsAssignableFrom<IFormFile>(result.Model); var file = Assert.IsAssignableFrom<IFormFile>(result.Model);
@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
[Fact] [Fact]
public async Task FormFileModelBinder_ReturnsNoResult_WithEmptyContentDisposition() public async Task FormFileModelBinder_ReturnsNothing_WithEmptyContentDisposition()
{ {
// Arrange // Arrange
var formFiles = new FormFileCollection(); var formFiles = new FormFileCollection();
@ -184,15 +184,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Null(result.Model); Assert.Null(result.Model);
} }
[Fact] [Fact]
public async Task FormFileModelBinder_ReturnsNoResult_WithNoFileNameAndZeroLength() public async Task FormFileModelBinder_ReturnsNothing_WithNoFileNameAndZeroLength()
{ {
// Arrange // Arrange
var formFiles = new FormFileCollection(); var formFiles = new FormFileCollection();
@ -202,17 +202,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var binder = new FormFileModelBinder(); var binder = new FormFileModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Null(result.Model); 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 metadataProvider = new EmptyModelMetadataProvider();
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "file", ModelName = "file",

View File

@ -24,10 +24,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var modelBindingContext = GetBindingContext(type); var modelBindingContext = GetBindingContext(type);
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
} }
[Fact] [Fact]
@ -44,10 +44,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue });
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Equal(headerValue.Split(','), result.Model); 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 }); modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue });
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Equal(headerValue, result.Model); Assert.Equal(headerValue, result.Model);
} }
[Fact] [Fact]
public async Task HeaderBinder_ReturnsNoResult_ForNullBindingSource() public async Task HeaderBinder_ReturnsNothing_ForNullBindingSource()
{ {
// Arrange // Arrange
var type = typeof(string); var type = typeof(string);
@ -88,14 +88,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue });
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
public async Task HeaderBinder_ReturnsNoResult_ForNonHeaderBindingSource() public async Task HeaderBinder_ReturnsNothing_ForNonHeaderBindingSource()
{ {
// Arrange // Arrange
var type = typeof(string); var type = typeof(string);
@ -110,18 +110,18 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue }); modelBindingContext.OperationBindingContext.HttpContext.Request.Headers.Add(header, new[] { headerValue });
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // 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(); var metadataProvider = new TestModelMetadataProvider();
metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Header); metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Header);
var modelMetadata = metadataProvider.GetMetadataForType(modelType); var modelMetadata = metadataProvider.GetMetadataForType(modelType);
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = modelMetadata, ModelMetadata = modelMetadata,
ModelName = "modelName", ModelName = "modelName",

View File

@ -26,10 +26,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new KeyValuePairModelBinder<int, string>(); var binder = new KeyValuePairModelBinder<int, string>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Null(result.Model); Assert.Null(result.Model);
Assert.False(bindingContext.ModelState.IsValid); Assert.False(bindingContext.ModelState.IsValid);
Assert.Equal("someName", bindingContext.ModelName); Assert.Equal("someName", bindingContext.ModelName);
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new KeyValuePairModelBinder<int, string>(); var binder = new KeyValuePairModelBinder<int, string>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Null(result.Model); 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. // Create int binder to create the value but not the key.
var bindingContext = GetBindingContext(valueProvider); var bindingContext = GetBindingContext(valueProvider);
var mockBinder = new Mock<IModelBinder>(); var mockBinder = new StubModelBinder();
mockBinder.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync);
bindingContext.OperationBindingContext.ModelBinder = mockBinder.Object; bindingContext.OperationBindingContext.ModelBinder = mockBinder;
var binder = new KeyValuePairModelBinder<int, string>(); var binder = new KeyValuePairModelBinder<int, string>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
Assert.True(bindingContext.ModelState.IsValid); Assert.True(bindingContext.ModelState.IsValid);
Assert.Equal(0, bindingContext.ModelState.ErrorCount); Assert.Equal(0, bindingContext.ModelState.ErrorCount);
} }
@ -95,10 +93,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new KeyValuePairModelBinder<int, string>(); var binder = new KeyValuePairModelBinder<int, string>();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), result.Model); Assert.Equal(new KeyValuePair<int, string>(42, "some-value"), result.Model);
} }
@ -111,7 +109,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
bool isSuccess) bool isSuccess)
{ {
// Arrange // Arrange
ModelBindingResult innerResult; ModelBindingResult? innerResult;
if (isSuccess) if (isSuccess)
{ {
innerResult = ModelBindingResult.Success("somename.key", model); innerResult = ModelBindingResult.Success("somename.key", model);
@ -121,23 +119,19 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
innerResult = ModelBindingResult.Failed("somename.key"); innerResult = ModelBindingResult.Failed("somename.key");
} }
var innerBinder = new Mock<IModelBinder>(); var innerBinder = new StubModelBinder(context =>
innerBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) Assert.Equal("someName.key", context.ModelName);
.Returns((ModelBindingContext context) => return innerResult;
{ });
Assert.Equal("someName.key", context.ModelName); var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder);
return Task.FromResult(innerResult);
});
var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder.Object);
var binder = new KeyValuePairModelBinder<int, string>(); var binder = new KeyValuePairModelBinder<int, string>();
// Act // Act
var result = await binder.TryBindStrongModel<int>(bindingContext, "key"); var result = await binder.TryBindStrongModel<int>(bindingContext, "key");
// Assert // Assert
Assert.Equal(innerResult, result); Assert.Equal(innerResult.Value, result);
Assert.Empty(bindingContext.ModelState); Assert.Empty(bindingContext.ModelState);
} }
@ -159,10 +153,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
var model = Assert.IsType<KeyValuePair<string, string>>(result.Model); var model = Assert.IsType<KeyValuePair<string, string>>(result.Model);
Assert.Equal(default(KeyValuePair<string, string>), model); Assert.Equal(default(KeyValuePair<string, string>), model);
@ -189,15 +183,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
context.ValueProvider = new TestValueProvider(new Dictionary<string, object>()); context.ValueProvider = new TestValueProvider(new Dictionary<string, object>());
// Act // Act
var result = await binder.BindModelAsync(context); var result = await binder.BindModelResultAsync(context);
// Assert // 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() OperationBindingContext = new OperationBindingContext()
{ {
@ -214,13 +208,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
return modelBindingContext; return modelBindingContext;
} }
private static ModelBindingContext GetBindingContext( private static DefaultModelBindingContext GetBindingContext(
IValueProvider valueProvider, IValueProvider valueProvider,
IModelBinder innerBinder = null, IModelBinder innerBinder = null,
Type keyValuePairType = null) Type keyValuePairType = null)
{ {
var metataProvider = new EmptyModelMetadataProvider(); var metataProvider = new EmptyModelMetadataProvider();
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metataProvider.GetMetadataForType( ModelMetadata = metataProvider.GetMetadataForType(
keyValuePairType ?? typeof(KeyValuePair<int, string>)), keyValuePairType ?? typeof(KeyValuePair<int, string>)),
@ -242,36 +236,29 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
private static IModelBinder CreateIntBinder() private static IModelBinder CreateIntBinder()
{ {
var mockIntBinder = new Mock<IModelBinder>(); var mockIntBinder = new StubModelBinder(mbc =>
mockIntBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) if (mbc.ModelType == typeof(int))
.Returns((ModelBindingContext mbc) =>
{ {
if (mbc.ModelType == typeof(int)) var model = 42;
{ return ModelBindingResult.Success(mbc.ModelName, model);
var model = 42; }
return ModelBindingResult.SuccessAsync(mbc.ModelName, model); return null;
} });
return ModelBindingResult.NoResultAsync; return mockIntBinder;
});
return mockIntBinder.Object;
} }
private static IModelBinder CreateStringBinder() private static IModelBinder CreateStringBinder()
{ {
var mockStringBinder = new Mock<IModelBinder>(); return new StubModelBinder(mbc =>
mockStringBinder {
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>())) if (mbc.ModelType == typeof(string))
.Returns((ModelBindingContext mbc) =>
{ {
if (mbc.ModelType == typeof(string)) var model = "some-value";
{ return ModelBindingResult.Success(mbc.ModelName, model);
var model = "some-value"; }
return ModelBindingResult.SuccessAsync(mbc.ModelName, model); return null;
} });
return ModelBindingResult.NoResultAsync;
});
return mockStringBinder.Object;
} }
private class ModelWithKeyValuePairProperty private class ModelWithKeyValuePairProperty

View File

@ -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<object>().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<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
}
}
}

View File

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.AspNetCore.Mvc.ModelBinding.Test;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Moq; using Moq;
@ -22,13 +23,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
public class ModelBindingHelperTest public class ModelBindingHelperTest
{ {
public static TheoryData<ModelBindingResult> UnsuccessfulModelBindingData public static TheoryData<ModelBindingResult?> UnsuccessfulModelBindingData
{ {
get get
{ {
return new TheoryData<ModelBindingResult> return new TheoryData<ModelBindingResult?>
{ {
ModelBindingResult.NoResult, null,
ModelBindingResult.Failed("someKey"), ModelBindingResult.Failed("someKey"),
}; };
} }
@ -36,14 +37,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
[Theory] [Theory]
[MemberData(nameof(UnsuccessfulModelBindingData))] [MemberData(nameof(UnsuccessfulModelBindingData))]
public async Task TryUpdateModel_ReturnsFalse_IfBinderIsUnsuccessful(ModelBindingResult binderResult) public async Task TryUpdateModel_ReturnsFalse_IfBinderIsUnsuccessful(ModelBindingResult? binderResult)
{ {
// Arrange // Arrange
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(binderResult);
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(Task.FromResult<ModelBindingResult>(binderResult));
var model = new MyModel(); var model = new MyModel();
// Act // Act
@ -52,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
string.Empty, string.Empty,
new ActionContext() { HttpContext = new DefaultHttpContext() }, new ActionContext() { HttpContext = new DefaultHttpContext() },
metadataProvider, metadataProvider,
GetCompositeBinder(binder.Object), GetCompositeBinder(binder),
Mock.Of<IValueProvider>(), Mock.Of<IValueProvider>(),
new List<IInputFormatter>(), new List<IInputFormatter>(),
new Mock<IObjectModelValidator>(MockBehavior.Strict).Object, new Mock<IObjectModelValidator>(MockBehavior.Strict).Object,
@ -153,14 +151,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
[Theory] [Theory]
[MemberData(nameof(UnsuccessfulModelBindingData))] [MemberData(nameof(UnsuccessfulModelBindingData))]
public async Task TryUpdateModel_UsingIncludePredicateOverload_ReturnsFalse_IfBinderIsUnsuccessful( public async Task TryUpdateModel_UsingIncludePredicateOverload_ReturnsFalse_IfBinderIsUnsuccessful(
ModelBindingResult binderResult) ModelBindingResult? binderResult)
{ {
// Arrange // Arrange
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(binderResult);
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(Task.FromResult<ModelBindingResult>(binderResult));
var model = new MyModel(); var model = new MyModel();
Func<ModelBindingContext, string, bool> includePredicate = (context, propertyName) => true; Func<ModelBindingContext, string, bool> includePredicate = (context, propertyName) => true;
@ -170,7 +165,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
string.Empty, string.Empty,
new ActionContext() { HttpContext = new DefaultHttpContext() }, new ActionContext() { HttpContext = new DefaultHttpContext() },
metadataProvider, metadataProvider,
GetCompositeBinder(binder.Object), GetCompositeBinder(binder),
Mock.Of<IValueProvider>(), Mock.Of<IValueProvider>(),
new List<IInputFormatter>(), new List<IInputFormatter>(),
new Mock<IObjectModelValidator>(MockBehavior.Strict).Object, new Mock<IObjectModelValidator>(MockBehavior.Strict).Object,
@ -243,14 +238,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
[Theory] [Theory]
[MemberData(nameof(UnsuccessfulModelBindingData))] [MemberData(nameof(UnsuccessfulModelBindingData))]
public async Task TryUpdateModel_UsingIncludeExpressionOverload_ReturnsFalse_IfBinderIsUnsuccessful( public async Task TryUpdateModel_UsingIncludeExpressionOverload_ReturnsFalse_IfBinderIsUnsuccessful(
ModelBindingResult binderResult) ModelBindingResult? binderResult)
{ {
// Arrange // Arrange
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(binderResult);
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(Task.FromResult<ModelBindingResult>(binderResult));
var model = new MyModel(); var model = new MyModel();
// Act // Act
@ -259,7 +251,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
string.Empty, string.Empty,
new ActionContext() { HttpContext = new DefaultHttpContext() }, new ActionContext() { HttpContext = new DefaultHttpContext() },
metadataProvider, metadataProvider,
GetCompositeBinder(binder.Object), GetCompositeBinder(binder),
Mock.Of<IValueProvider>(), Mock.Of<IValueProvider>(),
new List<IInputFormatter>(), new List<IInputFormatter>(),
new Mock<IObjectModelValidator>(MockBehavior.Strict).Object, new Mock<IObjectModelValidator>(MockBehavior.Strict).Object,
@ -500,14 +492,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
[Theory] [Theory]
[MemberData(nameof(UnsuccessfulModelBindingData))] [MemberData(nameof(UnsuccessfulModelBindingData))]
public async Task TryUpdateModelNonGeneric_PredicateOverload_ReturnsFalse_IfBinderIsUnsuccessful( public async Task TryUpdateModelNonGeneric_PredicateOverload_ReturnsFalse_IfBinderIsUnsuccessful(
ModelBindingResult binderResult) ModelBindingResult? binderResult)
{ {
// Arrange // Arrange
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(binderResult);
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(Task.FromResult<ModelBindingResult>(binderResult));
var model = new MyModel(); var model = new MyModel();
Func<ModelBindingContext, string, bool> includePredicate = (context, propertyName) => true; Func<ModelBindingContext, string, bool> includePredicate = (context, propertyName) => true;
@ -518,7 +507,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
prefix: "", prefix: "",
actionContext: new ActionContext() { HttpContext = new DefaultHttpContext() }, actionContext: new ActionContext() { HttpContext = new DefaultHttpContext() },
metadataProvider: metadataProvider, metadataProvider: metadataProvider,
modelBinder: GetCompositeBinder(binder.Object), modelBinder: GetCompositeBinder(binder),
valueProvider: Mock.Of<IValueProvider>(), valueProvider: Mock.Of<IValueProvider>(),
inputFormatters: new List<IInputFormatter>(), inputFormatters: new List<IInputFormatter>(),
objectModelValidator: new Mock<IObjectModelValidator>(MockBehavior.Strict).Object, objectModelValidator: new Mock<IObjectModelValidator>(MockBehavior.Strict).Object,
@ -593,14 +582,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
[Theory] [Theory]
[MemberData(nameof(UnsuccessfulModelBindingData))] [MemberData(nameof(UnsuccessfulModelBindingData))]
public async Task TryUpdateModelNonGeneric_ModelTypeOverload_ReturnsFalse_IfBinderIsUnsuccessful( public async Task TryUpdateModelNonGeneric_ModelTypeOverload_ReturnsFalse_IfBinderIsUnsuccessful(
ModelBindingResult binderResult) ModelBindingResult? binderResult)
{ {
// Arrange // Arrange
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder(binderResult);
binder
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(Task.FromResult<ModelBindingResult>(binderResult));
var model = new MyModel(); var model = new MyModel();
// Act // Act
@ -669,9 +656,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Arrange // Arrange
var metadataProvider = new EmptyModelMetadataProvider(); var metadataProvider = new EmptyModelMetadataProvider();
var binder = new Mock<IModelBinder>(); var binder = new StubModelBinder();
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync);
var model = new MyModel(); var model = new MyModel();
Func<ModelBindingContext, string, bool> includePredicate = Func<ModelBindingContext, string, bool> includePredicate =
(context, propertyName) => true; (context, propertyName) => true;

View File

@ -23,23 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Same(model, result.Model); 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] [Fact]
public void Failed_SetsProperties() public void Failed_SetsProperties()
{ {
@ -54,44 +38,5 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
Assert.False(result.IsModelSet); Assert.False(result.IsModelSet);
Assert.Null(result.Model); 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);
}
} }
} }

View File

@ -9,6 +9,7 @@ using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Internal; using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding.Test;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Moq; using Moq;
@ -33,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var metadataProvider = new TestModelMetadataProvider(); var metadataProvider = new TestModelMetadataProvider();
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
IsTopLevelObject = isTopLevelObject, IsTopLevelObject = isTopLevelObject,
@ -70,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.First(metadata => metadata.PropertyName == nameof(Document.SubDocument)); .First(metadata => metadata.PropertyName == nameof(Document.SubDocument));
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = modelMetadata, ModelMetadata = modelMetadata,
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -97,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
// Here the metadata represents a top level object. // Here the metadata represents a top level object.
IsTopLevelObject = true, IsTopLevelObject = true,
@ -130,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(BinderMetadataPocoType)), ModelMetadata = GetMetadataForType(typeof(BinderMetadataPocoType)),
ValueProvider = mockValueProvider.Object, ValueProvider = mockValueProvider.Object,
@ -174,7 +175,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var modelMetadata = typeMetadata.Properties[nameof(SimpleContainer.Simple)]; var modelMetadata = typeMetadata.Properties[nameof(SimpleContainer.Simple)];
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = modelMetadata, ModelMetadata = modelMetadata,
ModelName = "SimpleContainer.Simple", ModelName = "SimpleContainer.Simple",
@ -206,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Arrange // Arrange
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
IsTopLevelObject = false, IsTopLevelObject = false,
@ -231,7 +232,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
// Arrange // Arrange
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
IsTopLevelObject = true, IsTopLevelObject = true,
ModelMetadata = GetMetadataForType(typeof(PersonWithNoProperties)) ModelMetadata = GetMetadataForType(typeof(PersonWithNoProperties))
@ -266,7 +267,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(modelType), ModelMetadata = GetMetadataForType(modelType),
ValueProvider = mockValueProvider.Object, ValueProvider = mockValueProvider.Object,
@ -325,7 +326,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var modelMetadata = GetMetadataForType(modelType); var modelMetadata = GetMetadataForType(modelType);
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = modelMetadata, ModelMetadata = modelMetadata,
ValueProvider = mockValueProvider.Object, ValueProvider = mockValueProvider.Object,
@ -374,7 +375,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var bindingContext = new MutableObjectBinderContext var bindingContext = new MutableObjectBinderContext
{ {
ModelBindingContext = new ModelBindingContext ModelBindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(modelType), ModelMetadata = GetMetadataForType(modelType),
ValueProvider = mockValueProvider.Object, ValueProvider = mockValueProvider.Object,
@ -411,19 +412,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.Returns(true); .Returns(true);
// Mock binder fails to bind all properties. // Mock binder fails to bind all properties.
var mockBinder = new Mock<IModelBinder>(); var mockBinder = new StubModelBinder();
mockBinder
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync);
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(Person)), ModelMetadata = GetMetadataForType(typeof(Person)),
ModelName = "someName", ModelName = "someName",
ValueProvider = mockValueProvider.Object, ValueProvider = mockValueProvider.Object,
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
{ {
ModelBinder = mockBinder.Object, ModelBinder = mockBinder,
MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(),
ValidatorProvider = Mock.Of<IModelValidatorProvider>() ValidatorProvider = Mock.Of<IModelValidatorProvider>()
}, },
@ -442,7 +440,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.Returns(new ModelMetadata[0]); .Returns(new ModelMetadata[0]);
// Act // Act
var retValue = await testableBinder.Object.BindModelAsync(bindingContext); var retValue = await testableBinder.Object.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(retValue); Assert.NotNull(retValue);
@ -462,12 +460,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.Returns(false); .Returns(false);
// Mock binder fails to bind all properties. // Mock binder fails to bind all properties.
var mockBinder = new Mock<IModelBinder>(); var mockBinder = new StubModelBinder();
mockBinder
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(ModelBindingResult.NoResultAsync);
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
IsTopLevelObject = true, IsTopLevelObject = true,
ModelMetadata = GetMetadataForType(typeof(Person)), ModelMetadata = GetMetadataForType(typeof(Person)),
@ -475,7 +470,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
ValueProvider = mockValueProvider.Object, ValueProvider = mockValueProvider.Object,
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
{ {
ModelBinder = mockBinder.Object, ModelBinder = mockBinder,
MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(),
ValidatorProvider = Mock.Of<IModelValidatorProvider>() ValidatorProvider = Mock.Of<IModelValidatorProvider>()
}, },
@ -495,7 +490,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.Returns(new ModelMetadata[0]); .Returns(new ModelMetadata[0]);
// Act // Act
var retValue = await testableBinder.Object.BindModelAsync(bindingContext); var retValue = await testableBinder.Object.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotNull(retValue); Assert.NotNull(retValue);
@ -548,7 +543,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void CreateModel_InstantiatesInstanceOfMetadataType() public void CreateModel_InstantiatesInstanceOfMetadataType()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(Person)) ModelMetadata = GetMetadataForType(typeof(Person))
}; };
@ -566,7 +561,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void GetModel_ModelIsNotNull_DoesNothing() public void GetModel_ModelIsNotNull_DoesNothing()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
Model = new Person(), Model = new Person(),
ModelMetadata = GetMetadataForType(typeof(Person)) ModelMetadata = GetMetadataForType(typeof(Person))
@ -588,7 +583,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void GetModel_ModelIsNull_CallsCreateModel() public void GetModel_ModelIsNull_CallsCreateModel()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(Person)) ModelMetadata = GetMetadataForType(typeof(Person))
}; };
@ -614,7 +609,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
// Arrange // Arrange
var expectedPropertyNames = new[] { "FirstName", "LastName" }; var expectedPropertyNames = new[] { "FirstName", "LastName" };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(PersonWithBindExclusion)), ModelMetadata = GetMetadataForType(typeof(PersonWithBindExclusion)),
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -650,7 +645,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
nameof(Person.PropertyWithInitializedValue), nameof(Person.PropertyWithInitializedValue),
nameof(Person.PropertyWithInitializedValueAndDefault), nameof(Person.PropertyWithInitializedValueAndDefault),
}; };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(Person)), ModelMetadata = GetMetadataForType(typeof(Person)),
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -675,7 +670,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
// Arrange // Arrange
var expectedPropertyNames = new[] { "IncludedByDefault1", "IncludedByDefault2" }; var expectedPropertyNames = new[] { "IncludedByDefault1", "IncludedByDefault2" };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(TypeWithExcludedPropertiesUsingBindAttribute)), ModelMetadata = GetMetadataForType(typeof(TypeWithExcludedPropertiesUsingBindAttribute)),
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -707,7 +702,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{ {
// Arrange // Arrange
var expectedPropertyNames = new[] { "IncludedExplicitly1", "IncludedExplicitly2" }; var expectedPropertyNames = new[] { "IncludedExplicitly1", "IncludedExplicitly2" };
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(TypeWithIncludedPropertiesUsingBindAttribute)), ModelMetadata = GetMetadataForType(typeof(TypeWithIncludedPropertiesUsingBindAttribute)),
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -731,7 +726,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void GetRequiredPropertiesCollection_MixedAttributes() public void GetRequiredPropertiesCollection_MixedAttributes()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(ModelWithMixedBindingBehaviors)), ModelMetadata = GetMetadataForType(typeof(ModelWithMixedBindingBehaviors)),
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -752,7 +747,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void GetPropertyValidationInfo_WithIndexerProperties_Succeeds() public void GetPropertyValidationInfo_WithIndexerProperties_Succeeds()
{ {
// Arrange // Arrange
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = GetMetadataForType(typeof(PersonCollection)), ModelMetadata = GetMetadataForType(typeof(PersonCollection)),
OperationBindingContext = new OperationBindingContext OperationBindingContext = new OperationBindingContext
@ -781,7 +776,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
}; };
var containerMetadata = GetMetadataForType(model.GetType()); var containerMetadata = GetMetadataForType(model.GetType());
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
Model = model, Model = model,
ModelMetadata = containerMetadata, ModelMetadata = containerMetadata,
@ -831,7 +826,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
}; };
var containerMetadata = GetMetadataForType(model.GetType()); var containerMetadata = GetMetadataForType(model.GetType());
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
Model = model, Model = model,
ModelMetadata = containerMetadata, ModelMetadata = containerMetadata,
@ -881,7 +876,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
}; };
var containerMetadata = GetMetadataForType(model.GetType()); var containerMetadata = GetMetadataForType(model.GetType());
var bindingContext = new ModelBindingContext() var bindingContext = new DefaultModelBindingContext()
{ {
Model = model, Model = model,
ModelMetadata = containerMetadata, ModelMetadata = containerMetadata,
@ -1566,9 +1561,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
bindingContext.ModelState["foo.NameNoAttribute"].Errors[0].Exception.Message); 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, Model = model,
ModelMetadata = metadata, ModelMetadata = metadata,

View File

@ -22,10 +22,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var modelBindingContext = GetBindingContext(type); var modelBindingContext = GetBindingContext(type);
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.NotNull(result.Model); Assert.NotNull(result.Model);
Assert.Equal("modelName", result.Key); Assert.Equal("modelName", result.Key);
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
} }
[Fact] [Fact]
public async Task ServiceModelBinder_ReturnsNoResult_ForNullBindingSource() public async Task ServiceModelBinder_ReturnsNothing_ForNullBindingSource()
{ {
// Arrange // Arrange
var type = typeof(IService); var type = typeof(IService);
@ -47,14 +47,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
modelBindingContext.BindingSource = null; modelBindingContext.BindingSource = null;
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
[Fact] [Fact]
public async Task ServiceModelBinder_ReturnsNoResult_ForNonServiceBindingSource() public async Task ServiceModelBinder_ReturnsNothing_ForNonServiceBindingSource()
{ {
// Arrange // Arrange
var type = typeof(IService); var type = typeof(IService);
@ -64,13 +64,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
modelBindingContext.BindingSource = BindingSource.Body; modelBindingContext.BindingSource = BindingSource.Body;
// Act // Act
var result = await binder.BindModelAsync(modelBindingContext); var result = await binder.BindModelResultAsync(modelBindingContext);
// Assert // 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(); var metadataProvider = new TestModelMetadataProvider();
metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Services); metadataProvider.ForType(modelType).BindingDetails(d => d.BindingSource = BindingSource.Services);
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var services = new ServiceCollection(); var services = new ServiceCollection();
services.AddSingleton<IService>(new Service()); services.AddSingleton<IService>(new Service());
var bindingContext = new ModelBindingContext var bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = modelMetadata, ModelMetadata = modelMetadata,
ModelName = "modelName", ModelName = "modelName",

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
[InlineData(typeof(object))] [InlineData(typeof(object))]
[InlineData(typeof(Calendar))] [InlineData(typeof(Calendar))]
[InlineData(typeof(TestClass))] [InlineData(typeof(TestClass))]
public async Task BindModel_ReturnsNoResult_IfTypeCannotBeConverted(Type destinationType) public async Task BindModel_ReturnsNothing_IfTypeCannotBeConverted(Type destinationType)
{ {
// Arrange // Arrange
var bindingContext = GetBindingContext(destinationType); var bindingContext = GetBindingContext(destinationType);
@ -27,10 +27,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
} }
public static TheoryData<Type> ConvertableTypeData public static TheoryData<Type> ConvertableTypeData
@ -72,10 +72,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.False(result.IsModelSet); Assert.False(result.IsModelSet);
} }
@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.False(result.IsModelSet); Assert.False(result.IsModelSet);
@ -123,10 +123,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.NotEqual(default(ModelBindingResult), result);
Assert.Null(result.Model); Assert.Null(result.Model);
Assert.False(bindingContext.ModelState.IsValid); Assert.False(bindingContext.ModelState.IsValid);
var error = Assert.Single(bindingContext.ModelState["theModelName"].Errors); var error = Assert.Single(bindingContext.ModelState["theModelName"].Errors);
@ -141,10 +141,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, result); Assert.Equal(default(ModelBindingResult), result);
Assert.Empty(bindingContext.ModelState); Assert.Empty(bindingContext.ModelState);
} }
@ -161,7 +161,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.Null(result.Model); Assert.Null(result.Model);
@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
@ -207,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
var binder = new SimpleTypeModelBinder(); var binder = new SimpleTypeModelBinder();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); var result = await binder.BindModelResultAsync(bindingContext);
// Assert // Assert
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
@ -215,9 +215,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
Assert.Equal((FlagsEnum)expected, boundModel); 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), ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType),
ModelName = "theModelName", ModelName = "theModelName",

View File

@ -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<ModelBindingContext, Task> _callback;
public StubModelBinder()
{
_callback = context => TaskCache.CompletedTask;
}
public StubModelBinder(ModelBindingResult? result)
{
_callback = context =>
{
context.Result = result;
return TaskCache.CompletedTask;
};
}
public StubModelBinder(Action<ModelBindingContext> callback)
{
_callback = context =>
{
callback(context);
return TaskCache.CompletedTask;
};
}
public StubModelBinder(Func<ModelBindingContext, ModelBindingResult?> callback)
{
_callback = context =>
{
var result = callback.Invoke(context);
context.Result = result;
return TaskCache.CompletedTask;
};
}
public StubModelBinder(Func<ModelBindingContext, Task<ModelBindingResult?>> 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);
}
}
}

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var type = typeof(User); var type = typeof(User);
var provider = CreateProvider(); var provider = CreateProvider();
var context = new ModelBindingContext(); var context = new DefaultModelBindingContext();
var expected = new[] { "IsAdmin", "UserName" }; var expected = new[] { "IsAdmin", "UserName" };

View File

@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var model = new Person3(); var model = new Person3();
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
var model = new Person4(); var model = new Person4();
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -229,7 +229,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -276,7 +276,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -317,7 +317,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -1,9 +1,11 @@
// 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. // 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 System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Xunit; using Xunit;
@ -34,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -71,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); Assert.Equal(null, modelBindingResult);
// ModelState (not set unless inner binder sets it) // ModelState (not set unless inner binder sets it)
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -108,7 +110,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
// Assert // Assert
// ModelBindingResult // ModelBindingResult
Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); Assert.Equal(null, modelBindingResult);
// ModelState // ModelState
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -144,7 +146,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
// Assert // Assert
// ModelBindingResult // ModelBindingResult
Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); Assert.Equal(null, modelBindingResult);
// ModelState // ModelState
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -174,7 +176,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -217,7 +219,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -258,7 +260,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -280,11 +282,17 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
private class AddressModelBinder : IModelBinder private class AddressModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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)) if (bindingContext.ModelType != typeof(Address))
{ {
return null; return TaskCache.CompletedTask;
} }
var address = new Address() { Street = "SomeStreet" }; var address = new Address() { Street = "SomeStreet" };
@ -294,45 +302,73 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
new string[] { address.Street }, new string[] { address.Street },
address.Street); address.Street);
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, address); bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, address);
return TaskCache.CompletedTask;
} }
} }
private class SuccessModelBinder : IModelBinder private class SuccessModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) public Task BindModelAsync(ModelBindingContext bindingContext)
{ {
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
Debug.Assert(bindingContext.Result == null);
var model = "Success"; var model = "Success";
bindingContext.ModelState.SetModelValue( bindingContext.ModelState.SetModelValue(
bindingContext.ModelName, bindingContext.ModelName,
new string[] { model }, new string[] { model },
model); model);
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model); bindingContext.Result =ModelBindingResult.Success(bindingContext.ModelName, model);
return TaskCache.CompletedTask;
} }
} }
private class NullModelBinder : IModelBinder private class NullModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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 private class NullModelNotSetModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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 private class NullResultModelBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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;
} }
} }
} }

View File

@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -182,7 +182,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -258,7 +258,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -301,7 +301,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -379,7 +379,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -421,7 +421,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -480,7 +480,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -518,7 +518,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -582,7 +582,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -639,7 +639,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -90,12 +90,12 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); Assert.Equal(default(ModelBindingResult), modelBindingResult);
// ModelState // ModelState
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -230,7 +230,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -263,7 +263,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -301,7 +301,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -360,7 +360,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -463,7 +463,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -506,7 +506,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -557,7 +557,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -607,7 +607,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -664,7 +664,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -703,7 +703,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -927,7 +927,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -164,7 +164,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -292,7 +292,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -332,7 +332,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -371,7 +371,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -522,7 +522,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
@ -149,10 +149,10 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); Assert.Equal(default(ModelBindingResult), modelBindingResult);
// ModelState // ModelState
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);

View File

@ -3,9 +3,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Xunit; using Xunit;
@ -40,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -78,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -117,7 +119,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -150,18 +152,25 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
private class AddressBinder : IModelBinder private class AddressBinder : IModelBinder
{ {
public Task<ModelBindingResult> 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; var allowedBindingSource = bindingContext.BindingSource;
if (allowedBindingSource == null || if (allowedBindingSource == null ||
!allowedBindingSource.CanAcceptDataFrom(BindAddressAttribute.Source)) !allowedBindingSource.CanAcceptDataFrom(BindAddressAttribute.Source))
{ {
// Binding Sources are opt-in. This model either didn't specify one or specified something // Binding Sources are opt-in. This model either didn't specify one or specified something
// incompatible so let other binders run. // 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; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -220,7 +229,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -255,7 +264,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -300,7 +309,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -345,7 +354,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -380,7 +389,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -424,7 +433,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -468,7 +477,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -504,7 +513,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -552,7 +561,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -600,7 +609,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.False(modelBindingResult.IsModelSet); Assert.False(modelBindingResult.IsModelSet);
@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.False(modelBindingResult.IsModelSet); Assert.False(modelBindingResult.IsModelSet);
@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.False(modelBindingResult.IsModelSet); Assert.False(modelBindingResult.IsModelSet);
@ -201,7 +201,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.False(modelBindingResult.IsModelSet); Assert.False(modelBindingResult.IsModelSet);
@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -324,7 +324,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -360,7 +360,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -405,7 +405,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -446,7 +446,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -487,7 +487,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -280,7 +280,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -366,7 +366,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -420,7 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -464,7 +464,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -509,7 +509,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -555,7 +555,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -596,7 +596,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -637,7 +637,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -683,7 +683,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -729,7 +729,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -767,7 +767,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -809,7 +809,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -855,7 +855,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -901,7 +901,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -939,7 +939,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -981,7 +981,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1027,7 +1027,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1073,7 +1073,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1111,7 +1111,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1153,7 +1153,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1199,7 +1199,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1245,7 +1245,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1283,7 +1283,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1331,7 +1331,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1375,7 +1375,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1421,7 +1421,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1473,7 +1473,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1518,7 +1518,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1567,7 +1567,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1618,7 +1618,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1661,7 +1661,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1700,7 +1700,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1743,7 +1743,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1786,7 +1786,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1825,7 +1825,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1869,7 +1869,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1913,7 +1913,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult

View File

@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -276,7 +276,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -325,7 +325,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -377,7 +377,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
@ -420,7 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
@ -458,12 +458,12 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult
Assert.Equal(ModelBindingResult.NoResult, modelBindingResult); Assert.Equal(default(ModelBindingResult), modelBindingResult);
// ModelState // ModelState
Assert.True(modelState.IsValid); Assert.True(modelState.IsValid);
@ -512,7 +512,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
// ModelBindingResult // ModelBindingResult

View File

@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -314,7 +314,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -353,7 +353,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -401,7 +401,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -439,7 +439,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -487,7 +487,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -524,7 +524,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -575,7 +575,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -612,7 +612,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -652,7 +652,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -710,7 +710,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -747,7 +747,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -817,7 +817,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -854,7 +854,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -905,7 +905,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -942,7 +942,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -982,7 +982,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1022,7 +1022,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1062,7 +1062,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var modelState = operationContext.ActionContext.ModelState; var modelState = operationContext.ActionContext.ModelState;
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1193,7 +1193,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
modelState.SetModelValue("CustomParameter.message", "Hello", "Hello"); modelState.SetModelValue("CustomParameter.message", "Hello", "Hello");
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1236,7 +1236,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
modelState.SetModelValue("message", "Hello", "Hello"); modelState.SetModelValue("message", "Hello", "Hello");
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1281,7 +1281,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
modelState.SetModelValue("other.key", "1", "1"); modelState.SetModelValue("other.key", "1", "1");
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);
@ -1328,7 +1328,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
modelState.SetModelValue("other.key", "1", "1"); modelState.SetModelValue("other.key", "1", "1");
// Act // Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext); var modelBindingResult = await argumentBinder.BindModelAsync(parameter, operationContext) ?? default(ModelBindingResult);
// Assert // Assert
Assert.True(modelBindingResult.IsModelSet); Assert.True(modelBindingResult.IsModelSet);

View File

@ -22,10 +22,12 @@ namespace Microsoft.AspNetCore.Mvc.WebApiCompatShim
var expectedModel = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage(); var expectedModel = bindingContext.OperationBindingContext.HttpContext.GetHttpRequestMessage();
// Act // Act
var result = await binder.BindModelAsync(bindingContext); await binder.BindModelAsync(bindingContext);
// Assert // Assert
Assert.NotEqual(ModelBindingResult.NoResult, result); Assert.True(bindingContext.Result.HasValue);
var result = bindingContext.Result.Value;
Assert.True(result.IsModelSet); Assert.True(result.IsModelSet);
Assert.Same(expectedModel, result.Model); Assert.Same(expectedModel, result.Model);
@ -46,16 +48,16 @@ namespace Microsoft.AspNetCore.Mvc.WebApiCompatShim
var bindingContext = GetBindingContext(type); var bindingContext = GetBindingContext(type);
// Act // Act
var result = await binder.BindModelAsync(bindingContext); await binder.BindModelAsync(bindingContext);
// Assert // 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(); var metadataProvider = new EmptyModelMetadataProvider();
ModelBindingContext bindingContext = new ModelBindingContext DefaultModelBindingContext bindingContext = new DefaultModelBindingContext
{ {
ModelMetadata = metadataProvider.GetMetadataForType(modelType), ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "someName", ModelName = "someName",