Fix #2414 Part 2 - Add [DefaultValue(...)] support to the invoker for

action parameters
This commit is contained in:
Ryan Nowak 2015-05-14 13:58:02 -07:00
parent 2fc983b23a
commit cc4ee1068d
5 changed files with 202 additions and 3 deletions

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
@ -125,9 +126,19 @@ namespace Microsoft.AspNet.Mvc
}
else
{
value = parameterInfo.ParameterType.GetTypeInfo().IsValueType
? Activator.CreateInstance(parameterInfo.ParameterType)
: null;
var defaultValueAttribute =
parameterInfo.GetCustomAttribute<DefaultValueAttribute>(inherit: false);
if (defaultValueAttribute?.Value == null)
{
value = parameterInfo.ParameterType.GetTypeInfo().IsValueType
? Activator.CreateInstance(parameterInfo.ParameterType)
: null;
}
else
{
value = defaultValueAttribute.Value;
}
}
}

View File

@ -193,6 +193,70 @@ namespace Microsoft.AspNet.Mvc.Core.Test
new Dictionary<string, object>() { { "input", inputString } }));
}
[Fact]
public async Task ExecuteAsync_WithArgumentDictionary_DefaultValueAttributeUsed()
{
// Arrange
var syncMethod = new SyncMethod(_controller.EchoWithDefaultValue);
// Act
var result = await ControllerActionExecutor.ExecuteAsync(
syncMethod.GetMethodInfo(),
_controller,
new Dictionary<string, object>());
// Assert
Assert.Equal("hello", result);
}
[Fact]
public async Task ExecuteAsync_WithArgumentArray_DefaultValueAttributeIgnored()
{
// Arrange
var syncMethod = new SyncMethod(_controller.EchoWithDefaultValue);
// Act
var result = await ControllerActionExecutor.ExecuteAsync(
syncMethod.GetMethodInfo(),
_controller,
new object[] { null, });
// Assert
Assert.Null(result);
}
[Fact]
public async Task ExecuteAsync_WithArgumentDictionary_DefaultParameterValueUsed()
{
// Arrange
var syncMethod = new SyncMethod(_controller.EchoWithDefaultValueAndAttribute);
// Act
var result = await ControllerActionExecutor.ExecuteAsync(
syncMethod.GetMethodInfo(),
_controller,
new Dictionary<string, object>());
// Assert
Assert.Equal("world", result);
}
[Fact]
public async Task ExecuteAsync_WithArgumentDictionary_AnyValue_HasPrecedenceOverDefaults()
{
// Arrange
var syncMethod = new SyncMethod(_controller.EchoWithDefaultValueAndAttribute);
// Act
var result = await ControllerActionExecutor.ExecuteAsync(
syncMethod.GetMethodInfo(),
_controller,
new Dictionary<string, object>() { { "input", null } });
// Assert
Assert.Null(result);
}
[Fact]
public async Task AsyncAction_WithCustomTaskReturnTypeThrows()
{

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.Core.Test
@ -85,6 +86,16 @@ namespace Microsoft.AspNet.Mvc.Core.Test
throw new NotImplementedException();
}
public string EchoWithDefaultValue([DefaultValue("hello")] string input)
{
return input;
}
public string EchoWithDefaultValueAndAttribute([DefaultValue("hello")] string input = "world")
{
return input;
}
public dynamic ReturnTaskAsDynamicValue(int i, string s)
{
return Task.Factory.StartNew(() => i);

View File

@ -0,0 +1,90 @@
// 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.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Xunit;
namespace Microsoft.AspNet.Mvc.FunctionalTests
{
public class DefaultValuesTest
{
private const string SiteName = nameof(BasicWebSite);
private readonly Action<IApplicationBuilder> _app = new BasicWebSite.Startup().Configure;
private readonly Action<IServiceCollection> _configureServices = new BasicWebSite.Startup().ConfigureServices;
[Fact]
public async Task Controller_WithDefaultValueAttribut_ReturnsDefault()
{
// Arrange
var expected = "hello";
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient();
var url = "http://localhost/DefaultValues/EchoValue_DefaultValueAttribute";
// Act
var response = await client.GetStringAsync(url);
// Assert
Assert.Equal(expected, response);
}
[Fact]
public async Task Controller_WithDefaultValueAttribute_ReturnsModelBoundValues()
{
// Arrange
var expected = "cool";
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient();
var url = "http://localhost/DefaultValues/EchoValue_DefaultValueAttribute?input=cool";
// Act
var response = await client.GetStringAsync(url);
// Assert
Assert.Equal(expected, response);
}
[Fact]
public async Task Controller_WithDefaultParameterValue_ReturnsDefault()
{
// Arrange
var expected = "world";
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient();
var url = "http://localhost/DefaultValues/EchoValue_DefaultParameterValue";
// Act
var response = await client.GetStringAsync(url);
// Assert
Assert.Equal(expected, response);
}
[Fact]
public async Task Controller_WithDefaultParameterValue_ReturnsModelBoundValues()
{
// Arrange
var expected = "cool";
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient();
var url = "http://localhost/DefaultValues/EchoValue_DefaultParameterValue?input=cool";
// Act
var response = await client.GetStringAsync(url);
// Assert
Assert.Equal(expected, response);
}
}
}

View File

@ -0,0 +1,23 @@
// 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.ComponentModel;
using Microsoft.AspNet.Mvc;
namespace BasicWebSite.Controllers
{
public class DefaultValuesController : Controller
{
[HttpGet]
public string EchoValue_DefaultValueAttribute([DefaultValue("hello")] string input)
{
return input;
}
[HttpGet]
public string EchoValue_DefaultParameterValue(string input = "world")
{
return input;
}
}
}