Fix breaking changes from HttpAbstractions

This commit is contained in:
Ryan Nowak 2015-11-02 18:17:52 -08:00
parent e2c2676042
commit 32da2b8c46
18 changed files with 169 additions and 49 deletions

View File

@ -109,6 +109,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return null; return null;
} }
public bool TryGetValue(string key, out StringValues value)
{
value = default(StringValues);
return false;
}
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator(); return GetEnumerator();
@ -132,7 +138,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
IReadOnlyList<IFormFile> IFormFileCollection.GetFiles(string name) IReadOnlyList<IFormFile> IFormFileCollection.GetFiles(string name)
{ {
throw new NotImplementedException(); return null;
} }
} }
} }

View File

@ -9,23 +9,23 @@ using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Mvc.ModelBinding namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
/// <summary> /// <summary>
/// An <see cref="IValueProvider"/> adapter for data stored in an <see cref="IReadableStringCollection"/>. /// An <see cref="IValueProvider"/> adapter for data stored in an <see cref="IFormCollection"/>.
/// </summary> /// </summary>
public class ReadableStringCollectionValueProvider : BindingSourceValueProvider, IEnumerableValueProvider public class FormValueProvider : BindingSourceValueProvider, IEnumerableValueProvider
{ {
private readonly CultureInfo _culture; private readonly CultureInfo _culture;
private PrefixContainer _prefixContainer; private PrefixContainer _prefixContainer;
private IReadableStringCollection _values; private IFormCollection _values;
/// <summary> /// <summary>
/// Creates a provider for <see cref="IReadableStringCollection"/> wrapping an existing set of key value pairs. /// Creates a value provider for <see cref="IFormCollection"/>.
/// </summary> /// </summary>
/// <param name="bindingSource">The <see cref="BindingSource"/> for the data.</param> /// <param name="bindingSource">The <see cref="BindingSource"/> for the data.</param>
/// <param name="values">The key value pairs to wrap.</param> /// <param name="values">The key value pairs to wrap.</param>
/// <param name="culture">The culture to return with ValueProviderResult instances.</param> /// <param name="culture">The culture to return with ValueProviderResult instances.</param>
public ReadableStringCollectionValueProvider( public FormValueProvider(
BindingSource bindingSource, BindingSource bindingSource,
IReadableStringCollection values, IFormCollection values,
CultureInfo culture) CultureInfo culture)
: base(bindingSource) : base(bindingSource)
{ {

View File

@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private static async Task<IValueProvider> CreateValueProviderAsync(HttpRequest request) private static async Task<IValueProvider> CreateValueProviderAsync(HttpRequest request)
{ {
return new ReadableStringCollectionValueProvider( return new FormValueProvider(
BindingSource.Form, BindingSource.Form,
await request.ReadFormAsync(), await request.ReadFormAsync(),
CultureInfo.CurrentCulture); CultureInfo.CurrentCulture);

View File

@ -0,0 +1,103 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// An <see cref="IValueProvider"/> adapter for data stored in an <see cref="IQueryCollection"/>.
/// </summary>
public class QueryStringValueProvider : BindingSourceValueProvider, IEnumerableValueProvider
{
private readonly CultureInfo _culture;
private PrefixContainer _prefixContainer;
private IQueryCollection _values;
/// <summary>
/// Creates a value provider for <see cref="IQueryCollection"/>.
/// </summary>
/// <param name="bindingSource">The <see cref="BindingSource"/> for the data.</param>
/// <param name="values">The key value pairs to wrap.</param>
/// <param name="culture">The culture to return with ValueProviderResult instances.</param>
public QueryStringValueProvider(
BindingSource bindingSource,
IQueryCollection values,
CultureInfo culture)
: base(bindingSource)
{
if (bindingSource == null)
{
throw new ArgumentNullException(nameof(bindingSource));
}
if (values == null)
{
throw new ArgumentNullException(nameof(values));
}
_values = values;
_culture = culture;
}
public CultureInfo Culture
{
get
{
return _culture;
}
}
protected PrefixContainer PrefixContainer
{
get
{
if (_prefixContainer == null)
{
_prefixContainer = new PrefixContainer(_values.Keys);
}
return _prefixContainer;
}
}
/// <inheritdoc />
public override bool ContainsPrefix(string prefix)
{
return PrefixContainer.ContainsPrefix(prefix);
}
/// <inheritdoc />
public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix)
{
if (prefix == null)
{
throw new ArgumentNullException(nameof(prefix));
}
return PrefixContainer.GetKeysFromPrefix(prefix);
}
/// <inheritdoc />
public override ValueProviderResult GetValue(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
var values = _values[key];
if (values.Count == 0)
{
return ValueProviderResult.None;
}
else
{
return new ValueProviderResult(values, _culture);
}
}
}
}

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
return Task.FromResult<IValueProvider>(new ReadableStringCollectionValueProvider( return Task.FromResult<IValueProvider>(new QueryStringValueProvider(
BindingSource.Query, BindingSource.Query,
context.HttpContext.Request.Query, context.HttpContext.Request.Query,
CultureInfo.InvariantCulture)); CultureInfo.InvariantCulture));

View File

@ -12,6 +12,7 @@ using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures; using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Razor.TagHelpers; using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNet.Mvc.TagHelpers namespace Microsoft.AspNet.Mvc.TagHelpers
{ {
@ -195,9 +196,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
.Append(VaryBy); .Append(VaryBy);
} }
AddStringCollectionKey(builder, nameof(VaryByCookie), VaryByCookie, request.Cookies); AddStringCollectionKey(builder, nameof(VaryByCookie), VaryByCookie, request.Cookies, (c, key) => c[key]);
AddStringCollectionKey(builder, nameof(VaryByHeader), VaryByHeader, request.Headers); AddStringCollectionKey(builder, nameof(VaryByHeader), VaryByHeader, request.Headers, (c, key) => c[key]);
AddStringCollectionKey(builder, nameof(VaryByQuery), VaryByQuery, request.Query); AddStringCollectionKey(builder, nameof(VaryByQuery), VaryByQuery, request.Query, (c, key) => c[key]);
AddVaryByRouteKey(builder); AddVaryByRouteKey(builder);
if (VaryByUser) if (VaryByUser)
@ -251,7 +252,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
StringBuilder builder, StringBuilder builder,
string keyName, string keyName,
string value, string value,
IReadableStringCollection sourceCollection) IDictionary<string, StringValues> sourceCollection)
{ {
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
@ -281,11 +282,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
} }
} }
private static void AddStringCollectionKey( private static void AddStringCollectionKey<T>(
StringBuilder builder, StringBuilder builder,
string keyName, string keyName,
string value, string value,
IHeaderDictionary sourceCollection) T sourceCollection,
Func<T, string, StringValues> accessor)
{ {
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
@ -301,7 +303,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
builder.Append(item) builder.Append(item)
.Append(CacheKeyTokenSeparator) .Append(CacheKeyTokenSeparator)
.Append(sourceCollection[item]) .Append(accessor(sourceCollection, item))
.Append(CacheKeyTokenSeparator); .Append(CacheKeyTokenSeparator);
} }

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
protected override IEnumerableValueProvider GetEnumerableValueProvider( protected override IEnumerableValueProvider GetEnumerableValueProvider(
BindingSource bindingSource, BindingSource bindingSource,
IDictionary<string, StringValues> values, Dictionary<string, StringValues> values,
CultureInfo culture) CultureInfo culture)
{ {
var emptyValueProvider = var emptyValueProvider =

View File

@ -444,11 +444,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var backingStore = dictionary.ToDictionary( var backingStore = dictionary.ToDictionary(
kvp => string.Format(keyFormat, kvp.Key), kvp => string.Format(keyFormat, kvp.Key),
kvp => (StringValues)kvp.Value); kvp => (StringValues)kvp.Value);
var stringCollection = new ReadableStringCollection(backingStore);
return new ReadableStringCollectionValueProvider( var formCollection = new FormCollection(backingStore);
return new FormValueProvider(
BindingSource.Form, BindingSource.Form,
stringCollection, formCollection,
CultureInfo.InvariantCulture); CultureInfo.InvariantCulture);
} }

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
public abstract class EnumerableValueProviderTest public abstract class EnumerableValueProviderTest
{ {
private static readonly IDictionary<string, StringValues> _backingStore = new Dictionary<string, StringValues> private static readonly Dictionary<string, StringValues> _backingStore = new Dictionary<string, StringValues>
{ {
{ "some", new[] { "someValue1", "someValue2" } }, { "some", new[] { "someValue1", "someValue2" } },
{ "null_value", StringValues.Empty }, { "null_value", StringValues.Empty },
@ -279,7 +279,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private IBindingSourceValueProvider GetBindingSourceValueProvider( private IBindingSourceValueProvider GetBindingSourceValueProvider(
BindingSource bindingSource, BindingSource bindingSource,
IDictionary<string, StringValues> values, Dictionary<string, StringValues> values,
CultureInfo culture) CultureInfo culture)
{ {
var provider = GetEnumerableValueProvider(bindingSource, values, culture) as IBindingSourceValueProvider; var provider = GetEnumerableValueProvider(bindingSource, values, culture) as IBindingSourceValueProvider;
@ -292,7 +292,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
protected abstract IEnumerableValueProvider GetEnumerableValueProvider( protected abstract IEnumerableValueProvider GetEnumerableValueProvider(
BindingSource bindingSource, BindingSource bindingSource,
IDictionary<string, StringValues> values, Dictionary<string, StringValues> values,
CultureInfo culture); CultureInfo culture);
} }
} }

View File

@ -134,20 +134,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return bindingContext; return bindingContext;
} }
private class MyFormCollection : ReadableStringCollection, IFormCollection
{
public MyFormCollection(IDictionary<string, StringValues> store) : this(store, new FormFileCollection())
{
}
public MyFormCollection(IDictionary<string, StringValues> store, IFormFileCollection files) : base(store)
{
Files = files;
}
public IFormFileCollection Files { get; private set; }
}
} }
} }

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var result = await factory.GetValueProviderAsync(context); var result = await factory.GetValueProviderAsync(context);
// Assert // Assert
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result); var valueProvider = Assert.IsType<FormValueProvider>(result);
Assert.Equal(CultureInfo.CurrentCulture, valueProvider.Culture); Assert.Equal(CultureInfo.CurrentCulture, valueProvider.Culture);
} }

View File

@ -8,15 +8,15 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNet.Mvc.ModelBinding namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
public class ReadableStringCollectionValueProviderTest : EnumerableValueProviderTest public class FormValueProviderTest : EnumerableValueProviderTest
{ {
protected override IEnumerableValueProvider GetEnumerableValueProvider( protected override IEnumerableValueProvider GetEnumerableValueProvider(
BindingSource bindingSource, BindingSource bindingSource,
IDictionary<string, StringValues> values, Dictionary<string, StringValues> values,
CultureInfo culture) CultureInfo culture)
{ {
var backingStore = new ReadableStringCollection(values); var backingStore = new FormCollection(values);
return new ReadableStringCollectionValueProvider(bindingSource, backingStore, culture); return new FormValueProvider(bindingSource, backingStore, culture);
} }
} }
} }

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ {
public class JQueryFormValueProviderFactoryTest public class JQueryFormValueProviderFactoryTest
{ {
private static readonly IDictionary<string, StringValues> _backingStore = new Dictionary<string, StringValues> private static readonly Dictionary<string, StringValues> _backingStore = new Dictionary<string, StringValues>
{ {
{ "[]", new[] { "found" } }, { "[]", new[] { "found" } },
{ "[]property1", new[] { "found" } }, { "[]property1", new[] { "found" } },
@ -116,7 +116,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
private static ValueProviderFactoryContext CreateContext( private static ValueProviderFactoryContext CreateContext(
string contentType, string contentType,
IDictionary<string, StringValues> formValues) Dictionary<string, StringValues> formValues)
{ {
var context = new DefaultHttpContext(); var context = new DefaultHttpContext();
context.Request.ContentType = contentType; context.Request.ContentType = contentType;

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
protected override IEnumerableValueProvider GetEnumerableValueProvider( protected override IEnumerableValueProvider GetEnumerableValueProvider(
BindingSource bindingSource, BindingSource bindingSource,
IDictionary<string, StringValues> values, Dictionary<string, StringValues> values,
CultureInfo culture) CultureInfo culture)
{ {
return new JQueryFormValueProvider(bindingSource, values, culture); return new JQueryFormValueProvider(bindingSource, values, culture);

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ {
// Arrange // Arrange
var request = new Mock<HttpRequest>(); var request = new Mock<HttpRequest>();
request.SetupGet(f => f.Query).Returns(Mock.Of<IReadableStringCollection>()); request.SetupGet(f => f.Query).Returns(Mock.Of<IQueryCollection>());
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);
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var result = await _factory.GetValueProviderAsync(factoryContext); var result = await _factory.GetValueProviderAsync(factoryContext);
// Assert // Assert
var valueProvider = Assert.IsType<ReadableStringCollectionValueProvider>(result); var valueProvider = Assert.IsType<QueryStringValueProvider>(result);
Assert.Equal(CultureInfo.InvariantCulture, valueProvider.Culture); Assert.Equal(CultureInfo.InvariantCulture, valueProvider.Culture);
} }
#endif #endif

View File

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNet.Http.Internal;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class QueryStringValueProviderTest : EnumerableValueProviderTest
{
protected override IEnumerableValueProvider GetEnumerableValueProvider(
BindingSource bindingSource,
Dictionary<string, StringValues> values,
CultureInfo culture)
{
var backingStore = new QueryCollection(values);
return new QueryStringValueProvider(bindingSource, backingStore, culture);
}
}
}

View File

@ -908,7 +908,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
[MemberData(nameof(CollectionTypeData))] [MemberData(nameof(CollectionTypeData))]
public async Task CollectionModelBinder_BindsParameterToExpectedType( public async Task CollectionModelBinder_BindsParameterToExpectedType(
Type parameterType, Type parameterType,
IDictionary<string, StringValues> formContent, Dictionary<string, StringValues> formContent,
Type expectedType) Type expectedType)
{ {
// Arrange // Arrange

View File

@ -438,7 +438,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
[Theory] [Theory]
[MemberData(nameof(PersonStoreData))] [MemberData(nameof(PersonStoreData))]
public async Task BindParameter_FromFormData_BindsCorrectly(IDictionary<string, StringValues> personStore) public async Task BindParameter_FromFormData_BindsCorrectly(Dictionary<string, StringValues> personStore)
{ {
// Arrange // Arrange
var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var argumentBinder = ModelBindingTestHelper.GetArgumentBinder();