JsonResult to use ObjectResult for content negotiation to pick default json formatter.
This commit is contained in:
parent
2920c55116
commit
bb452f19a7
|
|
@ -1,77 +1,112 @@
|
|||
// 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.IO;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class JsonResult : ActionResult
|
||||
{
|
||||
private const int BufferSize = 1024;
|
||||
private static readonly IList<MediaTypeHeaderValue> _defaultSupportedContentTypes =
|
||||
new List<MediaTypeHeaderValue>()
|
||||
{
|
||||
MediaTypeHeaderValue.Parse("application/json"),
|
||||
MediaTypeHeaderValue.Parse("text/json"),
|
||||
};
|
||||
private IOutputFormatter _defaultFormatter;
|
||||
|
||||
private JsonSerializerSettings _jsonSerializerSettings;
|
||||
private Encoding _encoding = Encodings.UTF8EncodingWithoutBOM;
|
||||
private ObjectResult _objectResult;
|
||||
|
||||
public JsonResult([NotNull] object data)
|
||||
public JsonResult(object data) :
|
||||
this(data, null)
|
||||
{
|
||||
Data = data;
|
||||
_jsonSerializerSettings = JsonOutputFormatter.CreateDefaultSettings();
|
||||
}
|
||||
|
||||
public JsonSerializerSettings SerializerSettings
|
||||
{
|
||||
get { return _jsonSerializerSettings; }
|
||||
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
|
||||
_jsonSerializerSettings = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to indent elements when writing data.
|
||||
/// Creates an instance of <see cref="JsonResult"/> class.
|
||||
/// </summary>
|
||||
public bool Indent { get; set; }
|
||||
|
||||
public Encoding Encoding
|
||||
/// <param name="data"></param>
|
||||
/// <param name="defaultFormatter">If no matching formatter is found,
|
||||
/// the response is written to using defaultFormatter.</param>
|
||||
/// <remarks>
|
||||
/// The default formatter must be able to handle either application/json
|
||||
/// or text/json.
|
||||
/// </remarks>
|
||||
public JsonResult(object data, IOutputFormatter defaultFormatter)
|
||||
{
|
||||
get { return _encoding; }
|
||||
_defaultFormatter = defaultFormatter;
|
||||
_objectResult = new ObjectResult(data);
|
||||
}
|
||||
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return _objectResult.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
|
||||
_encoding = value;
|
||||
_objectResult.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public object Data { get; private set; }
|
||||
|
||||
public override void ExecuteResult([NotNull] ActionContext context)
|
||||
public IList<MediaTypeHeaderValue> ContentTypes
|
||||
{
|
||||
var response = context.HttpContext.Response;
|
||||
var writeStream = response.Body;
|
||||
|
||||
if (response.ContentType == null)
|
||||
get
|
||||
{
|
||||
response.ContentType = "application/json";
|
||||
return _objectResult.ContentTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
_objectResult.ContentTypes = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||
{
|
||||
// Set the content type explicitly to application/json and text/json.
|
||||
// if the user has not already set it.
|
||||
if (ContentTypes == null || ContentTypes.Count == 0)
|
||||
{
|
||||
ContentTypes = _defaultSupportedContentTypes;
|
||||
}
|
||||
|
||||
using (var writer = new StreamWriter(writeStream, Encoding, BufferSize, leaveOpen: true))
|
||||
var formatterContext = new OutputFormatterContext()
|
||||
{
|
||||
var formatter = new JsonOutputFormatter(SerializerSettings, Indent);
|
||||
formatter.WriteObject(writer, Data);
|
||||
DeclaredType = _objectResult.DeclaredType,
|
||||
ActionContext = context,
|
||||
Object = Value,
|
||||
};
|
||||
|
||||
// Need to call this instead of directly calling _objectResult.ExecuteResultAsync
|
||||
// as that sets the status to 406 if a formatter is not found.
|
||||
// this can be cleaned up after https://github.com/aspnet/Mvc/issues/941 gets resolved.
|
||||
var formatter = SelectFormatter(formatterContext);
|
||||
await formatter.WriteAsync(formatterContext);
|
||||
}
|
||||
|
||||
private IOutputFormatter SelectFormatter(OutputFormatterContext formatterContext)
|
||||
{
|
||||
var defaultFormatters = formatterContext.ActionContext
|
||||
.HttpContext
|
||||
.RequestServices
|
||||
.GetService<IOutputFormattersProvider>()
|
||||
.OutputFormatters;
|
||||
|
||||
var formatter = _objectResult.SelectFormatter(formatterContext, defaultFormatters);
|
||||
if (formatter == null)
|
||||
{
|
||||
formatter = _defaultFormatter ?? formatterContext.ActionContext
|
||||
.HttpContext
|
||||
.RequestServices
|
||||
.GetService<JsonOutputFormatter>();
|
||||
}
|
||||
|
||||
return formatter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
|
|
|||
|
|
@ -79,16 +79,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var selectedEncoding = context.SelectedEncoding;
|
||||
using (var writer = new StreamWriter(response.Body, selectedEncoding, 1024, leaveOpen: true))
|
||||
{
|
||||
using (var jsonWriter = CreateJsonWriter(writer))
|
||||
{
|
||||
var jsonSerializer = CreateJsonSerializer();
|
||||
jsonSerializer.Serialize(jsonWriter, context.Object);
|
||||
|
||||
// We're explicitly calling flush here to simplify the debugging experience because the
|
||||
// underlying TextWriter might be long-lived. If this method ends up being called repeatedly
|
||||
// for a request, we should revisit.
|
||||
jsonWriter.Flush();
|
||||
}
|
||||
WriteObject(writer, context.Object);
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// with default XmlWriterSettings
|
||||
/// </summary>
|
||||
public XmlDataContractSerializerOutputFormatter()
|
||||
:this(GetDefaultXmlWriterSettings())
|
||||
: this(GetDefaultXmlWriterSettings())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
/// <param name="writerSettings">The settings to be used by the <see cref="DataContractSerializer"/>.</param>
|
||||
public XmlDataContractSerializerOutputFormatter([NotNull] XmlWriterSettings writerSettings)
|
||||
:base(writerSettings)
|
||||
: base(writerSettings)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
/// <param name="writeStream">The stream on which the XmlWriter should operate on.</param>
|
||||
/// <returns>A new instance of <see cref="XmlWriter"/></returns>
|
||||
public virtual XmlWriter CreateXmlWriter([NotNull] Stream writeStream, [NotNull] XmlWriterSettings xmlWriterSettings)
|
||||
public virtual XmlWriter CreateXmlWriter([NotNull] Stream writeStream,
|
||||
[NotNull] XmlWriterSettings xmlWriterSettings)
|
||||
{
|
||||
return XmlWriter.Create(writeStream, xmlWriterSettings);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// with default XmlWriterSettings.
|
||||
/// </summary>
|
||||
public XmlSerializerOutputFormatter()
|
||||
:this(GetDefaultXmlWriterSettings())
|
||||
: this(GetDefaultXmlWriterSettings())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
/// <param name="writerSettings">The settings to be used by the <see cref="XmlSerializer"/>.</param>
|
||||
public XmlSerializerOutputFormatter([NotNull] XmlWriterSettings writerSettings)
|
||||
:base(writerSettings)
|
||||
: base(writerSettings)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
yield return describe.Scoped<ICompositeValueProviderFactory, CompositeValueProviderFactory>();
|
||||
yield return describe.Transient<IOutputFormattersProvider, DefaultOutputFormattersProvider>();
|
||||
|
||||
yield return describe.Instance<JsonOutputFormatter>(
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), indent: false));
|
||||
|
||||
yield return describe.Transient<INestedProvider<FilterProviderContext>, DefaultFilterProvider>();
|
||||
|
||||
yield return describe.Transient<IModelValidatorProvider, DataAnnotationsModelValidatorProvider>();
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
|
||||
// Assert
|
||||
Assert.IsType<JsonResult>(actualJsonResult);
|
||||
Assert.Same(data, actualJsonResult.Data);
|
||||
Assert.Same(data, actualJsonResult.Value);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> RedirectTestData
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -18,7 +20,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
private static readonly byte[] _abcdUTF8Bytes
|
||||
= new byte[] { 123, 34, 102, 111, 111, 34, 58, 34, 97, 98, 99, 100, 34, 125 };
|
||||
|
||||
private JsonOutputFormatter _jsonformatter = new JsonOutputFormatter(
|
||||
JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false);
|
||||
[Fact]
|
||||
public async Task ExecuteResult_GeneratesResultsWithoutBOMByDefault()
|
||||
{
|
||||
|
|
@ -28,10 +32,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(r => r.Body)
|
||||
.Returns(memoryStream);
|
||||
var context = new Mock<HttpContext>();
|
||||
context.SetupGet(c => c.Response)
|
||||
.Returns(response.Object);
|
||||
var actionContext = new ActionContext(context.Object,
|
||||
var context = GetHttpContext(response.Object);
|
||||
var actionContext = new ActionContext(context,
|
||||
new RouteData(),
|
||||
new ActionDescriptor());
|
||||
var result = new JsonResult(new { foo = "abcd" });
|
||||
|
|
@ -44,7 +46,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteResult_UsesEncoderIfSpecified()
|
||||
public async Task ExecuteResult_IfNoMatchFoundUsesPassedInFormatter()
|
||||
{
|
||||
// Arrange
|
||||
var expected = Enumerable.Concat(Encoding.UTF8.GetPreamble(), _abcdUTF8Bytes);
|
||||
|
|
@ -52,16 +54,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(r => r.Body)
|
||||
.Returns(memoryStream);
|
||||
var context = new Mock<HttpContext>();
|
||||
context.SetupGet(c => c.Response)
|
||||
.Returns(response.Object);
|
||||
var actionContext = new ActionContext(context.Object,
|
||||
var context = GetHttpContext(response.Object, registerDefaultFormatter: false);
|
||||
var actionContext = new ActionContext(context,
|
||||
new RouteData(),
|
||||
new ActionDescriptor());
|
||||
var result = new JsonResult(new { foo = "abcd" })
|
||||
{
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var testFormatter = new TestJsonFormatter()
|
||||
{
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
|
||||
var result = new JsonResult(new { foo = "abcd" }, testFormatter);
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(actionContext);
|
||||
|
|
@ -69,5 +71,61 @@ namespace Microsoft.AspNet.Mvc
|
|||
// Assert
|
||||
Assert.Equal(expected, memoryStream.ToArray());
|
||||
}
|
||||
|
||||
public async Task ExecuteResult_UsesDefaultFormatter_IfNoneIsRegistered_AndNoneIsPassed()
|
||||
{
|
||||
// Arrange
|
||||
var expected = _abcdUTF8Bytes;
|
||||
var memoryStream = new MemoryStream();
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(r => r.Body)
|
||||
.Returns(memoryStream);
|
||||
var context = GetHttpContext(response.Object, registerDefaultFormatter: false);
|
||||
var actionContext = new ActionContext(context,
|
||||
new RouteData(),
|
||||
new ActionDescriptor());
|
||||
var result = new JsonResult(new { foo = "abcd" });
|
||||
|
||||
// Act
|
||||
await result.ExecuteResultAsync(actionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, memoryStream.ToArray());
|
||||
}
|
||||
|
||||
private HttpContext GetHttpContext(HttpResponse response, bool registerDefaultFormatter = true)
|
||||
{
|
||||
var defaultFormatters = registerDefaultFormatter ? new List<IOutputFormatter>() { _jsonformatter } :
|
||||
new List<IOutputFormatter>();
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var mockFormattersProvider = new Mock<IOutputFormattersProvider>();
|
||||
mockFormattersProvider.SetupGet(o => o.OutputFormatters)
|
||||
.Returns(defaultFormatters);
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(mockFormattersProvider.Object);
|
||||
httpContext.SetupGet(o => o.Request.Accept)
|
||||
.Returns("");
|
||||
httpContext.SetupGet(c => c.Response).Returns(response);
|
||||
return httpContext.Object;
|
||||
}
|
||||
|
||||
private class TestJsonFormatter : IOutputFormatter
|
||||
{
|
||||
public Encoding Encoding { get; set; }
|
||||
|
||||
public bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task WriteAsync(OutputFormatterContext context)
|
||||
{
|
||||
// Override using the selected encoding.
|
||||
context.SelectedEncoding = Encoding;
|
||||
var jsonFormatter = new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false);
|
||||
await jsonFormatter.WriteResponseBodyAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1295,7 +1295,20 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var httpContext = new Mock<HttpContext>(MockBehavior.Loose);
|
||||
var httpResponse = new Mock<HttpResponse>(MockBehavior.Loose);
|
||||
var mockFormattersProvider = new Mock<IOutputFormattersProvider>();
|
||||
mockFormattersProvider.SetupGet(o => o.OutputFormatters)
|
||||
.Returns(
|
||||
new List<IOutputFormatter>()
|
||||
{
|
||||
new JsonOutputFormatter(
|
||||
JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false)
|
||||
});
|
||||
httpContext.SetupGet(o => o.Request.Accept)
|
||||
.Returns("");
|
||||
httpContext.SetupGet(c => c.Response).Returns(httpResponse.Object);
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(mockFormattersProvider.Object);
|
||||
httpResponse.SetupGet(r => r.Body).Returns(new MemoryStream());
|
||||
|
||||
var actionContext = new ActionContext(
|
||||
|
|
|
|||
|
|
@ -184,6 +184,77 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Act
|
||||
var result = await client.GetAsync("http://localhost/ProducesContentOnClass/ReturnClassNameContentTypeOnDerivedAction");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
Assert.Equal(expectedBody, body);
|
||||
}
|
||||
[Fact]
|
||||
public async Task ProducesContentAttribute_IsNotHonored_ForJsonResult()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedBody = "{\"MethodName\":\"Produces_WithNonObjectResult\"}";
|
||||
|
||||
// Act
|
||||
var result = await client.GetAsync("http://localhost/JsonResult/Produces_WithNonObjectResult");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
Assert.Equal(expectedBody, body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonResult_UsesDefaultContentTypes_IfNoneAreAddedExplicitly()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedBody = "{\"MethodName\":\"ReturnJsonResult\"}";
|
||||
|
||||
// Act
|
||||
var result = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
Assert.Equal(expectedBody, body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonResult_UsesExplicitContentTypeAndFormatter_IfAdded()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expectedContentType = "application/custom-json;charset=utf-8";
|
||||
var expectedBody = "{ MethodName = ReturnJsonResult_WithCustomMediaType }";
|
||||
|
||||
// Act
|
||||
var result = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult_WithCustomMediaType");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
Assert.Equal(expectedBody, body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonResult_UsesDefaultJsonFormatter_IfNoMatchingFormatterIsFound()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.Handler;
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedBody = "{\"MethodName\":\"ReturnJsonResult_WithCustomMediaType_NoFormatter\"}";
|
||||
|
||||
// Act
|
||||
var result = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult_WithCustomMediaType_NoFormatter");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
// 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 Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace ConnegWebsite
|
||||
{
|
||||
public class JsonResultController : Controller
|
||||
{
|
||||
public IActionResult ReturnJsonResult()
|
||||
{
|
||||
return new JsonResult(new { MethodName = "ReturnJsonResult" });
|
||||
}
|
||||
|
||||
public IActionResult ReturnJsonResult_WithCustomMediaType()
|
||||
{
|
||||
var jsonResult = new JsonResult(new { MethodName = "ReturnJsonResult_WithCustomMediaType" },
|
||||
new CustomFormatter("application/custom-json"));
|
||||
jsonResult.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/custom-json"));
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
public IActionResult ReturnJsonResult_WithCustomMediaType_NoFormatter()
|
||||
{
|
||||
var jsonResult = new JsonResult(new { MethodName = "ReturnJsonResult_WithCustomMediaType_NoFormatter" });
|
||||
jsonResult.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/custom-json"));
|
||||
return jsonResult;
|
||||
}
|
||||
|
||||
[Produces("application/xml")]
|
||||
public IActionResult Produces_WithNonObjectResult()
|
||||
{
|
||||
return new JsonResult(new { MethodName = "Produces_WithNonObjectResult" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace ConnegWebsite
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace ConnegWebsite
|
|||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
response.ContentType = ContentType + ";charset=utf-8";
|
||||
await response.WriteAsync(context.Object as string);
|
||||
await response.WriteAsync(context.Object.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue