Adding CancellationTokenModelBinder.

This commit is contained in:
Harsh Gupta 2014-10-09 12:41:03 -07:00
parent ad208442d8
commit e319fef5cb
6 changed files with 144 additions and 6 deletions

View File

@ -0,0 +1,26 @@
// 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.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// Represents a model binder which can bind models of type <see cref="CancellationToken"/>.
/// </summary>
public class CancellationTokenModelBinder : IModelBinder
{
/// <inheritdoc />
public Task<bool> BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(CancellationToken))
{
bindingContext.Model = bindingContext.HttpContext.RequestAborted;
return Task.FromResult(true);
}
return Task.FromResult(false);
}
}
}

View File

@ -27,6 +27,7 @@ namespace Microsoft.AspNet.Mvc
// Set up ModelBinding
options.ModelBinders.Add(new TypeConverterModelBinder());
options.ModelBinders.Add(new TypeMatchModelBinder());
options.ModelBinders.Add(new CancellationTokenModelBinder());
options.ModelBinders.Add(new ByteArrayModelBinder());
options.ModelBinders.Add(typeof(GenericModelBinder));
options.ModelBinders.Add(new MutableObjectModelBinder());

View File

@ -18,6 +18,37 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
private readonly IServiceProvider _services = TestHelper.CreateServices("ModelBindingWebSite");
private readonly Action<IApplicationBuilder> _app = new ModelBindingWebSite.Startup().Configure;
[Fact]
public async Task ModelBindCancellationTokenParameteres()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync("http://localhost/Home/ActionWithCancellationToken");
//Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("true", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ModelBindCancellationToken_ForProperties()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
// Act
var response = await client.GetAsync(
"http://localhost/Home/ActionWithCancellationTokenModel?wrapper=bogusValue");
//Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("true", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task ModelBindingBindsBase64StringsToByteArrays()
{

View File

@ -0,0 +1,63 @@
// 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;
using System.Threading.Tasks;
using Microsoft.AspNet.PipelineCore;
using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
public class CancellationTokenModelBinderTests
{
[Fact]
public async Task CancellationTokenModelBinder_ReturnsTrue_ForCancellationTokenType()
{
// Arrange
var bindingContext = GetBindingContext(typeof(CancellationToken));
var binder = new CancellationTokenModelBinder();
// Act
var bound = await binder.BindModelAsync(bindingContext);
// Assert
Assert.True(bound);
Assert.Equal(bindingContext.HttpContext.RequestAborted, bindingContext.Model);
}
[Theory]
[InlineData(typeof(int))]
[InlineData(typeof(object))]
[InlineData(typeof(CancellationTokenModelBinderTests))]
public async Task CancellationTokenModelBinder_ReturnsFalse_ForNonCancellationTokenType(Type t)
{
// Arrange
var bindingContext = GetBindingContext(t);
var binder = new CancellationTokenModelBinder();
// Act
var bound = await binder.BindModelAsync(bindingContext);
// Assert
Assert.False(bound);
Assert.Null(bindingContext.Model);
}
private static ModelBindingContext GetBindingContext(Type modelType)
{
var metadataProvider = new EmptyModelMetadataProvider();
ModelBindingContext bindingContext = new ModelBindingContext
{
ModelMetadata = metadataProvider.GetMetadataForType(null, modelType),
ModelName = "someName",
ValueProvider = new SimpleHttpValueProvider(),
ModelBinder = new CancellationTokenModelBinder(),
MetadataProvider = metadataProvider,
HttpContext = new DefaultHttpContext(),
};
return bindingContext;
}
}
}

View File

@ -35,13 +35,14 @@ namespace Microsoft.AspNet.Mvc
setup.Invoke(mvcOptions);
// Assert
Assert.Equal(6, mvcOptions.ModelBinders.Count);
Assert.Equal(7, mvcOptions.ModelBinders.Count);
Assert.Equal(typeof(TypeConverterModelBinder), mvcOptions.ModelBinders[0].OptionType);
Assert.Equal(typeof(TypeMatchModelBinder), mvcOptions.ModelBinders[1].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);
Assert.Equal(typeof(CancellationTokenModelBinder), mvcOptions.ModelBinders[2].OptionType);
Assert.Equal(typeof(ByteArrayModelBinder), mvcOptions.ModelBinders[3].OptionType);
Assert.Equal(typeof(GenericModelBinder), mvcOptions.ModelBinders[4].OptionType);
Assert.Equal(typeof(MutableObjectModelBinder), mvcOptions.ModelBinders[5].OptionType);
Assert.Equal(typeof(ComplexModelDtoModelBinder), mvcOptions.ModelBinders[6].OptionType);
}
[Fact]

View File

@ -2,8 +2,9 @@
// 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.Mvc;
using System.Linq;
using System.Threading;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
@ -26,6 +27,16 @@ namespace ModelBindingWebSite.Controllers
return CreateValidationDictionary();
}
public bool ActionWithCancellationToken(CancellationToken token)
{
return token == ActionContext.HttpContext.RequestAborted;
}
public bool ActionWithCancellationTokenModel(CancellationTokenModel wrapper)
{
return wrapper.CancellationToken == ActionContext.HttpContext.RequestAborted;
}
private Dictionary<string, string> CreateValidationDictionary()
{
var result = new Dictionary<string, string>();
@ -42,5 +53,10 @@ namespace ModelBindingWebSite.Controllers
return result;
}
public class CancellationTokenModel
{
public CancellationToken CancellationToken { get; set; }
}
}
}