Adding a context class for ValueProviderFactories
This allows model binding to once again be independent of routing. Sending RouteContext into model binding was an odd choice from a layering point-of-view.
This commit is contained in:
parent
44ed23f65e
commit
7f34c94de7
|
|
@ -33,9 +33,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
public Task<ActionBindingContext> GetActionBindingContextAsync(ActionContext actionContext)
|
public Task<ActionBindingContext> GetActionBindingContextAsync(ActionContext actionContext)
|
||||||
{
|
{
|
||||||
var routeContext = new RouteContext(actionContext.HttpContext);
|
var factoryContext = new ValueProviderFactoryContext(
|
||||||
routeContext.RouteData = actionContext.RouteData;
|
actionContext.HttpContext,
|
||||||
var valueProviders = _valueProviderFactories.Select(factory => factory.GetValueProvider(routeContext))
|
actionContext.RouteData.Values);
|
||||||
|
|
||||||
|
var valueProviders = _valueProviderFactories.Select(factory => factory.GetValueProvider(factoryContext))
|
||||||
.Where(vp => vp != null);
|
.Where(vp => vp != null);
|
||||||
var context = new ActionBindingContext(
|
var context = new ActionBindingContext(
|
||||||
actionContext,
|
actionContext,
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@
|
||||||
<Compile Include="ValueProviders\QueryStringValueProviderFactory.cs" />
|
<Compile Include="ValueProviders\QueryStringValueProviderFactory.cs" />
|
||||||
<Compile Include="ValueProviders\ReadableStringCollectionValueProvider.cs" />
|
<Compile Include="ValueProviders\ReadableStringCollectionValueProvider.cs" />
|
||||||
<Compile Include="ValueProviders\RouteValueValueProviderFactory.cs" />
|
<Compile Include="ValueProviders\RouteValueValueProviderFactory.cs" />
|
||||||
|
<Compile Include="ValueProviders\ValueProviderFactoryContext.cs" />
|
||||||
<Compile Include="ValueProviders\ValueProviderResult.cs" />
|
<Compile Include="ValueProviders\ValueProviderResult.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -12,9 +11,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
private const string FormEncodedContentType = "application/x-www-form-urlencoded";
|
private const string FormEncodedContentType = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
public IValueProvider GetValueProvider([NotNull] RouteContext routeContext)
|
public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context)
|
||||||
{
|
{
|
||||||
var request = routeContext.HttpContext.Request;
|
var request = context.HttpContext.Request;
|
||||||
|
|
||||||
if (IsSupportedContentType(request))
|
if (IsSupportedContentType(request))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Routing;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public interface IValueProviderFactory
|
public interface IValueProviderFactory
|
||||||
|
|
@ -10,8 +8,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a value provider with values from the given <paramref name="requestContext"/>.
|
/// Get a value provider with values from the given <paramref name="requestContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="routeContext">RouteContext that value provider will populate from</param>
|
/// <param name="context">ValueProviderFactoryContext that value provider will populate from</param>
|
||||||
/// <returns>a value provider instance or null</returns>
|
/// <returns>a value provider instance or null</returns>
|
||||||
IValueProvider GetValueProvider([NotNull] RouteContext routeContext);
|
IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// 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.Globalization;
|
||||||
using Microsoft.AspNet.Routing;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -10,15 +9,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
private static readonly object _cacheKey = new object();
|
private static readonly object _cacheKey = new object();
|
||||||
|
|
||||||
public IValueProvider GetValueProvider([NotNull] RouteContext routeContext)
|
public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context)
|
||||||
{
|
{
|
||||||
// Process the query collection once-per request.
|
// Process the query collection once-per request.
|
||||||
var storage = routeContext.HttpContext.Items;
|
var storage = context.HttpContext.Items;
|
||||||
object value;
|
object value;
|
||||||
IValueProvider provider;
|
IValueProvider provider;
|
||||||
if (!storage.TryGetValue(_cacheKey, out value))
|
if (!storage.TryGetValue(_cacheKey, out value))
|
||||||
{
|
{
|
||||||
var queryCollection = routeContext.HttpContext.Request.Query;
|
var queryCollection = context.HttpContext.Request.Query;
|
||||||
provider = new ReadableStringCollectionValueProvider(queryCollection, CultureInfo.InvariantCulture);
|
provider = new ReadableStringCollectionValueProvider(queryCollection, CultureInfo.InvariantCulture);
|
||||||
storage[_cacheKey] = provider;
|
storage[_cacheKey] = provider;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Routing;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public class RouteValueValueProviderFactory : IValueProviderFactory
|
public class RouteValueValueProviderFactory : IValueProviderFactory
|
||||||
{
|
{
|
||||||
public IValueProvider GetValueProvider([NotNull] RouteContext routeContext)
|
public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context)
|
||||||
{
|
{
|
||||||
return new DictionaryBasedValueProvider(routeContext.RouteData.Values);
|
return new DictionaryBasedValueProvider(context.RouteValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// 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.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
{
|
||||||
|
public class ValueProviderFactoryContext
|
||||||
|
{
|
||||||
|
public ValueProviderFactoryContext(
|
||||||
|
[NotNull] HttpContext httpContext,
|
||||||
|
[NotNull] IDictionary<string, object> routeValues)
|
||||||
|
{
|
||||||
|
HttpContext = httpContext;
|
||||||
|
RouteValues = routeValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpContext HttpContext { get; private set; }
|
||||||
|
|
||||||
|
public IDictionary<string, object> RouteValues { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Http": "0.1-alpha-*",
|
"Microsoft.AspNet.Http": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Mvc.Common": "",
|
"Microsoft.AspNet.Mvc.Common": "",
|
||||||
"Microsoft.AspNet.Routing": "0.1-alpha-*",
|
|
||||||
"Microsoft.DataAnnotations": "0.1-alpha-*",
|
"Microsoft.DataAnnotations": "0.1-alpha-*",
|
||||||
"Microsoft.Framework.DependencyInjection": "0.1-alpha-*",
|
"Microsoft.Framework.DependencyInjection": "0.1-alpha-*",
|
||||||
"Newtonsoft.Json": "5.0.8"
|
"Newtonsoft.Json": "5.0.8"
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
public void GetValueProvider_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded()
|
public void GetValueProvider_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var requestContext = CreateRequestContext("some-content-type");
|
var context = CreateContext("some-content-type");
|
||||||
var factory = new FormValueProviderFactory();
|
var factory = new FormValueProviderFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = factory.GetValueProvider(requestContext);
|
var result = factory.GetValueProvider(context);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(result);
|
Assert.Null(result);
|
||||||
|
|
@ -35,18 +35,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
public void GetValueProvider_ReturnsValueProviderInstaceWithInvariantCulture(string contentType)
|
public void GetValueProvider_ReturnsValueProviderInstaceWithInvariantCulture(string contentType)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var requestContext = CreateRequestContext(contentType);
|
var context = CreateContext(contentType);
|
||||||
var factory = new FormValueProviderFactory();
|
var factory = new FormValueProviderFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = factory.GetValueProvider(requestContext);
|
var result = factory.GetValueProvider(context);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result);
|
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result);
|
||||||
Assert.Equal(CultureInfo.CurrentCulture, valueProvider.Culture);
|
Assert.Equal(CultureInfo.CurrentCulture, valueProvider.Culture);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RouteContext CreateRequestContext(string contentType)
|
private static ValueProviderFactoryContext CreateContext(string contentType)
|
||||||
{
|
{
|
||||||
var collection = Mock.Of<IReadableStringCollection>();
|
var collection = Mock.Of<IReadableStringCollection>();
|
||||||
var request = new Mock<HttpRequest>();
|
var request = new Mock<HttpRequest>();
|
||||||
|
|
@ -59,9 +59,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var context = new Mock<HttpContext>();
|
var context = new Mock<HttpContext>();
|
||||||
context.SetupGet(c => c.Request).Returns(request.Object);
|
context.SetupGet(c => c.Request).Returns(request.Object);
|
||||||
|
|
||||||
var routeContext = new RouteContext(context.Object);
|
return new ValueProviderFactoryContext(
|
||||||
routeContext.RouteData.Values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
context.Object,
|
||||||
return routeContext;
|
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var context = new Mock<HttpContext>();
|
var context = new Mock<HttpContext>();
|
||||||
context.SetupGet(c => c.Items).Returns(new Dictionary<object, object>());
|
context.SetupGet(c => c.Items).Returns(new Dictionary<object, object>());
|
||||||
context.SetupGet(c => c.Request).Returns(request.Object);
|
context.SetupGet(c => c.Request).Returns(request.Object);
|
||||||
var routeContext = new RouteContext(context.Object);
|
var factoryContext = new ValueProviderFactoryContext(context.Object, new Dictionary<String, object>(StringComparer.OrdinalIgnoreCase));
|
||||||
routeContext.RouteData.Values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = _factory.GetValueProvider(routeContext);
|
var result = _factory.GetValueProvider(factoryContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result);
|
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue