diff --git a/Mvc.sln b/Mvc.sln
index fd2508e6b0..e476c49ffc 100644
--- a/Mvc.sln
+++ b/Mvc.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.21916.0
+VisualStudioVersion = 14.0.21902.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
EndProject
@@ -61,6 +61,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Header
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.HeaderValueAbstractions.Tests", "test\Microsoft.AspNet.Mvc.HeaderValueAbstractions.Test\Microsoft.AspNet.Mvc.HeaderValueAbstractions.Tests.kproj", "{E69FD235-2042-43A4-9970-59CB29955B4E}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ModelBindingWebSite", "test\WebSites\ModelBindingWebSite\ModelBindingWebSite.kproj", "{EE1AB716-F102-4CA3-AD2C-214A44B459A0}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}"
ProjectSection(SolutionItems) = preProject
global.json = global.json
@@ -328,6 +330,16 @@ Global
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|x86.ActiveCfg = Release|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Release|x86.ActiveCfg = Release|Any CPU
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -379,6 +391,7 @@ Global
{14F79E79-AE79-48FA-95DE-D794EF4EABB3} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{98335B23-E4B9-4CAD-9749-0DED32A659A1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{E69FD235-2042-43A4-9970-59CB29955B4E} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
+ {EE1AB716-F102-4CA3-AD2C-214A44B459A0} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{A353B17E-A940-4CE8-8BF9-179E24A9041F} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
EndGlobalSection
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/ByteArrayModelBinder.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/ByteArrayModelBinder.cs
new file mode 100644
index 0000000000..d34f32ffa3
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/ByteArrayModelBinder.cs
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Mvc.ModelBinding.Internal;
+
+namespace Microsoft.AspNet.Mvc.ModelBinding
+{
+ ///
+ /// ModelBinder to bind Byte Arrays.
+ ///
+ public class ByteArrayModelBinder : IModelBinder
+ {
+ ///
+ public async Task BindModelAsync([NotNull] ModelBindingContext bindingContext)
+ {
+ if (bindingContext.ModelType != typeof(byte[]))
+ {
+ return false;
+ }
+
+ var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
+
+ // case 1: there was no element containing this data
+ if (valueProviderResult == null)
+ {
+ return false;
+ }
+
+ var value = valueProviderResult.AttemptedValue;
+
+ // case 2: there was an element but it was left blank
+ if (string.IsNullOrEmpty(value))
+ {
+ return false;
+ }
+
+ try
+ {
+ bindingContext.Model = Convert.FromBase64String(value);
+ }
+ catch (Exception ex)
+ {
+ ModelBindingHelper.AddModelErrorBasedOnExceptionType(bindingContext, ex);
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/IModelBinder.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/IModelBinder.cs
index 301f36b43d..538110dc17 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/IModelBinder.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/IModelBinder.cs
@@ -10,6 +10,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
///
public interface IModelBinder
{
+ ///
+ /// Async function to bind to a particular model.
+ ///
+ /// The binding context which has the object to be bound.
+ /// A Task with a bool implying the success or failure of the operation.
Task BindModelAsync(ModelBindingContext bindingContext);
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/TypeConverterModelBinder.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/TypeConverterModelBinder.cs
index a5461d9781..7e2edc9f9a 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/TypeConverterModelBinder.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/TypeConverterModelBinder.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
@@ -36,30 +35,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
}
catch (Exception ex)
{
- if (IsFormatException(ex))
- {
- // there was a type conversion failure
- bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
- }
- else
- {
- bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
- }
+ ModelBindingHelper.AddModelErrorBasedOnExceptionType(bindingContext, ex);
}
return true;
}
-
- private static bool IsFormatException(Exception ex)
- {
- for (; ex != null; ex = ex.InnerException)
- {
- if (ex is FormatException)
- {
- return true;
- }
- }
- return false;
- }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Internal/ModelBindingHelper.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Internal/ModelBindingHelper.cs
index c3b384b36d..6f34b42c59 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Internal/ModelBindingHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Internal/ModelBindingHelper.cs
@@ -93,5 +93,29 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Internal
throw new ArgumentException(message, "bindingContext");
}
}
+
+ internal static void AddModelErrorBasedOnExceptionType(ModelBindingContext bindingContext, Exception ex)
+ {
+ if (IsFormatException(ex))
+ {
+ bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
+ }
+ else
+ {
+ bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
+ }
+ }
+
+ internal static bool IsFormatException(Exception ex)
+ {
+ for (; ex != null; ex = ex.InnerException)
+ {
+ if (ex is FormatException)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj b/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj
index 9583a0b71a..629617a20c 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj
@@ -26,6 +26,7 @@
+
diff --git a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs
index 9b100ddb73..cf4d6cd29b 100644
--- a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs
+++ b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs
@@ -28,6 +28,7 @@ namespace Microsoft.AspNet.Mvc
// Set up ModelBinding
options.ModelBinders.Add(new TypeConverterModelBinder());
options.ModelBinders.Add(new TypeMatchModelBinder());
+ options.ModelBinders.Add(new ByteArrayModelBinder());
options.ModelBinders.Add(typeof(GenericModelBinder));
options.ModelBinders.Add(new MutableObjectModelBinder());
options.ModelBinders.Add(new ComplexModelDtoModelBinder());
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj b/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj
index c2a93aa2c1..6cb7fc3c3c 100644
--- a/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj
@@ -33,6 +33,7 @@
+
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/ModelBindingTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/ModelBindingTests.cs
new file mode 100644
index 0000000000..c7431bb341
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/ModelBindingTests.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Builder;
+using Microsoft.AspNet.TestHost;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.FunctionalTests
+{
+ public class ModelBindingTests
+ {
+ private readonly IServiceProvider _services;
+ private readonly Action _app = new ModelBindingWebSite.Startup().Configure;
+
+ public ModelBindingTests()
+ {
+ _services = TestHelper.CreateServices("ModelBindingWebSite");
+ }
+
+ [Fact]
+ public async Task ModelBindingBindsBase64StringsToByteArrays()
+ {
+ // Arrange
+ var server = TestServer.Create(_services, _app);
+ var client = server.Handler;
+
+ // Act
+ var response = await client.GetAsync("http://localhost/Home/Index?byteValues=SGVsbG9Xb3JsZA==");
+
+ //Assert
+ Assert.Equal(200, response.StatusCode);
+ Assert.Equal("HelloWorld", await response.ReadBodyAsStringAsync());
+ }
+
+ [Fact]
+ public async Task ModelBindingBindsEmptyStringsToByteArrays()
+ {
+ // Arrange
+ var server = TestServer.Create(_services, _app);
+ var client = server.Handler;
+
+ // Act
+ var response = await client.GetAsync("http://localhost/Home/Index?byteValues=");
+
+ //Assert
+ Assert.Equal(200, response.StatusCode);
+ Assert.Equal("\0", await response.ReadBodyAsStringAsync());
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json
index 79163665b7..0c2ee64a2e 100644
--- a/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/project.json
@@ -19,6 +19,7 @@
"Microsoft.Framework.Logging": "1.0.0-*",
"Microsoft.Framework.Runtime.Interfaces": "1.0.0-*",
"Microsoft.AspNet.PipelineCore": "1.0.0-*",
+ "ModelBindingWebSite": "",
"RoutingWebSite": "",
"RazorWebSite": "",
"ValueProvidersSite": "",
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/ByteArrayModelBinderTests.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/ByteArrayModelBinderTests.cs
new file mode 100644
index 0000000000..ddad1ae23f
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/ByteArrayModelBinderTests.cs
@@ -0,0 +1,128 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+#if NET45
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.ModelBinding.Test
+{
+ public class ByteArrayModelBinderTests
+ {
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ public async Task BindModelSetsModelToNullOnNullOrEmptyString(string value)
+ {
+ // Arrange
+ var valueProvider = new SimpleHttpValueProvider()
+ {
+ { "foo", value }
+ };
+
+ var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
+ var binder = new ByteArrayModelBinder();
+
+ // Act
+ var binderResult = await binder.BindModelAsync(bindingContext);
+
+ // Assert
+ Assert.False(binderResult);
+ Assert.Null(bindingContext.Model);
+ }
+
+ [Fact]
+ public async Task BindModel()
+ {
+ // Arrange
+ var valueProvider = new SimpleHttpValueProvider()
+ {
+ { "foo", "Fys1" }
+ };
+
+ var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
+ var binder = new ByteArrayModelBinder();
+
+ // Act
+ var binderResult = await binder.BindModelAsync(bindingContext);
+
+ // Assert
+ Assert.True(binderResult);
+ var bytes = Assert.IsType(bindingContext.Model);
+ Assert.Equal(new byte[] { 23, 43, 53 }, bytes);
+ }
+
+ [Fact]
+ public async Task BindModelAddsModelErrorsOnInvalidCharacters()
+ {
+ // Arrange
+ var valueProvider = new SimpleHttpValueProvider()
+ {
+ { "foo", "\"Fys1\"" }
+ };
+
+ var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
+ var binder = new ByteArrayModelBinder();
+
+ // Act
+ var binderResult = await binder.BindModelAsync(bindingContext);
+
+ // Assert
+ Assert.True(binderResult);
+ Assert.False(bindingContext.ModelState.IsValid);
+ Assert.Equal(1, bindingContext.ModelState.Values.Count);
+ Assert.Equal("The input is not a valid Base-64 string as it contains a non-base 64 character," +
+ " more than two padding characters, or an illegal character among the padding characters. ",
+ bindingContext.ModelState.Values.First().Errors[0].ErrorMessage);
+ }
+
+ [Fact]
+ public async Task BindModelReturnsFalseWhenValueNotFound()
+ {
+ // Arrange
+ var valueProvider = new SimpleHttpValueProvider()
+ {
+ { "someName", "" }
+ };
+
+ var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
+ var binder = new ByteArrayModelBinder();
+
+ // Act
+ var binderResult = await binder.BindModelAsync(bindingContext);
+
+ // Assert
+ Assert.False(binderResult);
+ }
+
+ [Fact]
+ public async Task ByteArrayModelBinderReturnsFalseForOtherTypes()
+ {
+ // Arrange
+ var bindingContext = GetBindingContext(null, typeof(int[]));
+ var binder = new ByteArrayModelBinder();
+
+ // Act
+ var binderResult = await binder.BindModelAsync(bindingContext);
+
+ // Assert
+ Assert.False(binderResult);
+ }
+
+ private static ModelBindingContext GetBindingContext(IValueProvider valueProvider, Type modelType)
+ {
+ var metadataProvider = new EmptyModelMetadataProvider();
+ var bindingContext = new ModelBindingContext
+ {
+ ModelMetadata = metadataProvider.GetMetadataForType(null, modelType),
+ ModelName = "foo",
+ ValueProvider = valueProvider,
+ MetadataProvider = metadataProvider
+ };
+ return bindingContext;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs
index bd8a8184f4..91a0bc4449 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs
@@ -200,6 +200,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ "friends[0].friends[0].firstname", "nested friend"},
{ "friends[1].firstName", "some other"},
{ "friends[1].lastName", "name"},
+ { "resume", "4+mFeTp3tPF=" }
};
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person));
@@ -218,6 +219,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
Assert.Equal("nested friend", nestedFriend.FirstName);
Assert.Equal("some other", model.Friends[1].FirstName);
Assert.Equal("name", model.Friends[1].LastName);
+ Assert.Equal(new byte[] { 227, 233, 133, 121, 58, 119, 180, 241 }, model.Resume);
}
[Fact]
@@ -294,6 +296,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var binders = new IModelBinder[]
{
new TypeMatchModelBinder(),
+ new ByteArrayModelBinder(),
new GenericModelBinder(serviceProvider, typeActivator.Object),
new ComplexModelDtoModelBinder(),
new TypeConverterModelBinder(),
@@ -331,6 +334,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public int Age { get; set; }
public List Friends { get; set; }
+
+ public byte[] Resume { get; set; }
}
private class User : IValidatableObject
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Microsoft.AspNet.Mvc.ModelBinding.Test.kproj b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Microsoft.AspNet.Mvc.ModelBinding.Test.kproj
index 2c0f04de8f..5caee71a58 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Microsoft.AspNet.Mvc.ModelBinding.Test.kproj
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Microsoft.AspNet.Mvc.ModelBinding.Test.kproj
@@ -23,6 +23,7 @@
+
diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs
index 2674329afc..39a37485d1 100644
--- a/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs
@@ -35,12 +35,13 @@ namespace Microsoft.AspNet.Mvc
setup.Setup(mvcOptions);
// Assert
- Assert.Equal(5, mvcOptions.ModelBinders.Count);
+ Assert.Equal(6, mvcOptions.ModelBinders.Count);
Assert.Equal(typeof(TypeConverterModelBinder), mvcOptions.ModelBinders[0].OptionType);
Assert.Equal(typeof(TypeMatchModelBinder), mvcOptions.ModelBinders[1].OptionType);
- Assert.Equal(typeof(GenericModelBinder), mvcOptions.ModelBinders[2].OptionType);
- Assert.Equal(typeof(MutableObjectModelBinder), mvcOptions.ModelBinders[3].OptionType);
- Assert.Equal(typeof(ComplexModelDtoModelBinder), mvcOptions.ModelBinders[4].OptionType);
+ Assert.Equal(typeof(ByteArrayModelBinder), mvcOptions.ModelBinders[2].OptionType);
+ Assert.Equal(typeof(GenericModelBinder), mvcOptions.ModelBinders[3].OptionType);
+ Assert.Equal(typeof(MutableObjectModelBinder), mvcOptions.ModelBinders[4].OptionType);
+ Assert.Equal(typeof(ComplexModelDtoModelBinder), mvcOptions.ModelBinders[5].OptionType);
}
[Fact]
diff --git a/test/WebSites/ModelBindingWebSite/Controllers/HomeController.cs b/test/WebSites/ModelBindingWebSite/Controllers/HomeController.cs
new file mode 100644
index 0000000000..b4abf7e023
--- /dev/null
+++ b/test/WebSites/ModelBindingWebSite/Controllers/HomeController.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Mvc;
+
+namespace ModelBindingWebSite.Controllers
+{
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index(byte[] byteValues)
+ {
+ return Content(System.Text.Encoding.UTF8.GetString(byteValues));
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/WebSites/ModelBindingWebSite/ModelBindingWebSite.kproj b/test/WebSites/ModelBindingWebSite/ModelBindingWebSite.kproj
new file mode 100644
index 0000000000..113f6d6c2f
--- /dev/null
+++ b/test/WebSites/ModelBindingWebSite/ModelBindingWebSite.kproj
@@ -0,0 +1,39 @@
+
+
+
+ 12.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+ Debug
+ AnyCPU
+
+
+
+ ee1ab716-f102-4ca3-ad2c-214a44b459a0
+ Web
+
+
+ ConsoleDebugger
+
+
+ WebDebugger
+
+
+
+
+ 2.0
+
+
+ 38820
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/WebSites/ModelBindingWebSite/Startup.cs b/test/WebSites/ModelBindingWebSite/Startup.cs
new file mode 100644
index 0000000000..84b80ee479
--- /dev/null
+++ b/test/WebSites/ModelBindingWebSite/Startup.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Routing;
+using Microsoft.Framework.DependencyInjection;
+
+namespace ModelBindingWebSite
+{
+ public class Startup
+ {
+ public void Configure(IBuilder app)
+ {
+ var configuration = app.GetTestConfiguration();
+
+ // Set up application services
+ app.UseServices(services =>
+ {
+ // Add MVC services to the services container
+ services.AddMvc(configuration);
+ });
+
+ // Add MVC to the request pipeline
+ app.UseMvc(routes =>
+ {
+ routes.MapRoute("ActionAsMethod", "{controller}/{action}",
+ defaults: new { controller = "Home", action = "Index" });
+
+ });
+ }
+ }
+}
diff --git a/test/WebSites/ModelBindingWebSite/project.json b/test/WebSites/ModelBindingWebSite/project.json
new file mode 100644
index 0000000000..7c0d0637ed
--- /dev/null
+++ b/test/WebSites/ModelBindingWebSite/project.json
@@ -0,0 +1,10 @@
+{
+ "dependencies": {
+ "Microsoft.AspNet.Mvc": "",
+ "Microsoft.AspNet.Mvc.TestConfiguration": ""
+ },
+ "configurations": {
+ "net45": { },
+ "k10": { }
+ }
+}