[Fixes #2190] Remove GetSupportedContentTypes method from IOutputFormatter and move to a separate metadata interface
This commit is contained in:
parent
52c1c20967
commit
ee4ffea294
|
|
@ -170,12 +170,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
foreach (var formatter in formatters)
|
foreach (var formatter in formatters)
|
||||||
{
|
{
|
||||||
var supportedContentTypes = formatter.GetSupportedContentTypes(
|
if (formatter.CanWriteResult(formatterContext, contentType: null))
|
||||||
formatterContext.DeclaredType,
|
|
||||||
formatterContext.Object?.GetType(),
|
|
||||||
contentType: null);
|
|
||||||
|
|
||||||
if (formatter.CanWriteResult(formatterContext, supportedContentTypes?.FirstOrDefault()))
|
|
||||||
{
|
{
|
||||||
return formatter;
|
return formatter;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -296,16 +296,24 @@ namespace Microsoft.AspNet.Mvc.Description
|
||||||
{
|
{
|
||||||
foreach (var formatter in formatters)
|
foreach (var formatter in formatters)
|
||||||
{
|
{
|
||||||
var supportedTypes = formatter.GetSupportedContentTypes(declaredType, runtimeType, contentType);
|
var responseFormatMetadataProvider = formatter as IApiResponseFormatMetadataProvider;
|
||||||
if (supportedTypes != null)
|
if (responseFormatMetadataProvider != null)
|
||||||
{
|
{
|
||||||
foreach (var supportedType in supportedTypes)
|
var supportedTypes = responseFormatMetadataProvider.GetSupportedContentTypes(
|
||||||
|
declaredType,
|
||||||
|
runtimeType,
|
||||||
|
contentType);
|
||||||
|
|
||||||
|
if (supportedTypes != null)
|
||||||
{
|
{
|
||||||
results.Add(new ApiResponseFormat()
|
foreach (var supportedType in supportedTypes)
|
||||||
{
|
{
|
||||||
Formatter = formatter,
|
results.Add(new ApiResponseFormat()
|
||||||
MediaType = supportedType,
|
{
|
||||||
});
|
Formatter = formatter,
|
||||||
|
MediaType = supportedType,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// 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 Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Description
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides metadata information about the response format to an <see cref="IApiDescriptionProvider"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// An <see cref="IOutputFormatter"/> should implement this interface to expose metadata information
|
||||||
|
/// to an <see cref="IApiDescriptionProvider"/>.
|
||||||
|
/// </remarks>
|
||||||
|
public interface IApiResponseFormatMetadataProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a filtered list of content types which are supported by the <see cref="IOutputFormatter"/>
|
||||||
|
/// for the <paramref name="declaredType"/> and <paramref name="contentType"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="declaredType">The declared type for which the supported content types are desired.</param>
|
||||||
|
/// <param name="runtimeType">The runtime type for which the supported content types are desired.</param>
|
||||||
|
/// <param name="contentType">
|
||||||
|
/// The content type for which the supported content types are desired, or <c>null</c> if any content
|
||||||
|
/// type can be used.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>Content types which are supported by the <see cref="IOutputFormatter"/>.</returns>
|
||||||
|
IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(
|
||||||
|
Type declaredType,
|
||||||
|
Type runtimeType,
|
||||||
|
MediaTypeHeaderValue contentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,14 +33,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
return TreatNullValueAsNoContent && context.Object == null;
|
return TreatNullValueAsNoContent && context.Object == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(
|
|
||||||
Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task WriteAsync(OutputFormatterContext context)
|
public Task WriteAsync(OutputFormatterContext context)
|
||||||
{
|
{
|
||||||
var response = context.ActionContext.HttpContext.Response;
|
var response = context.ActionContext.HttpContext.Response;
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
return context.FailedContentNegotiation ?? false;
|
return context.FailedContentNegotiation ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task WriteAsync(OutputFormatterContext context)
|
public Task WriteAsync(OutputFormatterContext context)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,31 +13,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IOutputFormatter
|
public interface IOutputFormatter
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets a filtered list of content types which are supported by this formatter
|
|
||||||
/// for the <paramref name="declaredType"/> and <paramref name="contentType"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="declaredType">The declared type for which the supported content types are desired.</param>
|
|
||||||
/// <param name="runtimeType">The runtime type for which the supported content types are desired.</param>
|
|
||||||
/// <param name="contentType">
|
|
||||||
/// The content type for which the supported content types are desired, or <c>null</c> if any content
|
|
||||||
/// type can be used.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>Content types which are supported by this formatter.</returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// If the value of <paramref name="contentType"/> is <c>null</c>, then the formatter should return a list
|
|
||||||
/// of all content types that it can produce for the given data type. This may occur during content
|
|
||||||
/// negotiation when the HTTP Accept header is not specified, or when no match for the value in the Accept
|
|
||||||
/// header can be found.
|
|
||||||
///
|
|
||||||
/// If the value of <paramref name="contentType"/> is not <c>null</c>, then the formatter should return
|
|
||||||
/// a list of all content types that it can produce which match the given data type and content type.
|
|
||||||
/// </remarks>
|
|
||||||
IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(
|
|
||||||
Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether this <see cref="IOutputFormatter"/> can serialize
|
/// Determines whether this <see cref="IOutputFormatter"/> can serialize
|
||||||
/// an object of the specified type.
|
/// an object of the specified type.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
|
using Microsoft.AspNet.Mvc.Description;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes an object to the output stream.
|
/// Writes an object to the output stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class OutputFormatter : IOutputFormatter
|
public abstract class OutputFormatter : IOutputFormatter, IApiResponseFormatMetadataProvider
|
||||||
{
|
{
|
||||||
// using a field so we can return it as both IList and IReadOnlyList
|
// using a field so we can return it as both IList and IReadOnlyList
|
||||||
private readonly List<MediaTypeHeaderValue> _supportedMediaTypes;
|
private readonly List<MediaTypeHeaderValue> _supportedMediaTypes;
|
||||||
|
|
|
||||||
|
|
@ -15,32 +15,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StreamOutputFormatter : IOutputFormatter
|
public class StreamOutputFormatter : IOutputFormatter
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Echos the <paramref name="contentType"/> if the <paramref name="runtimeType"/> implements
|
|
||||||
/// <see cref="Stream"/> and <paramref name="contentType"/> is not <c>null</c>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="declaredType">The declared type for which the supported content types are desired.</param>
|
|
||||||
/// <param name="runtimeType">The runtime type for which the supported content types are desired.</param>
|
|
||||||
/// <param name="contentType">
|
|
||||||
/// The content type for which the supported content types are desired, or <c>null</c> if any content
|
|
||||||
/// type can be used.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>Content types which are supported by this formatter.</returns>
|
|
||||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(
|
|
||||||
Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType)
|
|
||||||
{
|
|
||||||
if (contentType != null &&
|
|
||||||
runtimeType != null &&
|
|
||||||
typeof(Stream).IsAssignableFrom(runtimeType))
|
|
||||||
{
|
|
||||||
return new[] { contentType };
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool CanWriteResult([NotNull] OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
public bool CanWriteResult([NotNull] OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,6 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
||||||
return context.Object is HttpResponseMessage;
|
return context.Object is HttpResponseMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(
|
|
||||||
Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task WriteAsync(OutputFormatterContext context)
|
public async Task WriteAsync(OutputFormatterContext context)
|
||||||
{
|
{
|
||||||
var response = context.ActionContext.HttpContext.Response;
|
var response = context.ActionContext.HttpContext.Response;
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
(string acceptHeader)
|
(string acceptHeader)
|
||||||
{
|
{
|
||||||
// For no accept headers,
|
// For no accept headers,
|
||||||
// can write is called twice once for the request media type and once for the type match pass.
|
// can write is called twice once for the request Content-Type and once for the type match pass.
|
||||||
// For each additional accept header, it is called once.
|
// For each additional accept header, it is called once.
|
||||||
// Arrange
|
// Arrange
|
||||||
var acceptHeaderCollection = string.IsNullOrEmpty(acceptHeader) ?
|
var acceptHeaderCollection = string.IsNullOrEmpty(acceptHeader) ?
|
||||||
|
|
@ -332,7 +332,6 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
var actionContext = CreateMockActionContext(httpResponse.Object,
|
var actionContext = CreateMockActionContext(httpResponse.Object,
|
||||||
requestAcceptHeader: acceptHeader,
|
requestAcceptHeader: acceptHeader,
|
||||||
requestContentType: "application/xml");
|
requestContentType: "application/xml");
|
||||||
var requestContentType = MediaTypeHeaderValue.Parse("application/xml");
|
|
||||||
var input = "testInput";
|
var input = "testInput";
|
||||||
var result = new ObjectResult(input);
|
var result = new ObjectResult(input);
|
||||||
var mockCountingFormatter = new Mock<IOutputFormatter>();
|
var mockCountingFormatter = new Mock<IOutputFormatter>();
|
||||||
|
|
@ -345,16 +344,11 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
};
|
};
|
||||||
var mockCountingSupportedContentType = MediaTypeHeaderValue.Parse("application/text");
|
var mockCountingSupportedContentType = MediaTypeHeaderValue.Parse("application/text");
|
||||||
mockCountingFormatter.Setup(o => o.CanWriteResult(context,
|
mockCountingFormatter.Setup(o => o.CanWriteResult(context,
|
||||||
It.IsNotIn<MediaTypeHeaderValue>(mockCountingSupportedContentType)))
|
It.Is<MediaTypeHeaderValue>(mth => mth == null)))
|
||||||
.Returns(false);
|
.Returns(true);
|
||||||
mockCountingFormatter.Setup(o => o.CanWriteResult(context, mockCountingSupportedContentType))
|
mockCountingFormatter.Setup(o => o.CanWriteResult(context, mockCountingSupportedContentType))
|
||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
mockCountingFormatter.Setup(o => o.GetSupportedContentTypes(context.DeclaredType,
|
|
||||||
input.GetType(),
|
|
||||||
It.IsAny<MediaTypeHeaderValue>()))
|
|
||||||
.Returns(new List<MediaTypeHeaderValue> { mockCountingSupportedContentType });
|
|
||||||
|
|
||||||
// Set more than one formatters. The test output formatter throws on write.
|
// Set more than one formatters. The test output formatter throws on write.
|
||||||
result.Formatters = new List<IOutputFormatter>
|
result.Formatters = new List<IOutputFormatter>
|
||||||
{
|
{
|
||||||
|
|
@ -367,10 +361,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(mockCountingFormatter.Object, formatter);
|
Assert.Equal(mockCountingFormatter.Object, formatter);
|
||||||
mockCountingFormatter.Verify(v => v.CanWriteResult(context,
|
mockCountingFormatter.Verify(v => v.CanWriteResult(context, null), Times.Once());
|
||||||
mockCountingSupportedContentType),
|
|
||||||
Times.Once());
|
// CanWriteResult is invoked for the following cases:
|
||||||
var callCount = (acceptHeaderCollection == null ? 0 : acceptHeaderCollection.Count()) + 1;
|
// 1. For each accept header present
|
||||||
|
// 2. Request Content-Type
|
||||||
|
// 3. Type based match
|
||||||
|
var callCount = (acceptHeaderCollection == null ? 0 : acceptHeaderCollection.Count()) + 2;
|
||||||
mockCountingFormatter.Verify(v => v.CanWriteResult(context,
|
mockCountingFormatter.Verify(v => v.CanWriteResult(context,
|
||||||
It.IsNotIn<MediaTypeHeaderValue>(mockCountingSupportedContentType)),
|
It.IsNotIn<MediaTypeHeaderValue>(mockCountingSupportedContentType)),
|
||||||
Times.Exactly(callCount));
|
Times.Exactly(callCount));
|
||||||
|
|
@ -770,7 +767,70 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
var actual = new StreamReader(responseStream).ReadToEnd();
|
var actual = new StreamReader(responseStream).ReadToEnd();
|
||||||
Assert.Equal(expectedData, actual);
|
Assert.Equal(expectedData, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ObjectResult_WithStream_DoesNotSetContentType_IfNotProvided()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var objectResult = new ObjectResult(new MemoryStream(Encoding.UTF8.GetBytes("Name=James")));
|
||||||
|
var outputFormatters = new IOutputFormatter[]
|
||||||
|
{
|
||||||
|
new StreamOutputFormatter(),
|
||||||
|
new JsonOutputFormatter()
|
||||||
|
};
|
||||||
|
var response = new Mock<HttpResponse>();
|
||||||
|
var responseStream = new MemoryStream();
|
||||||
|
response.SetupGet(r => r.Body).Returns(responseStream);
|
||||||
|
var expectedData = "Name=James";
|
||||||
|
|
||||||
|
var actionContext = CreateMockActionContext(
|
||||||
|
outputFormatters,
|
||||||
|
response.Object,
|
||||||
|
requestAcceptHeader: null,
|
||||||
|
requestContentType: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await objectResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.VerifySet(r => r.ContentType = It.IsAny<string>(), Times.Never());
|
||||||
|
responseStream.Position = 0;
|
||||||
|
var actual = new StreamReader(responseStream).ReadToEnd();
|
||||||
|
Assert.Equal(expectedData, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ObjectResult_WithStream_SetsExplicitContentType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var objectResult = new ObjectResult(new MemoryStream(Encoding.UTF8.GetBytes("Name=James")));
|
||||||
|
objectResult.ContentTypes.Add(new MediaTypeHeaderValue("application/foo"));
|
||||||
|
var outputFormatters = new IOutputFormatter[]
|
||||||
|
{
|
||||||
|
new StreamOutputFormatter(),
|
||||||
|
new JsonOutputFormatter()
|
||||||
|
};
|
||||||
|
var response = new Mock<HttpResponse>();
|
||||||
|
var responseStream = new MemoryStream();
|
||||||
|
response.SetupGet(r => r.Body).Returns(responseStream);
|
||||||
|
var expectedData = "Name=James";
|
||||||
|
|
||||||
|
var actionContext = CreateMockActionContext(
|
||||||
|
outputFormatters,
|
||||||
|
response.Object,
|
||||||
|
requestAcceptHeader: "application/json",
|
||||||
|
requestContentType: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await objectResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.VerifySet(r => r.ContentType = "application/foo");
|
||||||
|
responseStream.Position = 0;
|
||||||
|
var actual = new StreamReader(responseStream).ReadToEnd();
|
||||||
|
Assert.Equal(expectedData, actual);
|
||||||
|
}
|
||||||
|
|
||||||
private static ActionContext CreateMockActionContext(
|
private static ActionContext CreateMockActionContext(
|
||||||
HttpResponse response = null,
|
HttpResponse response = null,
|
||||||
string requestAcceptHeader = "application/*",
|
string requestAcceptHeader = "application/*",
|
||||||
|
|
@ -871,13 +931,6 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Task WriteAsync(OutputFormatterContext context)
|
public virtual Task WriteAsync(OutputFormatterContext context)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
||||||
|
|
@ -11,36 +11,51 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public class StreamOutputFormatterTest
|
public class StreamOutputFormatterTest
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(typeof(Stream), typeof(FileStream), "text/plain", "text/plain")]
|
[InlineData(typeof(Stream), "text/plain")]
|
||||||
[InlineData(typeof(object), typeof(FileStream), "text/plain", "text/plain")]
|
[InlineData(typeof(Stream), null)]
|
||||||
[InlineData(typeof(object), typeof(MemoryStream), "text/plain", "text/plain")]
|
[InlineData(typeof(object), "text/plain")]
|
||||||
[InlineData(typeof(object), typeof(object), "text/plain", null)]
|
[InlineData(typeof(object), null)]
|
||||||
[InlineData(typeof(object), typeof(string), "text/plain", null)]
|
[InlineData(typeof(IActionResult), "text/plain")]
|
||||||
[InlineData(typeof(object), null, "text/plain", null)]
|
[InlineData(typeof(IActionResult), null)]
|
||||||
[InlineData(typeof(IActionResult), null, "text/plain", null)]
|
public void CanWriteResult_ReturnsTrue_ForStreams(Type declaredType, string contentType)
|
||||||
[InlineData(typeof(IActionResult), typeof(IActionResult), "text/plain", null)]
|
|
||||||
public void GetSupportedContentTypes_ReturnsAppropriateValues(Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
string contentType,
|
|
||||||
string expected)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var formatter = new StreamOutputFormatter();
|
var formatter = new StreamOutputFormatter();
|
||||||
var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
|
var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
|
||||||
|
var formatterContext = new OutputFormatterContext()
|
||||||
|
{
|
||||||
|
DeclaredType = declaredType,
|
||||||
|
Object = new MemoryStream()
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var contentTypes = formatter.GetSupportedContentTypes(declaredType, runtimeType, contentTypeHeader);
|
var canWrite = formatter.CanWriteResult(formatterContext, contentTypeHeader);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
if (expected == null)
|
Assert.True(canWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(typeof(object), "text/plain")]
|
||||||
|
[InlineData(typeof(object), null)]
|
||||||
|
[InlineData(typeof(SimplePOCO), "text/plain")]
|
||||||
|
[InlineData(typeof(SimplePOCO), null)]
|
||||||
|
public void CanWriteResult_OnlyActsOnStreams_IgnoringContentType(Type declaredType, string contentType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formatter = new StreamOutputFormatter();
|
||||||
|
var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType);
|
||||||
|
var formatterContext = new OutputFormatterContext()
|
||||||
{
|
{
|
||||||
Assert.Null(contentTypes);
|
DeclaredType = declaredType,
|
||||||
}
|
Object = new SimplePOCO()
|
||||||
else
|
};
|
||||||
{
|
|
||||||
Assert.Equal(1, contentTypes.Count);
|
// Act
|
||||||
Assert.Equal(expected, contentTypes[0].ToString());
|
var canWrite = formatter.CanWriteResult(formatterContext, contentTypeHeader);
|
||||||
}
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(canWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,6 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes(Type declaredType,
|
|
||||||
Type runtimeType,
|
|
||||||
MediaTypeHeaderValue contentType)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task WriteAsync(OutputFormatterContext context)
|
public Task WriteAsync(OutputFormatterContext context)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue