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)
|
||||
{
|
||||
var routeContext = new RouteContext(actionContext.HttpContext);
|
||||
routeContext.RouteData = actionContext.RouteData;
|
||||
var valueProviders = _valueProviderFactories.Select(factory => factory.GetValueProvider(routeContext))
|
||||
var factoryContext = new ValueProviderFactoryContext(
|
||||
actionContext.HttpContext,
|
||||
actionContext.RouteData.Values);
|
||||
|
||||
var valueProviders = _valueProviderFactories.Select(factory => factory.GetValueProvider(factoryContext))
|
||||
.Where(vp => vp != null);
|
||||
var context = new ActionBindingContext(
|
||||
actionContext,
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@
|
|||
<Compile Include="ValueProviders\QueryStringValueProviderFactory.cs" />
|
||||
<Compile Include="ValueProviders\ReadableStringCollectionValueProvider.cs" />
|
||||
<Compile Include="ValueProviders\RouteValueValueProviderFactory.cs" />
|
||||
<Compile Include="ValueProviders\ValueProviderFactoryContext.cs" />
|
||||
<Compile Include="ValueProviders\ValueProviderResult.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Routing;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
|
|
@ -12,9 +11,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
// 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.Routing;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public interface IValueProviderFactory
|
||||
|
|
@ -10,8 +8,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// <summary>
|
||||
/// Get a value provider with values from the given <paramref name="requestContext"/>.
|
||||
/// </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>
|
||||
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.
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Routing;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
|
|
@ -10,15 +9,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
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.
|
||||
var storage = routeContext.HttpContext.Items;
|
||||
var storage = context.HttpContext.Items;
|
||||
object value;
|
||||
IValueProvider provider;
|
||||
if (!storage.TryGetValue(_cacheKey, out value))
|
||||
{
|
||||
var queryCollection = routeContext.HttpContext.Request.Query;
|
||||
var queryCollection = context.HttpContext.Request.Query;
|
||||
provider = new ReadableStringCollectionValueProvider(queryCollection, CultureInfo.InvariantCulture);
|
||||
storage[_cacheKey] = provider;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
// 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.Routing;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
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": {
|
||||
"Microsoft.AspNet.Http": "0.1-alpha-*",
|
||||
"Microsoft.AspNet.Mvc.Common": "",
|
||||
"Microsoft.AspNet.Routing": "0.1-alpha-*",
|
||||
"Microsoft.DataAnnotations": "0.1-alpha-*",
|
||||
"Microsoft.Framework.DependencyInjection": "0.1-alpha-*",
|
||||
"Newtonsoft.Json": "5.0.8"
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
|||
public void GetValueProvider_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded()
|
||||
{
|
||||
// Arrange
|
||||
var requestContext = CreateRequestContext("some-content-type");
|
||||
var context = CreateContext("some-content-type");
|
||||
var factory = new FormValueProviderFactory();
|
||||
|
||||
// Act
|
||||
var result = factory.GetValueProvider(requestContext);
|
||||
var result = factory.GetValueProvider(context);
|
||||
|
||||
// Assert
|
||||
Assert.Null(result);
|
||||
|
|
@ -35,18 +35,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
|||
public void GetValueProvider_ReturnsValueProviderInstaceWithInvariantCulture(string contentType)
|
||||
{
|
||||
// Arrange
|
||||
var requestContext = CreateRequestContext(contentType);
|
||||
var context = CreateContext(contentType);
|
||||
var factory = new FormValueProviderFactory();
|
||||
|
||||
// Act
|
||||
var result = factory.GetValueProvider(requestContext);
|
||||
var result = factory.GetValueProvider(context);
|
||||
|
||||
// Assert
|
||||
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result);
|
||||
Assert.Equal(CultureInfo.CurrentCulture, valueProvider.Culture);
|
||||
}
|
||||
|
||||
private static RouteContext CreateRequestContext(string contentType)
|
||||
private static ValueProviderFactoryContext CreateContext(string contentType)
|
||||
{
|
||||
var collection = Mock.Of<IReadableStringCollection>();
|
||||
var request = new Mock<HttpRequest>();
|
||||
|
|
@ -59,9 +59,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
|||
var context = new Mock<HttpContext>();
|
||||
context.SetupGet(c => c.Request).Returns(request.Object);
|
||||
|
||||
var routeContext = new RouteContext(context.Object);
|
||||
routeContext.RouteData.Values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
return routeContext;
|
||||
return new ValueProviderFactoryContext(
|
||||
context.Object,
|
||||
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
|||
var context = new Mock<HttpContext>();
|
||||
context.SetupGet(c => c.Items).Returns(new Dictionary<object, object>());
|
||||
context.SetupGet(c => c.Request).Returns(request.Object);
|
||||
var routeContext = new RouteContext(context.Object);
|
||||
routeContext.RouteData.Values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
var factoryContext = new ValueProviderFactoryContext(context.Object, new Dictionary<String, object>(StringComparer.OrdinalIgnoreCase));
|
||||
|
||||
// Act
|
||||
var result = _factory.GetValueProvider(routeContext);
|
||||
var result = _factory.GetValueProvider(factoryContext);
|
||||
|
||||
// Assert
|
||||
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result);
|
||||
|
|
|
|||
Loading…
Reference in New Issue