Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.ComponentModel;
namespace Microsoft.Web.Mvc.Controls.Test
{
public class DesignModeSite : ISite
{
IComponent ISite.Component
{
get { throw new NotImplementedException(); }
}
IContainer ISite.Container
{
get { throw new NotImplementedException(); }
}
bool ISite.DesignMode
{
get { return true; }
}
string ISite.Name
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
object IServiceProvider.GetService(Type serviceType)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,130 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Mvc;
using Xunit;
namespace Microsoft.Web.Mvc.Controls.Test
{
public class DropDownListTest
{
[Fact]
public void NameProperty()
{
// TODO: This
}
[Fact]
public void RenderWithNoNameNotInDesignModeThrows()
{
// TODO: This
}
[Fact]
public void RenderWithNoNameInDesignModeRendersWithSampleData()
{
// Setup
DropDownList c = new DropDownList();
// Execute
string html = MvcTestHelper.GetControlRendering(c, true);
// Verify
Assert.Equal(@"<select>
<option>
Sample Item
</option>
</select>", html);
}
[Fact]
public void RenderWithNoAttributes()
{
// Setup
DropDownList c = new DropDownList();
c.Name = "nameKey";
ViewDataContainer vdc = new ViewDataContainer();
vdc.Controls.Add(c);
vdc.ViewData = new ViewDataDictionary();
vdc.ViewData["nameKey"] = new SelectList(new[] { "aaa", "bbb", "ccc" }, "bbb");
// Execute
string html = MvcTestHelper.GetControlRendering(c, false);
// Verify
Assert.Equal(@"<select name=""nameKey"">
<option>
aaa
</option><option selected=""selected"">
bbb
</option><option>
ccc
</option>
</select>", html);
}
[Fact]
public void RenderWithTextsAndValues()
{
// Setup
DropDownList c = new DropDownList();
c.Name = "nameKey";
ViewDataContainer vdc = new ViewDataContainer();
vdc.Controls.Add(c);
vdc.ViewData = new ViewDataDictionary();
vdc.ViewData["nameKey"] = new SelectList(
new[]
{
new { Text = "aaa", Value = "111" },
new { Text = "bbb", Value = "222" },
new { Text = "ccc", Value = "333" }
},
"Value",
"Text",
"222");
// Execute
string html = MvcTestHelper.GetControlRendering(c, false);
// Verify
Assert.Equal(@"<select name=""nameKey"">
<option value=""111"">
aaa
</option><option value=""222"" selected=""selected"">
bbb
</option><option value=""333"">
ccc
</option>
</select>", html);
}
[Fact]
public void RenderWithNameAndIdRendersNameAndIdAttribute()
{
// Setup
DropDownList c = new DropDownList();
c.Name = "nameKey";
c.ID = "someID";
ViewDataContainer vdc = new ViewDataContainer();
vdc.Controls.Add(c);
vdc.ViewData = new ViewDataDictionary();
vdc.ViewData["nameKey"] = new SelectList(new[] { "aaa", "bbb", "ccc" }, "bbb");
// Execute
string html = MvcTestHelper.GetControlRendering(c, false);
// Verify
Assert.Equal(@"<select id=""someID"" name=""nameKey"">
<option>
aaa
</option><option selected=""selected"">
bbb
</option><option>
ccc
</option>
</select>", html);
}
}
}

View File

@@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.UI;
using Xunit;
namespace Microsoft.Web.Mvc.Controls.Test
{
public class MvcControlTest
{
[Fact]
public void AttributesProperty()
{
// Setup
DummyMvcControl c = new DummyMvcControl();
// Execute
IDictionary<string, string> attrs = c.Attributes;
// Verify
Assert.NotNull(attrs);
Assert.Empty(attrs);
}
[Fact]
public void GetSetAttributes()
{
// Setup
DummyMvcControl c = new DummyMvcControl();
IAttributeAccessor attrAccessor = c;
IDictionary<string, string> attrs = c.Attributes;
// Execute and Verify
string value;
value = attrAccessor.GetAttribute("xyz");
Assert.Null(value);
attrAccessor.SetAttribute("a1", "v1");
value = attrAccessor.GetAttribute("a1");
Assert.Equal("v1", value);
Assert.Single(attrs);
value = c.Attributes["a1"];
Assert.Equal("v1", value);
}
[Fact]
public void EnableViewStateProperty()
{
DummyMvcControl c = new DummyMvcControl();
Assert.True(c.EnableViewState);
Assert.True((c).EnableViewState);
c.EnableViewState = false;
Assert.False(c.EnableViewState);
Assert.False((c).EnableViewState);
c.EnableViewState = true;
Assert.True(c.EnableViewState);
Assert.True((c).EnableViewState);
}
[Fact]
public void ViewContextWithNoPageIsNull()
{
// Setup
DummyMvcControl c = new DummyMvcControl();
Control c1 = new Control();
c1.Controls.Add(c);
// Execute
ViewContext vc = c.ViewContext;
// Verify
Assert.Null(vc);
}
private sealed class DummyMvcControl : MvcControl
{
}
}
}

View File

@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
using System.Web.UI;
namespace Microsoft.Web.Mvc.Controls.Test
{
public static class MvcTestHelper
{
public static string GetControlRendering(Control c, bool designMode)
{
if (designMode)
{
c.Site = new DesignModeSite();
}
HtmlTextWriter writer = new HtmlTextWriter(new StringWriter());
c.RenderControl(writer);
return writer.InnerWriter.ToString();
}
}
}

View File

@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Mvc;
using System.Web.UI;
namespace Microsoft.Web.Mvc.Controls.Test
{
public class ViewDataContainer : Control, IViewDataContainer
{
public ViewDataDictionary ViewData { get; set; }
}
}

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),Runtime.sln))\tools\WebStack.settings.targets" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6C28DA70-60F1-4442-967F-591BF3962EC5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Web</RootNamespace>
<AssemblyName>Microsoft.Web.Mvc.Test</AssemblyName>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<!-- Force signing off -->
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>$(WebStackRootPath)\bin\Debug\Test\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>$(WebStackRootPath)\bin\Release\Test\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'CodeCoverage' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>$(WebStackRootPath)\bin\CodeCoverage\Test\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Moq, Version=4.0.10827.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Linq" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="xunit">
<HintPath>..\..\packages\xunit.1.9.0.1566\lib\xunit.dll</HintPath>
</Reference>
<Reference Include="xunit.extensions">
<HintPath>..\..\packages\xunit.extensions.1.9.0.1566\lib\xunit.extensions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Controls\Test\DesignModeSite.cs" />
<Compile Include="Controls\Test\DropDownListTest.cs" />
<Compile Include="Controls\Test\MvcControlTest.cs" />
<Compile Include="Controls\Test\MvcTestHelper.cs" />
<Compile Include="Controls\Test\ViewDataContainer.cs" />
<Compile Include="ModelBinding\Test\BindingBehaviorAttributeTest.cs" />
<Compile Include="ModelBinding\Test\BinaryDataModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\ExtensibleModelBinderAdapterTest.cs" />
<Compile Include="ModelBinding\Test\ExtensibleModelBindingContextTest.cs" />
<Compile Include="ModelBinding\Test\GenericModelBinderProviderTest.cs" />
<Compile Include="Test\AreaHelpersTest.cs" />
<Compile Include="ModelBinding\Test\CollectionModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\CollectionModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\CollectionModelBinderUtilTest.cs" />
<Compile Include="ModelBinding\Test\ComplexModelDtoResultTest.cs" />
<Compile Include="ModelBinding\Test\ComplexModelDtoTest.cs" />
<Compile Include="ModelBinding\Test\ComplexModelDtoModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\ComplexModelDtoModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\ArrayModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\ArrayModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\DictionaryModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\DictionaryModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\KeyValuePairModelBinderUtilTest.cs" />
<Compile Include="ModelBinding\Test\KeyValuePairModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\KeyValuePairModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\MutableObjectModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\MutableObjectModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\TypeConverterModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\TypeConverterModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\ModelBinderConfigTest.cs" />
<Compile Include="ModelBinding\Test\SimpleModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\TypeMatchModelBinderProviderTest.cs" />
<Compile Include="ModelBinding\Test\TypeMatchModelBinderTest.cs" />
<Compile Include="ModelBinding\Test\ModelBinderProviderCollectionTest.cs" />
<Compile Include="ModelBinding\Test\ModelBinderUtilTest.cs" />
<Compile Include="ModelBinding\Test\ModelValidationNodeTest.cs" />
<Compile Include="ModelBinding\Test\ModelBinderProvidersTest.cs" />
<Compile Include="Test\ButtonTest.cs" />
<Compile Include="Test\ContentTypeAttributeTest.cs" />
<Compile Include="Test\ControllerExtensionsTest.cs" />
<Compile Include="Test\CookieTempDataProviderTest.cs" />
<Compile Include="Test\AjaxOnlyAttributeTest.cs" />
<Compile Include="Test\AsyncManagerExtensionsTest.cs" />
<Compile Include="Test\CookieValueProviderFactoryTest.cs" />
<Compile Include="Test\CreditCardAttributeTest.cs" />
<Compile Include="Test\DynamicReflectionObjectTest.cs" />
<Compile Include="Test\DynamicViewDataDictionaryTest.cs" />
<Compile Include="Test\DynamicViewPageTest.cs" />
<Compile Include="Test\EmailAddressAttribueTest.cs" />
<Compile Include="Test\FileExtensionsAttributeTest.cs" />
<Compile Include="Test\ModelCopierTest.cs" />
<Compile Include="Test\ElementalValueProviderTest.cs" />
<Compile Include="Test\UrlAttributeTest.cs" />
<Compile Include="Test\ValueProviderUtilTest.cs" />
<Compile Include="Test\TempDataValueProviderFactoryTest.cs" />
<Compile Include="Test\SessionValueProviderFactoryTest.cs" />
<Compile Include="Test\ServerVariablesValueProviderFactoryTest.cs" />
<Compile Include="Test\CopyAsyncParametersAttributeTest.cs" />
<Compile Include="Test\CssExtensionsTests.cs" />
<Compile Include="Test\DeserializeAttributeTest.cs" />
<Compile Include="Test\ScriptExtensionsTest.cs" />
<Compile Include="Test\SerializationExtensionsTest.cs" />
<Compile Include="Test\MvcSerializerTest.cs" />
<Compile Include="Test\ExpressionHelperTest.cs" />
<Compile Include="Test\MailToExtensionsTest.cs" />
<Compile Include="Test\ReaderWriterCacheTest.cs" />
<Compile Include="Test\RenderActionTest.cs" />
<Compile Include="Test\SkipBindingAttributeTest.cs" />
<Compile Include="Test\FormExtensionsTest.cs" />
<Compile Include="Test\RadioExtensionsTest.cs" />
<Compile Include="Test\SubmitImageExtensionsTest.cs" />
<Compile Include="Test\ImageExtensionsTest.cs" />
<Compile Include="Test\SubmitButtonExtensionsTest.cs" />
<Compile Include="Test\TypeHelpersTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Web.Mvc\Microsoft.Web.Mvc.csproj">
<Project>{D3CF7430-6DA4-42B0-BD90-CA39D16687B2}</Project>
<Name>Microsoft.Web.Mvc</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\System.Web.Mvc\System.Web.Mvc.csproj">
<Project>{3D3FFD8A-624D-4E9B-954B-E1C105507975}</Project>
<Name>System.Web.Mvc</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\System.Web.WebPages\System.Web.WebPages.csproj">
<Project>{76EFA9C5-8D7E-4FDF-B710-E20F8B6B00D2}</Project>
<Name>System.Web.WebPages</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.TestCommon\Microsoft.TestCommon.csproj">
<Project>{FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}</Project>
<Name>Microsoft.TestCommon</Name>
</ProjectReference>
<ProjectReference Include="..\System.Web.Mvc.Test\System.Web.Mvc.Test.csproj">
<Project>{8AC2A2E4-2F11-4D40-A887-62E2583A65E6}</Project>
<Name>System.Web.Mvc.Test</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,102 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ArrayModelBinderProviderTest
{
[Fact]
public void GetBinder_CorrectModelTypeAndValueProviderEntries_ReturnsBinder()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
ArrayModelBinderProvider binderProvider = new ArrayModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.IsType<ArrayModelBinder<int>>(binder);
}
[Fact]
public void GetBinder_ModelMetadataReturnsReadOnly_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
bindingContext.ModelMetadata.IsReadOnly = true;
ArrayModelBinderProvider binderProvider = new ArrayModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
[Fact]
public void GetBinder_ModelTypeIsIncorrect_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(ICollection<int>)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
ArrayModelBinderProvider binderProvider = new ArrayModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
[Fact]
public void GetBinder_ValueProviderDoesNotContainPrefix_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider()
};
ArrayModelBinderProvider binderProvider = new ArrayModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
}
}

View File

@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Moq;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ArrayModelBinderTest
{
[Fact]
public void BindModel()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int[])),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider
{
{ "someName[0]", "42" },
{ "someName[1]", "84" }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType);
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, false /* suppressPrefixCheck */);
// Act
bool retVal = new ArrayModelBinder<int>().BindModel(controllerContext, bindingContext);
// Assert
Assert.True(retVal);
int[] array = bindingContext.Model as int[];
Assert.Equal(new[] { 42, 84 }, array);
}
}
}

View File

@@ -0,0 +1,161 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Data.Linq;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class BinaryDataModelBinderProviderTest
{
private static readonly byte[] _base64Bytes = new byte[] { 0x12, 0x20, 0x34, 0x40 };
private const string _base64String = "EiA0QA==";
[Fact]
public void BindModel_BadValue_Fails()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(byte[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo", "not base64 encoded!" }
}
};
BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
bool retVal = binder.BindModel(null, bindingContext);
// Assert
Assert.False(retVal);
}
[Fact]
public void BindModel_EmptyValue_Fails()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(byte[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo", "" }
}
};
BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
bool retVal = binder.BindModel(null, bindingContext);
// Assert
Assert.False(retVal);
}
[Fact]
public void BindModel_GoodValue_ByteArray_Succeeds()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(byte[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo", _base64String }
}
};
BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
bool retVal = binder.BindModel(null, bindingContext);
// Assert
Assert.True(retVal);
Assert.Equal(_base64Bytes, (byte[])bindingContext.Model);
}
[Fact]
public void BindModel_GoodValue_LinqBinary_Succeeds()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(Binary)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo", _base64String }
}
};
BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
bool retVal = binder.BindModel(null, bindingContext);
// Assert
Assert.True(retVal);
Binary binaryModel = Assert.IsType<Binary>(bindingContext.Model);
Assert.Equal(_base64Bytes, binaryModel.ToArray());
}
[Fact]
public void BindModel_NoValue_Fails()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(byte[])),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo.bar", _base64String }
}
};
BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
bool retVal = binder.BindModel(null, bindingContext);
// Assert
Assert.False(retVal);
}
[Fact]
public void GetBinder_WrongModelType_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(object)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo", _base64String }
}
};
BinaryDataModelBinderProvider binderProvider = new BinaryDataModelBinderProvider();
// Act
IExtensibleModelBinder modelBinder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(modelBinder);
}
}
}

View File

@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class BindingBehaviorAttributeTest
{
[Fact]
public void Behavior_Property()
{
// Arrange
BindingBehavior expectedBehavior = (BindingBehavior)(-20);
// Act
BindingBehaviorAttribute attr = new BindingBehaviorAttribute(expectedBehavior);
// Assert
Assert.Equal(expectedBehavior, attr.Behavior);
}
[Fact]
public void TypeId_ReturnsSameValue()
{
// Arrange
BindNeverAttribute neverAttr = new BindNeverAttribute();
BindRequiredAttribute requiredAttr = new BindRequiredAttribute();
// Act & assert
Assert.Same(neverAttr.TypeId, requiredAttr.TypeId);
}
[Fact]
public void BindNever_SetsBehavior()
{
// Act
BindingBehaviorAttribute attr = new BindNeverAttribute();
// Assert
Assert.Equal(BindingBehavior.Never, attr.Behavior);
}
[Fact]
public void BindRequired_SetsBehavior()
{
// Act
BindingBehaviorAttribute attr = new BindRequiredAttribute();
// Assert
Assert.Equal(BindingBehavior.Required, attr.Behavior);
}
}
}

View File

@@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class CollectionModelBinderProviderTest
{
[Fact]
public void GetBinder_CorrectModelTypeAndValueProviderEntries_ReturnsBinder()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IEnumerable<int>)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
CollectionModelBinderProvider binderProvider = new CollectionModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.IsType<CollectionModelBinder<int>>(binder);
}
[Fact]
public void GetBinder_ModelTypeIsIncorrect_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
CollectionModelBinderProvider binderProvider = new CollectionModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
[Fact]
public void GetBinder_ValueProviderDoesNotContainPrefix_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IEnumerable<int>)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider()
};
CollectionModelBinderProvider binderProvider = new CollectionModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
}
}

View File

@@ -0,0 +1,247 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Moq;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class CollectionModelBinderTest
{
[Fact]
public void BindComplexCollectionFromIndexes_FiniteIndexes()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR");
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider
{
{ "someName[foo]", "42" },
{ "someName[baz]", "200" }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType);
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, false /* suppressPrefixCheck */);
// Act
List<int> boundCollection = CollectionModelBinder<int>.BindComplexCollectionFromIndexes(controllerContext, bindingContext, new[] { "foo", "bar", "baz" });
// Assert
Assert.Equal(new[] { 42, 0, 200 }, boundCollection.ToArray());
Assert.Equal(new[] { "someName[foo]", "someName[baz]" }, bindingContext.ValidationNode.ChildNodes.Select(o => o.ModelStateKey).ToArray());
}
[Fact]
public void BindComplexCollectionFromIndexes_InfiniteIndexes()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR");
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider
{
{ "someName[0]", "42" },
{ "someName[1]", "100" },
{ "someName[3]", "400" }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType);
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, false /* suppressPrefixCheck */);
// Act
List<int> boundCollection = CollectionModelBinder<int>.BindComplexCollectionFromIndexes(controllerContext, bindingContext, null /* indexNames */);
// Assert
Assert.Equal(new[] { 42, 100 }, boundCollection.ToArray());
Assert.Equal(new[] { "someName[0]", "someName[1]" }, bindingContext.ValidationNode.ChildNodes.Select(o => o.ModelStateKey).ToArray());
}
[Fact]
public void BindModel_ComplexCollection()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR");
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider
{
{ "someName.index", new[] { "foo", "bar", "baz" } },
{ "someName[foo]", "42" },
{ "someName[bar]", "100" },
{ "someName[baz]", "200" }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType);
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);
CollectionModelBinder<int> modelBinder = new CollectionModelBinder<int>();
// Act
bool retVal = modelBinder.BindModel(controllerContext, bindingContext);
// Assert
Assert.Equal(new[] { 42, 100, 200 }, ((List<int>)bindingContext.Model).ToArray());
}
[Fact]
public void BindModel_SimpleCollection()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR");
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider
{
{ "someName", new[] { "42", "100", "200" } }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType);
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);
CollectionModelBinder<int> modelBinder = new CollectionModelBinder<int>();
// Act
bool retVal = modelBinder.BindModel(controllerContext, bindingContext);
// Assert
Assert.True(retVal);
Assert.Equal(new[] { 42, 100, 200 }, ((List<int>)bindingContext.Model).ToArray());
}
[Fact]
public void BindSimpleCollection_RawValueIsEmptyCollection_ReturnsEmptyList()
{
// Act
List<int> boundCollection = CollectionModelBinder<int>.BindSimpleCollection(null, null, new object[0], null);
// Assert
Assert.NotNull(boundCollection);
Assert.Empty(boundCollection);
}
[Fact]
public void BindSimpleCollection_RawValueIsNull_ReturnsNull()
{
// Act
List<int> boundCollection = CollectionModelBinder<int>.BindSimpleCollection(null, null, null, null);
// Assert
Assert.Null(boundCollection);
}
[Fact]
public void BindSimpleCollection_SubBinderDoesNotExist()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR");
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider()
};
// Act
List<int> boundCollection = CollectionModelBinder<int>.BindSimpleCollection(controllerContext, bindingContext, new int[1], culture);
// Assert
Assert.Equal(new[] { 0 }, boundCollection.ToArray());
Assert.Empty(bindingContext.ValidationNode.ChildNodes);
}
[Fact]
public void BindSimpleCollection_SubBindingSucceeds()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR");
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider()
};
ModelValidationNode childValidationNode = null;
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
Assert.Equal("someName", mbc.ModelName);
childValidationNode = mbc.ValidationNode;
mbc.Model = 42;
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);
// Act
List<int> boundCollection = CollectionModelBinder<int>.BindSimpleCollection(controllerContext, bindingContext, new int[1], culture);
// Assert
Assert.Equal(new[] { 42 }, boundCollection.ToArray());
Assert.Equal(new[] { childValidationNode }, bindingContext.ValidationNode.ChildNodes.ToArray());
}
}
}

View File

@@ -0,0 +1,393 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web.Mvc;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class CollectionModelBinderUtilTest
{
[Fact]
public void CreateOrReplaceCollection_OriginalModelImmutable_CreatesNewInstance()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => new ReadOnlyCollection<int>(new int[0]), typeof(ICollection<int>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceCollection(bindingContext, new[] { 10, 20, 30 }, () => new List<int>());
// Assert
int[] newModel = (bindingContext.Model as ICollection<int>).ToArray();
Assert.Equal(new[] { 10, 20, 30 }, newModel);
}
[Fact]
public void CreateOrReplaceCollection_OriginalModelMutable_UpdatesOriginalInstance()
{
// Arrange
List<int> originalInstance = new List<int> { 10, 20, 30 };
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => originalInstance, typeof(ICollection<int>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceCollection(bindingContext, new[] { 40, 50, 60 }, () => new List<int>());
// Assert
Assert.Same(originalInstance, bindingContext.Model);
Assert.Equal(new[] { 40, 50, 60 }, originalInstance.ToArray());
}
[Fact]
public void CreateOrReplaceCollection_OriginalModelNotCollection_CreatesNewInstance()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(ICollection<int>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceCollection(bindingContext, new[] { 10, 20, 30 }, () => new List<int>());
// Assert
int[] newModel = (bindingContext.Model as ICollection<int>).ToArray();
Assert.Equal(new[] { 10, 20, 30 }, newModel);
}
[Fact]
public void CreateOrReplaceDictionary_DisallowsDuplicateKeys()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(Dictionary<string, int>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceDictionary(
bindingContext,
new[]
{
new KeyValuePair<string, int>("forty-two", 40),
new KeyValuePair<string, int>("forty-two", 2),
new KeyValuePair<string, int>("forty-two", 42)
},
() => new Dictionary<string, int>());
// Assert
IDictionary<string, int> newModel = bindingContext.Model as IDictionary<string, int>;
Assert.Equal(new[] { "forty-two" }, newModel.Keys.ToArray());
Assert.Equal(42, newModel["forty-two"]);
}
[Fact]
public void CreateOrReplaceDictionary_DisallowsNullKeys()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(Dictionary<string, int>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceDictionary(
bindingContext,
new[]
{
new KeyValuePair<string, int>("forty-two", 42),
new KeyValuePair<string, int>(null, 84)
},
() => new Dictionary<string, int>());
// Assert
IDictionary<string, int> newModel = bindingContext.Model as IDictionary<string, int>;
Assert.Equal(new[] { "forty-two" }, newModel.Keys.ToArray());
Assert.Equal(42, newModel["forty-two"]);
}
[Fact]
public void CreateOrReplaceDictionary_OriginalModelImmutable_CreatesNewInstance()
{
// Arrange
ReadOnlyDictionary<string, string> originalModel = new ReadOnlyDictionary<string, string>();
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => originalModel, typeof(IDictionary<string, string>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceDictionary(
bindingContext,
new Dictionary<string, string>
{
{ "Hello", "World" }
},
() => new Dictionary<string, string>());
// Assert
IDictionary<string, string> newModel = bindingContext.Model as IDictionary<string, string>;
Assert.NotSame(originalModel, newModel);
Assert.Equal(new[] { "Hello" }, newModel.Keys.ToArray());
Assert.Equal("World", newModel["Hello"]);
}
[Fact]
public void CreateOrReplaceDictionary_OriginalModelMutable_UpdatesOriginalInstance()
{
// Arrange
Dictionary<string, string> originalInstance = new Dictionary<string, string>
{
{ "dog", "Canidae" },
{ "cat", "Felidae" }
};
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => originalInstance, typeof(IDictionary<string, string>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceDictionary(
bindingContext,
new Dictionary<string, string>
{
{ "horse", "Equidae" },
{ "bear", "Ursidae" }
},
() => new Dictionary<string, string>());
// Assert
Assert.Same(originalInstance, bindingContext.Model);
Assert.Equal(new[] { "horse", "bear" }, originalInstance.Keys.ToArray());
Assert.Equal("Equidae", originalInstance["horse"]);
Assert.Equal("Ursidae", originalInstance["bear"]);
}
[Fact]
public void CreateOrReplaceDictionary_OriginalModelNotDictionary_CreatesNewInstance()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IDictionary<string, string>))
};
// Act
CollectionModelBinderUtil.CreateOrReplaceDictionary(
bindingContext,
new Dictionary<string, string>
{
{ "horse", "Equidae" },
{ "bear", "Ursidae" }
},
() => new Dictionary<string, string>());
// Assert
IDictionary<string, string> newModel = bindingContext.Model as IDictionary<string, string>;
Assert.Equal(new[] { "horse", "bear" }, newModel.Keys.ToArray());
Assert.Equal("Equidae", newModel["horse"]);
Assert.Equal("Ursidae", newModel["bear"]);
}
[Fact]
public void GetIndexNamesFromValueProviderResult_ValueProviderResultIsNull_ReturnsNull()
{
// Act
IEnumerable<string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(null);
// Assert
Assert.Null(indexNames);
}
[Fact]
public void GetIndexNamesFromValueProviderResult_ValueProviderResultReturnsEmptyArray_ReturnsNull()
{
// Arrange
ValueProviderResult vpResult = new ValueProviderResult(new string[0], "", null);
// Act
IEnumerable<string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(vpResult);
// Assert
Assert.Null(indexNames);
}
[Fact]
public void GetIndexNamesFromValueProviderResult_ValueProviderResultReturnsNonEmptyArray_ReturnsArray()
{
// Arrange
ValueProviderResult vpResult = new ValueProviderResult(new[] { "foo", "bar", "baz" }, "foo,bar,baz", null);
// Act
IEnumerable<string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(vpResult);
// Assert
Assert.NotNull(indexNames);
Assert.Equal(new[] { "foo", "bar", "baz" }, indexNames.ToArray());
}
[Fact]
public void GetIndexNamesFromValueProviderResult_ValueProviderResultReturnsNull_ReturnsNull()
{
// Arrange
ValueProviderResult vpResult = new ValueProviderResult(null, null, null);
// Act
IEnumerable<string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(vpResult);
// Assert
Assert.Null(indexNames);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ModelTypeNotGeneric_Fail()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int));
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(null, null, modelMetadata);
// Assert
Assert.Null(typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ModelTypeOpenGeneric_Fail()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IList<>));
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(null, null, modelMetadata);
// Assert
Assert.Null(typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ModelTypeWrongNumberOfGenericArguments_Fail()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>));
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(ICollection<>), null, modelMetadata);
// Assert
Assert.Null(typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ReadOnlyReference_ModelInstanceImmutable_Valid()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => new int[0], typeof(IList<int>));
modelMetadata.IsReadOnly = true;
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(IList<>), typeof(List<>), modelMetadata);
// Assert
Assert.Null(typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ReadOnlyReference_ModelInstanceMutable_Valid()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => new List<int>(), typeof(IList<int>));
modelMetadata.IsReadOnly = true;
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(IList<>), typeof(List<>), modelMetadata);
// Assert
Assert.Equal(new[] { typeof(int) }, typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ReadOnlyReference_ModelInstanceOfWrongType_Fail()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => new HashSet<int>(), typeof(ICollection<int>));
modelMetadata.IsReadOnly = true;
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(IList<>), typeof(List<>), modelMetadata);
// Assert
// HashSet<> is not an IList<>, so we can't update
Assert.Null(typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ReadOnlyReference_ModelIsNull_Fail()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IList<int>));
modelMetadata.IsReadOnly = true;
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(ICollection<>), typeof(List<>), modelMetadata);
// Assert
Assert.Null(typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ReadWriteReference_NewInstanceAssignableToModelType_Success()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IList<int>));
modelMetadata.IsReadOnly = false;
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(ICollection<>), typeof(List<>), modelMetadata);
// Assert
Assert.Equal(new[] { typeof(int) }, typeArguments);
}
[Fact]
public void GetTypeArgumentsForUpdatableGenericCollection_ReadWriteReference_NewInstanceNotAssignableToModelType_MutableInstance_Success()
{
// Arrange
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => new Collection<int>(), typeof(Collection<int>));
modelMetadata.IsReadOnly = false;
// Act
Type[] typeArguments = CollectionModelBinderUtil.GetTypeArgumentsForUpdatableGenericCollection(typeof(ICollection<>), typeof(List<>), modelMetadata);
// Assert
Assert.Equal(new[] { typeof(int) }, typeArguments);
}
[Fact]
public void GetZeroBasedIndexes()
{
// Act
string[] indexes = CollectionModelBinderUtil.GetZeroBasedIndexes().Take(5).ToArray();
// Assert
Assert.Equal(new[] { "0", "1", "2", "3", "4" }, indexes);
}
private class ReadOnlyDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>
{
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
{
get { return true; }
}
}
}
}

View File

@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Web.Mvc;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ComplexModelDtoModelBinderProviderTest
{
[Fact]
public void GetBinder_TypeDoesNotMatch_ReturnsNull()
{
// Arrange
ComplexModelDtoModelBinderProvider provider = new ComplexModelDtoModelBinderProvider();
ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(object));
// Act
IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
[Fact]
public void GetBinder_TypeMatches_ReturnsBinder()
{
// Arrange
ComplexModelDtoModelBinderProvider provider = new ComplexModelDtoModelBinderProvider();
ExtensibleModelBindingContext bindingContext = GetBindingContext(typeof(ComplexModelDto));
// Act
IExtensibleModelBinder binder = provider.GetBinder(null, bindingContext);
// Assert
Assert.IsType<ComplexModelDtoModelBinder>(binder);
}
private static ExtensibleModelBindingContext GetBindingContext(Type modelType)
{
return new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => null, modelType)
};
}
}
}

View File

@@ -0,0 +1,108 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Web.Mvc;
using Moq;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ComplexModelDtoModelBinderTest
{
[Fact]
public void BindModel()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
MyModel model = new MyModel();
ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => model, typeof(MyModel));
ComplexModelDto dto = new ComplexModelDto(modelMetadata, modelMetadata.Properties);
Mock<IExtensibleModelBinder> mockStringBinder = new Mock<IExtensibleModelBinder>();
mockStringBinder
.Setup(b => b.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
Assert.Equal(typeof(string), mbc.ModelType);
Assert.Equal("theModel.StringProperty", mbc.ModelName);
mbc.ValidationNode = new ModelValidationNode(mbc.ModelMetadata, "theModel.StringProperty");
mbc.Model = "someStringValue";
return true;
});
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(b => b.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
Assert.Equal(typeof(int), mbc.ModelType);
Assert.Equal("theModel.IntProperty", mbc.ModelName);
mbc.ValidationNode = new ModelValidationNode(mbc.ModelMetadata, "theModel.IntProperty");
mbc.Model = 42;
return true;
});
Mock<IExtensibleModelBinder> mockDateTimeBinder = new Mock<IExtensibleModelBinder>();
mockDateTimeBinder
.Setup(b => b.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
Assert.Equal(typeof(DateTime), mbc.ModelType);
Assert.Equal("theModel.DateTimeProperty", mbc.ModelName);
return false;
});
ModelBinderProviderCollection binders = new ModelBinderProviderCollection();
binders.RegisterBinderForType(typeof(string), mockStringBinder.Object, true /* suppressPrefixCheck */);
binders.RegisterBinderForType(typeof(int), mockIntBinder.Object, true /* suppressPrefixCheck */);
binders.RegisterBinderForType(typeof(DateTime), mockDateTimeBinder.Object, true /* suppressPrefixCheck */);
ExtensibleModelBindingContext parentBindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => dto, typeof(ComplexModelDto)),
ModelName = "theModel",
ModelBinderProviders = binders
};
ComplexModelDtoModelBinder binder = new ComplexModelDtoModelBinder();
// Act
bool retVal = binder.BindModel(controllerContext, parentBindingContext);
// Assert
Assert.True(retVal);
Assert.Equal(dto, parentBindingContext.Model);
ComplexModelDtoResult stringDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(string)).First()];
Assert.Equal("someStringValue", stringDtoResult.Model);
Assert.Equal("theModel.StringProperty", stringDtoResult.ValidationNode.ModelStateKey);
ComplexModelDtoResult intDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(int)).First()];
Assert.Equal(42, intDtoResult.Model);
Assert.Equal("theModel.IntProperty", intDtoResult.ValidationNode.ModelStateKey);
ComplexModelDtoResult dateTimeDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(DateTime)).First()];
Assert.Null(dateTimeDtoResult);
}
private static ModelBindingContext GetBindingContext(Type modelType)
{
return new ModelBindingContext
{
ModelMetadata = new ModelMetadata(new Mock<ModelMetadataProvider>().Object, null, null, modelType, "SomeProperty")
};
}
private sealed class MyModel
{
public string StringProperty { get; set; }
public int IntProperty { get; set; }
public object ObjectProperty { get; set; } // no binding should happen since no registered binder
public DateTime DateTimeProperty { get; set; } // registered binder returns false
}
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Mvc;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ComplexModelDtoResultTest
{
[Fact]
public void Constructor_ThrowsIfValidationNodeIsNull()
{
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ComplexModelDtoResult("some string", null); }, "validationNode");
}
[Fact]
public void Constructor_SetsProperties()
{
// Arrange
ModelValidationNode validationNode = GetValidationNode();
// Act
ComplexModelDtoResult result = new ComplexModelDtoResult("some string", validationNode);
// Assert
Assert.Equal("some string", result.Model);
Assert.Equal(validationNode, result.ValidationNode);
}
private static ModelValidationNode GetValidationNode()
{
EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider();
ModelMetadata metadata = provider.GetMetadataForType(null, typeof(object));
return new ModelValidationNode(metadata, "someKey");
}
}
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Linq;
using System.Web.Mvc;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ComplexModelDtoTest
{
[Fact]
public void ConstructorThrowsIfModelMetadataIsNull()
{
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ComplexModelDto(null, Enumerable.Empty<ModelMetadata>()); }, "modelMetadata");
}
[Fact]
public void ConstructorThrowsIfPropertyMetadataIsNull()
{
// Arrange
ModelMetadata modelMetadata = GetModelMetadata();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ComplexModelDto(modelMetadata, null); }, "propertyMetadata");
}
[Fact]
public void ConstructorSetsProperties()
{
// Arrange
ModelMetadata modelMetadata = GetModelMetadata();
ModelMetadata[] propertyMetadata = new ModelMetadata[0];
// Act
ComplexModelDto dto = new ComplexModelDto(modelMetadata, propertyMetadata);
// Assert
Assert.Equal(modelMetadata, dto.ModelMetadata);
Assert.Equal(propertyMetadata, dto.PropertyMetadata.ToArray());
Assert.Empty(dto.Results);
}
private static ModelMetadata GetModelMetadata()
{
return new ModelMetadata(new EmptyModelMetadataProvider(), typeof(object), null, typeof(object), "PropertyName");
}
}
}

View File

@@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class DictionaryModelBinderProviderTest
{
[Fact]
public void GetBinder_CorrectModelTypeAndValueProviderEntries_ReturnsBinder()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IDictionary<int, string>)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
DictionaryModelBinderProvider binderProvider = new DictionaryModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.IsType<DictionaryModelBinder<int, string>>(binder);
}
[Fact]
public void GetBinder_ModelTypeIsIncorrect_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider
{
{ "foo[0]", "42" },
}
};
DictionaryModelBinderProvider binderProvider = new DictionaryModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
[Fact]
public void GetBinder_ValueProviderDoesNotContainPrefix_ReturnsNull()
{
// Arrange
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IDictionary<int, string>)),
ModelName = "foo",
ValueProvider = new SimpleValueProvider()
};
DictionaryModelBinderProvider binderProvider = new DictionaryModelBinderProvider();
// Act
IExtensibleModelBinder binder = binderProvider.GetBinder(null, bindingContext);
// Assert
Assert.Null(binder);
}
}
}

View File

@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Moq;
using Xunit;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class DictionaryModelBinderTest
{
[Fact]
public void BindModel()
{
// Arrange
ControllerContext controllerContext = new ControllerContext();
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(IDictionary<int, string>)),
ModelName = "someName",
ModelBinderProviders = new ModelBinderProviderCollection(),
ValueProvider = new SimpleValueProvider
{
{ "someName[0]", new KeyValuePair<int, string>(42, "forty-two") },
{ "someName[1]", new KeyValuePair<int, string>(84, "eighty-four") }
}
};
Mock<IExtensibleModelBinder> mockKvpBinder = new Mock<IExtensibleModelBinder>();
mockKvpBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
mbc.Model = mbc.ValueProvider.GetValue(mbc.ModelName).ConvertTo(mbc.ModelType);
return true;
});
bindingContext.ModelBinderProviders.RegisterBinderForType(typeof(KeyValuePair<int, string>), mockKvpBinder.Object, false /* suppressPrefixCheck */);
// Act
bool retVal = new DictionaryModelBinder<int, string>().BindModel(controllerContext, bindingContext);
// Assert
Assert.True(retVal);
var dictionary = Assert.IsAssignableFrom<IDictionary<int, string>>(bindingContext.Model);
Assert.NotNull(dictionary);
Assert.Equal(2, dictionary.Count);
Assert.Equal("forty-two", dictionary[42]);
Assert.Equal("eighty-four", dictionary[84]);
}
}
}

View File

@@ -0,0 +1,212 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Web.UnitTestUtil;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace Microsoft.Web.Mvc.ModelBinding.Test
{
public class ExtensibleModelBinderAdapterTest
{
[Fact]
public void BindModel_PropertyFilterIsSet_Throws()
{
// Arrange
ControllerContext controllerContext = GetControllerContext();
ModelBindingContext bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = true,
ModelMetadata = new DataAnnotationsModelMetadataProvider().GetMetadataForType(null, typeof(SimpleModel)),
PropertyFilter = (new BindAttribute { Include = "FirstName " }).IsPropertyAllowed
};
ModelBinderProviderCollection binderProviders = new ModelBinderProviderCollection();
ExtensibleModelBinderAdapter shimBinder = new ExtensibleModelBinderAdapter(binderProviders);
// Act & assert
Assert.Throws<InvalidOperationException>(
delegate { shimBinder.BindModel(controllerContext, bindingContext); },
@"The new model binding system cannot be used when a property whitelist or blacklist has been specified in [Bind] or via the call to UpdateModel() / TryUpdateModel(). Use the [BindRequired] and [BindNever] attributes on the model type or its properties instead.");
}
[Fact]
public void BindModel_SuccessfulBind_RunsValidationAndReturnsModel()
{
// Arrange
ControllerContext controllerContext = GetControllerContext();
bool validationCalled = false;
ModelBindingContext bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = true,
ModelMetadata = new DataAnnotationsModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelName = "someName",
ModelState = controllerContext.Controller.ViewData.ModelState,
PropertyFilter = _ => true,
ValueProvider = new SimpleValueProvider
{
{ "someName", "dummyValue" }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata);
Assert.Equal("someName", mbc.ModelName);
Assert.Same(bindingContext.ValueProvider, mbc.ValueProvider);
mbc.Model = 42;
mbc.ValidationNode.Validating += delegate { validationCalled = true; };
return true;
});
ModelBinderProviderCollection binderProviders = new ModelBinderProviderCollection();
binderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, false /* suppressPrefixCheck */);
ExtensibleModelBinderAdapter shimBinder = new ExtensibleModelBinderAdapter(binderProviders);
// Act
object retVal = shimBinder.BindModel(controllerContext, bindingContext);
// Assert
Assert.Equal(42, retVal);
Assert.True(validationCalled);
Assert.True(bindingContext.ModelState.IsValid);
}
[Fact]
public void BindModel_SuccessfulBind_ComplexTypeFallback_RunsValidationAndReturnsModel()
{
// Arrange
ControllerContext controllerContext = GetControllerContext();
bool validationCalled = false;
List<int> expectedModel = new List<int> { 1, 2, 3, 4, 5 };
ModelBindingContext bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = true,
ModelMetadata = new DataAnnotationsModelMetadataProvider().GetMetadataForType(null, typeof(List<int>)),
ModelName = "someName",
ModelState = controllerContext.Controller.ViewData.ModelState,
PropertyFilter = _ => true,
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
}
};
Mock<IExtensibleModelBinder> mockIntBinder = new Mock<IExtensibleModelBinder>();
mockIntBinder
.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>()))
.Returns(
delegate(ControllerContext cc, ExtensibleModelBindingContext mbc)
{
Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata);
Assert.Equal("", mbc.ModelName);
Assert.Same(bindingContext.ValueProvider, mbc.ValueProvider);
mbc.Model = expectedModel;
mbc.ValidationNode.Validating += delegate { validationCalled = true; };
return true;
});
ModelBinderProviderCollection binderProviders = new ModelBinderProviderCollection();
binderProviders.RegisterBinderForType(typeof(List<int>), mockIntBinder.Object, false /* suppressPrefixCheck */);
ExtensibleModelBinderAdapter shimBinder = new ExtensibleModelBinderAdapter(binderProviders);
// Act
object retVal = shimBinder.BindModel(controllerContext, bindingContext);
// Assert
Assert.Equal(expectedModel, retVal);
Assert.True(validationCalled);
Assert.True(bindingContext.ModelState.IsValid);
}
[Fact]
public void BindModel_UnsuccessfulBind_BinderFails_ReturnsNull()
{
// Arrange
ControllerContext controllerContext = GetControllerContext();
Mock<IExtensibleModelBinder> mockListBinder = new Mock<IExtensibleModelBinder>();
mockListBinder.Setup(o => o.BindModel(controllerContext, It.IsAny<ExtensibleModelBindingContext>())).Returns(false).Verifiable();
ModelBinderProviderCollection binderProviders = new ModelBinderProviderCollection();
binderProviders.RegisterBinderForType(typeof(List<int>), mockListBinder.Object, true /* suppressPrefixCheck */);
ExtensibleModelBinderAdapter shimBinder = new ExtensibleModelBinderAdapter(binderProviders);
ModelBindingContext bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = false,
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(List<int>)),
ModelState = controllerContext.Controller.ViewData.ModelState
};
// Act
object retVal = shimBinder.BindModel(controllerContext, bindingContext);
// Assert
Assert.Null(retVal);
Assert.True(bindingContext.ModelState.IsValid);
mockListBinder.Verify();
}
[Fact]
public void BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNull()
{
// Arrange
ControllerContext controllerContext = GetControllerContext();
Mock<ModelBinderProvider> mockBinderProvider = new Mock<ModelBinderProvider>();
mockBinderProvider.Setup(o => o.GetBinder(controllerContext, It.IsAny<ExtensibleModelBindingContext>())).Returns((IExtensibleModelBinder)null).Verifiable();
ModelBinderProviderCollection binderProviders = new ModelBinderProviderCollection
{
mockBinderProvider.Object
};
ExtensibleModelBinderAdapter shimBinder = new ExtensibleModelBinderAdapter(binderProviders);
ModelBindingContext bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = true,
ModelMetadata = new DataAnnotationsModelMetadataProvider().GetMetadataForType(null, typeof(int)),
ModelState = controllerContext.Controller.ViewData.ModelState
};
// Act
object retVal = shimBinder.BindModel(controllerContext, bindingContext);
// Assert
Assert.Null(retVal);
Assert.True(bindingContext.ModelState.IsValid);
mockBinderProvider.Verify();
mockBinderProvider.Verify(o => o.GetBinder(controllerContext, It.IsAny<ExtensibleModelBindingContext>()), Times.AtMostOnce());
}
private static ControllerContext GetControllerContext()
{
return new ControllerContext
{
Controller = new SimpleController()
};
}
private class SimpleController : Controller
{
}
private class SimpleModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
}

Some files were not shown because too many files have changed in this diff Show More