parent
d79943d30f
commit
85bd056780
|
|
@ -101,23 +101,25 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// optimize common path
|
||||
var actionResult = actionReturnValue as IActionResult;
|
||||
|
||||
if (actionResult != null)
|
||||
{
|
||||
return actionResult;
|
||||
}
|
||||
|
||||
if (actionReturnValue == null && typeof(IActionResult).IsAssignableFrom(declaredReturnType))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatActionResult_ActionReturnValueCannotBeNull(declaredReturnType));
|
||||
}
|
||||
|
||||
if (declaredReturnType == typeof(void))
|
||||
if (declaredReturnType == typeof(void) ||
|
||||
declaredReturnType == typeof(Task))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -275,7 +277,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
var parameterType = parameter.BodyParameterInfo.ParameterType;
|
||||
var modelMetadata = metadataProvider.GetMetadataForType(
|
||||
modelAccessor: null,
|
||||
modelAccessor: null,
|
||||
modelType: parameterType);
|
||||
var providerContext = new InputFormatterProviderContext(
|
||||
actionBindingContext.ActionContext.HttpContext,
|
||||
|
|
@ -295,7 +297,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
var parameterType = parameter.ParameterBindingInfo.ParameterType;
|
||||
var modelMetadata = metadataProvider.GetMetadataForType(
|
||||
modelAccessor: null,
|
||||
modelAccessor: null,
|
||||
modelType: parameterType);
|
||||
|
||||
var modelBindingContext = new ModelBindingContext
|
||||
|
|
@ -400,12 +402,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
_actionContext.Controller,
|
||||
_actionExecutingContext.ActionArguments);
|
||||
|
||||
var underlyingReturnType =
|
||||
TypeHelper.GetTaskInnerTypeOrNull(actionMethodInfo.ReturnType) ??
|
||||
actionMethodInfo.ReturnType;
|
||||
|
||||
var actionResult = CreateActionResult(
|
||||
underlyingReturnType,
|
||||
actionMethodInfo.ReturnType,
|
||||
actionReturnValue);
|
||||
return actionResult;
|
||||
}
|
||||
|
|
@ -459,8 +457,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Short-circuited by not calling next
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
Canceled = true,
|
||||
|
|
@ -470,8 +468,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Short-circuited by setting Cancel == true
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
Canceled = true,
|
||||
|
|
@ -486,8 +484,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Short-circuited by setting Cancel == true
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
Canceled = true,
|
||||
|
|
@ -504,16 +502,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
Contract.Assert(_resultExecutedContext == null);
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_resultExecutedContext = new ResultExecutedContext(
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext,
|
||||
_filters,
|
||||
_resultExecutingContext.Result)
|
||||
{
|
||||
ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception)
|
||||
|
|
|
|||
|
|
@ -29,22 +29,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
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]
|
||||
public async Task InvokeAction_DoesNotInvokeExceptionFilter_WhenActionDoesNotThrow()
|
||||
{
|
||||
|
|
@ -1241,28 +1225,44 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(void), typeof(NoContentResult))]
|
||||
[InlineData(typeof(string), typeof(ObjectContentResult))]
|
||||
public void CreateActionResult_Types_ReturnsAppropriateResults(Type type, Type returnType)
|
||||
[InlineData(typeof(void))]
|
||||
[InlineData(typeof(Task))]
|
||||
public void CreateActionResult_Types_ReturnsNoContentResultForTaskAndVoidReturnTypes(Type type)
|
||||
{
|
||||
// Arrange & Act
|
||||
var result = ReflectedActionInvoker.CreateActionResult(type, null).GetType();
|
||||
|
||||
// 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]
|
||||
[MemberData("CreateActionResultData")]
|
||||
public void CreateActionResult_ReturnsObjectContentResult(object input)
|
||||
[MemberData("CreateActionResult_ReturnsObjectContentResultData")]
|
||||
public void CreateActionResult_ReturnsObjectContentResult(Type type, object input)
|
||||
{
|
||||
// Arrange & Act
|
||||
var actualResult = ReflectedActionInvoker.CreateActionResult(input.GetType(), input)
|
||||
as ObjectContentResult;
|
||||
|
||||
var actualResult = ReflectedActionInvoker.CreateActionResult(type, input);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(actualResult);
|
||||
Assert.Equal(input, actualResult.Value);
|
||||
var contentResult = Assert.IsType<ObjectContentResult>(actualResult);
|
||||
Assert.Same(input, contentResult.Value);
|
||||
}
|
||||
|
||||
private ReflectedActionInvoker CreateInvoker(IFilter filter, bool actionThrows = false)
|
||||
|
|
|
|||
|
|
@ -90,6 +90,22 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
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]
|
||||
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
|
||||
{
|
||||
|
|
@ -7,7 +11,7 @@ namespace BasicWebSite.Controllers
|
|||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
||||
public IActionResult PlainView()
|
||||
{
|
||||
|
|
@ -18,5 +22,10 @@ namespace BasicWebSite.Controllers
|
|||
{
|
||||
return new HttpStatusCodeResult(204);
|
||||
}
|
||||
|
||||
public async Task ActionReturningTask()
|
||||
{
|
||||
await Context.Response.WriteAsync("Hello world");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue