Fix issue #1280 - Add HttpResponseMessageFormatter
Adds a formatter that can convert an HttpResponseMessage returned from an action into HttpContext.Response output.
This commit is contained in:
parent
aad3ae42ca
commit
22869b41c0
|
|
@ -0,0 +1,69 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.HttpFeature;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
||||
{
|
||||
public class HttpResponseMessageOutputFormatter : IOutputFormatter
|
||||
{
|
||||
public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
||||
{
|
||||
return context.Object is HttpResponseMessage;
|
||||
}
|
||||
|
||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(
|
||||
Type declaredType,
|
||||
Type runtimeType,
|
||||
MediaTypeHeaderValue contentType)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task WriteAsync(OutputFormatterContext context)
|
||||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
|
||||
var responseMessage = context.Object as HttpResponseMessage;
|
||||
if (responseMessage == null)
|
||||
{
|
||||
var message = Resources.FormatHttpResponseMessageFormatter_UnsupportedType(
|
||||
nameof(HttpResponseMessageOutputFormatter),
|
||||
nameof(HttpResponseMessage));
|
||||
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
response.StatusCode = (int)responseMessage.StatusCode;
|
||||
|
||||
var responseFeature = context.ActionContext.HttpContext.GetFeature<IHttpResponseFeature>();
|
||||
if (responseFeature != null)
|
||||
{
|
||||
responseFeature.ReasonPhrase = responseMessage.ReasonPhrase;
|
||||
}
|
||||
|
||||
var responseHeaders = responseMessage.Headers;
|
||||
foreach (var header in responseHeaders)
|
||||
{
|
||||
response.Headers.AppendValues(header.Key, header.Value.ToArray());
|
||||
}
|
||||
|
||||
if (responseMessage.Content != null)
|
||||
{
|
||||
var contentHeaders = responseMessage.Content.Headers;
|
||||
foreach (var header in contentHeaders)
|
||||
{
|
||||
response.Headers.AppendValues(header.Key, header.Value.ToArray());
|
||||
}
|
||||
|
||||
await responseMessage.Content.CopyToAsync(response.Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,22 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
|||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("Microsoft.AspNet.Mvc.WebApiCompatShim.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// The {0} only supports writing objects of type {1}.
|
||||
/// </summary>
|
||||
internal static string HttpResponseMessageFormatter_UnsupportedType
|
||||
{
|
||||
get { return GetString("HttpResponseMessageFormatter_UnsupportedType"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The {0} only supports writing objects of type {1}.
|
||||
/// </summary>
|
||||
internal static string FormatHttpResponseMessageFormatter_UnsupportedType(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("HttpResponseMessageFormatter_UnsupportedType"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The key is invalid JQuery syntax because it is missing a closing bracket.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="HttpResponseMessageFormatter_UnsupportedType" xml:space="preserve">
|
||||
<value>The {0} only supports writing objects of type {1}.</value>
|
||||
</data>
|
||||
<data name="JQuerySyntaxMissingClosingBracket" xml:space="preserve">
|
||||
<value>The key is invalid JQuery syntax because it is missing a closing bracket.</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
|||
|
||||
// Add a model binder to be able to bind HttpRequestMessage
|
||||
options.ModelBinders.Insert(0, new HttpRequestMessageModelBinder());
|
||||
|
||||
// Add a formatter to write out an HttpResponseMessage to the response
|
||||
options.OutputFormatters.Insert(0, new HttpResponseMessageOutputFormatter());
|
||||
}
|
||||
|
||||
public void Invoke(WebApiCompatShimOptions options)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#if ASPNET50
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
|
|
@ -123,6 +124,58 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expected, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_ResponseReturned()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expected =
|
||||
"POST Hello, HttpResponseMessage world!";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(
|
||||
"http://localhost/api/Blog/HttpRequestMessage/EchoWithResponseMessage",
|
||||
new StringContent("Hello, HttpResponseMessage world!"));
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expected, content);
|
||||
|
||||
IEnumerable<string> values;
|
||||
Assert.True(response.Headers.TryGetValues("X-Test", out values));
|
||||
Assert.Equal(new string[] { "Hello!" }, values);
|
||||
Assert.Equal(38, response.Content.Headers.ContentLength);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_ResponseReturned_Chunked()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
var expected =
|
||||
"POST Hello, HttpResponseMessage world!";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(
|
||||
"http://localhost/api/Blog/HttpRequestMessage/EchoWithResponseMessageChunked",
|
||||
new StringContent("Hello, HttpResponseMessage world!"));
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expected, content);
|
||||
|
||||
IEnumerable<string> values;
|
||||
Assert.True(response.Headers.TryGetValues("X-Test", out values));
|
||||
Assert.Equal(new string[] { "Hello!" }, values);
|
||||
Assert.Equal(true, response.Headers.TransferEncodingChunked);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||
using System.Web.Http;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using System.Net;
|
||||
|
||||
namespace WebApiCompatShimWebSite
|
||||
{
|
||||
|
|
@ -29,6 +30,33 @@ namespace WebApiCompatShimWebSite
|
|||
return new EmptyResult();
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> EchoWithResponseMessage(HttpRequestMessage request)
|
||||
{
|
||||
var message = string.Format(
|
||||
"{0} {1}",
|
||||
request.Method.ToString(),
|
||||
await request.Content.ReadAsStringAsync());
|
||||
|
||||
var response = request.CreateResponse(HttpStatusCode.OK);
|
||||
response.Content = new StringContent(message);
|
||||
response.Headers.TryAddWithoutValidation("X-Test", "Hello!");
|
||||
return response;
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> EchoWithResponseMessageChunked(HttpRequestMessage request)
|
||||
{
|
||||
var message = string.Format(
|
||||
"{0} {1}",
|
||||
request.Method.ToString(),
|
||||
await request.Content.ReadAsStringAsync());
|
||||
|
||||
var response = request.CreateResponse(HttpStatusCode.OK);
|
||||
response.Content = new StringContent(message);
|
||||
response.Headers.TransferEncodingChunked = true;
|
||||
response.Headers.TryAddWithoutValidation("X-Test", "Hello!");
|
||||
return response;
|
||||
}
|
||||
|
||||
private async Task Echo(HttpRequestMessage request)
|
||||
{
|
||||
var message = string.Format(
|
||||
|
|
|
|||
Loading…
Reference in New Issue