parent
d79943d30f
commit
85bd056780
|
|
@ -101,23 +101,25 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
// optimize common path
|
// optimize common path
|
||||||
var actionResult = actionReturnValue as IActionResult;
|
var actionResult = actionReturnValue as IActionResult;
|
||||||
|
|
||||||
if (actionResult != null)
|
if (actionResult != null)
|
||||||
{
|
{
|
||||||
return actionResult;
|
return actionResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionReturnValue == null && typeof(IActionResult).IsAssignableFrom(declaredReturnType))
|
if (declaredReturnType == typeof(void) ||
|
||||||
{
|
declaredReturnType == typeof(Task))
|
||||||
throw new InvalidOperationException(
|
|
||||||
Resources.FormatActionResult_ActionReturnValueCannotBeNull(declaredReturnType));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declaredReturnType == typeof(void))
|
|
||||||
{
|
{
|
||||||
return new NoContentResult();
|
return new NoContentResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap potential Task<T> types.
|
||||||
|
var actualReturnType = TypeHelper.GetTaskInnerTypeOrNull(declaredReturnType) ?? declaredReturnType;
|
||||||
|
if (actionReturnValue == null && typeof(IActionResult).IsAssignableFrom(actualReturnType))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
Resources.FormatActionResult_ActionReturnValueCannotBeNull(actualReturnType));
|
||||||
|
}
|
||||||
|
|
||||||
return new ObjectContentResult(actionReturnValue);
|
return new ObjectContentResult(actionReturnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,12 +402,8 @@ namespace Microsoft.AspNet.Mvc
|
||||||
_actionContext.Controller,
|
_actionContext.Controller,
|
||||||
_actionExecutingContext.ActionArguments);
|
_actionExecutingContext.ActionArguments);
|
||||||
|
|
||||||
var underlyingReturnType =
|
|
||||||
TypeHelper.GetTaskInnerTypeOrNull(actionMethodInfo.ReturnType) ??
|
|
||||||
actionMethodInfo.ReturnType;
|
|
||||||
|
|
||||||
var actionResult = CreateActionResult(
|
var actionResult = CreateActionResult(
|
||||||
underlyingReturnType,
|
actionMethodInfo.ReturnType,
|
||||||
actionReturnValue);
|
actionReturnValue);
|
||||||
return actionResult;
|
return actionResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,22 +29,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public int x;
|
public int x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<object[]> CreateActionResultData
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
yield return new object[] { new { x1 = 10, y1 = "Hello" } };
|
|
||||||
yield return new object[] { 5 };
|
|
||||||
yield return new object[] { "sample input" };
|
|
||||||
|
|
||||||
SampleStruct test;
|
|
||||||
test.x = 10;
|
|
||||||
yield return new object[] { test };
|
|
||||||
|
|
||||||
yield return new object[] { new Task(() => Console.WriteLine("Test task")) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task InvokeAction_DoesNotInvokeExceptionFilter_WhenActionDoesNotThrow()
|
public async Task InvokeAction_DoesNotInvokeExceptionFilter_WhenActionDoesNotThrow()
|
||||||
{
|
{
|
||||||
|
|
@ -1241,28 +1225,44 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(typeof(void), typeof(NoContentResult))]
|
[InlineData(typeof(void))]
|
||||||
[InlineData(typeof(string), typeof(ObjectContentResult))]
|
[InlineData(typeof(Task))]
|
||||||
public void CreateActionResult_Types_ReturnsAppropriateResults(Type type, Type returnType)
|
public void CreateActionResult_Types_ReturnsNoContentResultForTaskAndVoidReturnTypes(Type type)
|
||||||
{
|
{
|
||||||
// Arrange & Act
|
// Arrange & Act
|
||||||
var result = ReflectedActionInvoker.CreateActionResult(type, null).GetType();
|
var result = ReflectedActionInvoker.CreateActionResult(type, null).GetType();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(returnType, result);
|
Assert.Equal(typeof(NoContentResult), (result));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> CreateActionResult_ReturnsObjectContentResultData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var anonymousObject = new { x1 = 10, y1 = "Hello" };
|
||||||
|
yield return new object[] { anonymousObject.GetType(), anonymousObject, };
|
||||||
|
yield return new object[] { typeof(int), 5 };
|
||||||
|
yield return new object[] { typeof(string), "sample input" };
|
||||||
|
|
||||||
|
SampleStruct test;
|
||||||
|
test.x = 10;
|
||||||
|
yield return new object[] { test.GetType(), test };
|
||||||
|
yield return new object[] { typeof(Task<int>), 5 };
|
||||||
|
yield return new object[] { typeof(Task<string>), "Hello world" };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData("CreateActionResultData")]
|
[MemberData("CreateActionResult_ReturnsObjectContentResultData")]
|
||||||
public void CreateActionResult_ReturnsObjectContentResult(object input)
|
public void CreateActionResult_ReturnsObjectContentResult(Type type, object input)
|
||||||
{
|
{
|
||||||
// Arrange & Act
|
// Arrange & Act
|
||||||
var actualResult = ReflectedActionInvoker.CreateActionResult(input.GetType(), input)
|
var actualResult = ReflectedActionInvoker.CreateActionResult(type, input);
|
||||||
as ObjectContentResult;
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(actualResult);
|
var contentResult = Assert.IsType<ObjectContentResult>(actualResult);
|
||||||
Assert.Equal(input, actualResult.Value);
|
Assert.Same(input, contentResult.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReflectedActionInvoker CreateInvoker(IFilter filter, bool actionThrows = false)
|
private ReflectedActionInvoker CreateInvoker(IFilter filter, bool actionThrows = false)
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,22 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
Assert.Equal(0, result.Body.Length);
|
Assert.Equal(0, result.Body.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ReturningTaskFromAction_ProducesNoContentResult()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/Home/ActionReturningTask");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(204, result.StatusCode);
|
||||||
|
var body = await result.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal("Hello world", body);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ActionDescriptors_CreatedOncePerRequest()
|
public async Task ActionDescriptors_CreatedOncePerRequest()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
using Microsoft.AspNet.Mvc;
|
// 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.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
|
||||||
namespace BasicWebSite.Controllers
|
namespace BasicWebSite.Controllers
|
||||||
{
|
{
|
||||||
|
|
@ -18,5 +22,10 @@ namespace BasicWebSite.Controllers
|
||||||
{
|
{
|
||||||
return new HttpStatusCodeResult(204);
|
return new HttpStatusCodeResult(204);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ActionReturningTask()
|
||||||
|
{
|
||||||
|
await Context.Response.WriteAsync("Hello world");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue