Fix ActionMethodExecutor incorrectly setting DeclaredType on ObjectResult

Fixes #7782
This commit is contained in:
Pranav K 2018-05-15 14:41:02 -07:00
parent a736441ca5
commit 624a5ed522
5 changed files with 122 additions and 2 deletions

View File

@ -201,7 +201,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{
// Async method returning awaitable-of-nonvoid
var returnValue = await executor.ExecuteAsync(controller, arguments);
var actionResult = ConvertToActionResult(mapper, returnValue, executor.MethodReturnType);
var actionResult = ConvertToActionResult(mapper, returnValue, executor.AsyncResultType);
return actionResult;
}

View File

@ -79,6 +79,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
var result = Assert.IsType<ObjectResult>(valueTask.Result);
Assert.NotNull(result.Value);
Assert.IsType<TestModel>(result.Value);
Assert.Equal(typeof(TestModel), result.DeclaredType);
}
[Fact]
@ -97,6 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
var result = Assert.IsType<ObjectResult>(valueTask.Result);
Assert.NotNull(result.Value);
Assert.IsType<TestModel>(result.Value);
Assert.Equal(typeof(TestModel), result.DeclaredType);
}
[Fact]
@ -115,6 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
var result = Assert.IsType<ObjectResult>(valueTask.Result);
Assert.NotNull(result.Value);
Assert.IsType<TestModel>(result.Value);
Assert.Equal(typeof(object), result.DeclaredType);
}
[Fact]
@ -199,6 +202,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
var result = Assert.IsType<ObjectResult>(valueTask.Result);
Assert.NotNull(result.Value);
Assert.IsType<TestModel>(result.Value);
Assert.Equal(typeof(TestModel), result.DeclaredType);
}
[Fact]
@ -217,6 +221,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
var result = Assert.IsType<ObjectResult>(valueTask.Result);
Assert.NotNull(result.Value);
Assert.IsType<TestModel>(result.Value);
Assert.Equal(typeof(object), result.DeclaredType);
}
[Fact]
@ -251,6 +256,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
var result = Assert.IsType<ObjectResult>(valueTask.Result);
Assert.NotNull(result.Value);
Assert.IsType<TestModel>(result.Value);
Assert.Equal(typeof(TestModel), result.DeclaredType);
}
[Fact]

View File

@ -145,5 +145,89 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert
Assert.Equal(HttpStatusCode.NotAcceptable, response.StatusCode);
}
// Xml-based formatters are sensitive to ObjectResult.DeclaredType of the result. A couple of
// tests to verify we don't regress these.
[Fact]
public async Task XmlSerializerFormatter_WorksForActionsReturningTaskOfDummyClass()
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Post,
"http://localhost/XmlSerializer/GetTaskOfDummyClass");
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/xml"));
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
XmlAssert.Equal(
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task XmlSerializerFormatter_WorksForActionsReturningDummyClassAsTaskOfObject()
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Post,
"http://localhost/XmlSerializer/GetTaskOfDummyClassAsObject");
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/xml"));
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
XmlAssert.Equal(
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task XmlSerializerOutputFormatter_WorksForActionsReturningTaskOfPerson()
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Post,
"http://localhost/DataContractSerializer/GetTaskOfPerson?name=HelloWorld");
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/xml"));
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
XmlAssert.Equal(
"<Person xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite\">" +
"<Name>HelloWorld</Name></Person>",
await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task XmlSerializerOutputFormatter_WorksForActionsReturningPersonAsTaskOfObject()
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Post,
"http://localhost/DataContractSerializer/GetTaskOfPersonAsObject?name=HelloWorld");
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/xml"));
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
XmlAssert.Equal(
"<Person xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite\">" +
"<Name>HelloWorld</Name></Person>",
await response.Content.ReadAsStringAsync());
}
}
}
}

View File

@ -1,6 +1,7 @@
// 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.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
@ -31,5 +32,21 @@ namespace FormatterWebSite
// DataContractSerializer should pick up this output.
return new Person(name);
}
[HttpPost]
public Task<Person> GetTaskOfPerson(string name)
{
// The XmlSerializer should skip and the
// DataContractSerializer should pick up this output.
return Task.FromResult(new Person(name));
}
[HttpPost]
public Task<object> GetTaskOfPersonAsObject(string name)
{
// The XmlSerializer should skip and the
// DataContractSerializer should pick up this output.
return Task.FromResult<object>(new Person(name));
}
}
}

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.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
@ -45,5 +46,17 @@ namespace FormatterWebSite
{ "Hello", "World" }
};
}
[HttpPost]
public Task<DummyClass> GetTaskOfDummyClass()
{
return Task.FromResult(new DummyClass { SampleInt = 10 });
}
[HttpPost]
public Task<object> GetTaskOfDummyClassAsObject()
{
return Task.FromResult<object>(new DummyClass { SampleInt = 10 });
}
}
}