[Fixes #1216] Provide a property on JsonOutputFormatter to set serializer settings
[Fixes #1221] Rename OutputFormatter's WriteResponseContentHeaders to WriteResponseHeaders [Fixes #932] Setting Json Serializer Settings
This commit is contained in:
parent
ebf64ce4e3
commit
e985c22528
|
|
@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
_jsonSerializerSettings = value;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
|
@ -10,29 +11,33 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class JsonOutputFormatter : OutputFormatter
|
||||
{
|
||||
private readonly JsonSerializerSettings _settings;
|
||||
private readonly bool _indent;
|
||||
|
||||
public JsonOutputFormatter([NotNull] JsonSerializerSettings settings, bool indent)
|
||||
private JsonSerializerSettings _serializerSettings;
|
||||
|
||||
public JsonOutputFormatter()
|
||||
{
|
||||
_settings = settings;
|
||||
_indent = indent;
|
||||
SupportedEncodings.Add(Encodings.UTF8EncodingWithoutBOM);
|
||||
SupportedEncodings.Add(Encodings.UTF16EncodingLittleEndian);
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/json"));
|
||||
|
||||
_serializerSettings = new JsonSerializerSettings();
|
||||
}
|
||||
|
||||
public static JsonSerializerSettings CreateDefaultSettings()
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="JsonSerializerSettings"/> used to configure the <see cref="JsonSerializer"/>.
|
||||
/// </summary>
|
||||
public JsonSerializerSettings SerializerSettings
|
||||
{
|
||||
return new JsonSerializerSettings()
|
||||
get { return _serializerSettings; }
|
||||
set
|
||||
{
|
||||
MissingMemberHandling = MissingMemberHandling.Ignore,
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
// Do not change this setting
|
||||
// Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types.
|
||||
TypeNameHandling = TypeNameHandling.None
|
||||
};
|
||||
_serializerSettings = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteObject([NotNull] TextWriter writer, object value)
|
||||
|
|
@ -47,11 +52,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
private JsonWriter CreateJsonWriter(TextWriter writer)
|
||||
{
|
||||
var jsonWriter = new JsonTextWriter(writer);
|
||||
if (_indent)
|
||||
{
|
||||
jsonWriter.Formatting = Formatting.Indented;
|
||||
}
|
||||
|
||||
jsonWriter.CloseOutput = false;
|
||||
|
||||
return jsonWriter;
|
||||
|
|
@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
private JsonSerializer CreateJsonSerializer()
|
||||
{
|
||||
var jsonSerializer = JsonSerializer.Create(_settings);
|
||||
var jsonSerializer = JsonSerializer.Create(_serializerSettings);
|
||||
return jsonSerializer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,15 +157,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <inheritdoc />
|
||||
public async Task WriteAsync([NotNull] OutputFormatterContext context)
|
||||
{
|
||||
WriteResponseContentHeaders(context);
|
||||
WriteResponseHeaders(context);
|
||||
await WriteResponseBodyAsync(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the content-type headers with charset value to the HttpResponse.
|
||||
/// Sets the headers on <see cref="Microsoft.AspNet.Http.HttpResponse"/> object.
|
||||
/// </summary>
|
||||
/// <param name="context">The formatter context associated with the call.</param>
|
||||
public virtual void WriteResponseContentHeaders([NotNull] OutputFormatterContext context)
|
||||
public virtual void WriteResponseHeaders([NotNull] OutputFormatterContext context)
|
||||
{
|
||||
var selectedMediaType = context.SelectedContentType;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,39 +9,16 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class JsonViewComponentResult : IViewComponentResult
|
||||
{
|
||||
private JsonSerializerSettings _jsonSerializerSettings;
|
||||
|
||||
public JsonViewComponentResult([NotNull] object data)
|
||||
{
|
||||
Data = data;
|
||||
_jsonSerializerSettings = JsonOutputFormatter.CreateDefaultSettings();
|
||||
}
|
||||
|
||||
public object Data { get; private set; }
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
public bool Indent { get; set; }
|
||||
|
||||
public void Execute([NotNull] ViewComponentContext context)
|
||||
{
|
||||
var formatter = new JsonOutputFormatter(SerializerSettings, Indent);
|
||||
var formatter = new JsonOutputFormatter();
|
||||
formatter.WriteObject(context.Writer, Data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
// Set up default output formatters.
|
||||
options.OutputFormatters.Add(new HttpNoContentOutputFormatter());
|
||||
options.OutputFormatters.Add(new TextPlainFormatter());
|
||||
options.OutputFormatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false));
|
||||
options.OutputFormatters.Add(new JsonOutputFormatter());
|
||||
options.OutputFormatters.Add(
|
||||
new XmlDataContractSerializerOutputFormatter(XmlOutputFormatter.GetDefaultXmlWriterSettings()));
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,7 @@ 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.Instance<JsonOutputFormatter>(new JsonOutputFormatter());
|
||||
|
||||
yield return describe.Transient<IModelValidatorProviderProvider, DefaultModelValidatorProviderProvider>();
|
||||
yield return describe.Scoped<ICompositeModelValidatorProvider, CompositeModelValidatorProvider>();
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
result.Formatters = new List<IOutputFormatter>
|
||||
{
|
||||
new CannotWriteFormatter(),
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false),
|
||||
new JsonOutputFormatter(),
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -170,7 +170,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
result.Formatters = new List<IOutputFormatter>
|
||||
{
|
||||
new CannotWriteFormatter(),
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false),
|
||||
new JsonOutputFormatter(),
|
||||
};
|
||||
// Act
|
||||
await result.ExecuteResultAsync(actionContext);
|
||||
|
|
@ -202,7 +202,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
result.Formatters = new List<IOutputFormatter>
|
||||
{
|
||||
mockFormatter.Object,
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false),
|
||||
new JsonOutputFormatter(),
|
||||
new CannotWriteFormatter()
|
||||
};
|
||||
// Act
|
||||
|
|
@ -232,7 +232,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
result.Formatters = new List<IOutputFormatter>
|
||||
{
|
||||
new CannotWriteFormatter(),
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false),
|
||||
new JsonOutputFormatter(),
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -263,7 +263,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
result.Formatters = new List<IOutputFormatter>
|
||||
{
|
||||
new CannotWriteFormatter(),
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false),
|
||||
new JsonOutputFormatter(),
|
||||
};
|
||||
// Act
|
||||
await result.ExecuteResultAsync(actionContext);
|
||||
|
|
@ -364,7 +364,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
result.Formatters = new List<IOutputFormatter>
|
||||
{
|
||||
new CannotWriteFormatter(),
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false),
|
||||
new JsonOutputFormatter(),
|
||||
};
|
||||
// Act
|
||||
await result.ExecuteResultAsync(actionContext);
|
||||
|
|
@ -455,8 +455,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
Object = nonStringValue,
|
||||
DeclaredType = nonStringValue.GetType()
|
||||
};
|
||||
var formatter = new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false);
|
||||
formatter.WriteResponseContentHeaders(formatterContext);
|
||||
var formatter = new JsonOutputFormatter();
|
||||
formatter.WriteResponseHeaders(formatterContext);
|
||||
await formatter.WriteAsync(formatterContext);
|
||||
|
||||
// Act
|
||||
|
|
@ -559,7 +559,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
return new List<IOutputFormatter>()
|
||||
{
|
||||
new TextPlainFormatter(),
|
||||
new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), indent: false)
|
||||
new JsonOutputFormatter()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1305,9 +1305,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
.Returns(
|
||||
new List<IOutputFormatter>()
|
||||
{
|
||||
new JsonOutputFormatter(
|
||||
JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false)
|
||||
new JsonOutputFormatter()
|
||||
});
|
||||
httpContext.SetupGet(o => o.Request.Accept)
|
||||
.Returns("");
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#if ASPNET50
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
|
@ -11,12 +12,13 @@ using Microsoft.AspNet.Http;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class JsonInputFormatterTest
|
||||
{
|
||||
{
|
||||
|
||||
[Theory]
|
||||
[InlineData("application/json", true)]
|
||||
|
|
@ -64,7 +66,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
yield return new object[] { "100", typeof(int), 100 };
|
||||
yield return new object[] { "'abcd'", typeof(string), "abcd" };
|
||||
yield return new object[] { "'2012-02-01 12:45 AM'", typeof(DateTime),
|
||||
yield return new object[] { "'2012-02-01 12:45 AM'", typeof(DateTime),
|
||||
new DateTime(2012, 02, 01, 00, 45, 00) };
|
||||
}
|
||||
}
|
||||
|
|
@ -168,6 +170,72 @@ namespace Microsoft.AspNet.Mvc
|
|||
Assert.IsType<TooManyModelErrorsException>(error.Exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Creates_SerializerSettings_ByDefault()
|
||||
{
|
||||
// Arrange
|
||||
// Act
|
||||
var jsonFormatter = new JsonInputFormatter();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(jsonFormatter.SerializerSettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ChangesTo_DefaultSerializerSettings_TakesEffect()
|
||||
{
|
||||
// Arrange
|
||||
// missing password property here
|
||||
var contentBytes = Encoding.UTF8.GetBytes("{ \"UserName\" : \"John\"}");
|
||||
|
||||
var jsonFormatter = new JsonInputFormatter() { CaptureDeserilizationErrors = true };
|
||||
// by default we ignore missing members, so here explicitly changing it
|
||||
jsonFormatter.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Error;
|
||||
|
||||
var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8");
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(modelAccessor: null,
|
||||
modelType: typeof(UserLogin));
|
||||
var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType);
|
||||
|
||||
// Act
|
||||
var obj = await jsonFormatter.ReadAsync(inputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.False(actionContext.ModelState.IsValid);
|
||||
|
||||
var modelErrorMessage = actionContext.ModelState.Values.First().Errors[0].Exception.Message;
|
||||
Assert.Contains("Required property 'Password' not found in JSON", modelErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CustomSerializerSettingsObject_TakesEffect()
|
||||
{
|
||||
// Arrange
|
||||
// missing password property here
|
||||
var contentBytes = Encoding.UTF8.GetBytes("{ \"UserName\" : \"John\"}");
|
||||
|
||||
var jsonFormatter = new JsonInputFormatter() { CaptureDeserilizationErrors = true };
|
||||
// by default we ignore missing members, so here explicitly changing it
|
||||
jsonFormatter.SerializerSettings = new JsonSerializerSettings()
|
||||
{
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
};
|
||||
|
||||
var actionContext = GetActionContext(contentBytes, "application/json;charset=utf-8");
|
||||
var metadata = new EmptyModelMetadataProvider().GetMetadataForType(modelAccessor: null,
|
||||
modelType: typeof(UserLogin));
|
||||
var inputFormatterContext = new InputFormatterContext(actionContext, metadata.ModelType);
|
||||
|
||||
// Act
|
||||
var obj = await jsonFormatter.ReadAsync(inputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.False(actionContext.ModelState.IsValid);
|
||||
|
||||
var modelErrorMessage = actionContext.ModelState.Values.First().Errors[0].Exception.Message;
|
||||
Assert.Contains("Required property 'Password' not found in JSON", modelErrorMessage);
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext(byte[] contentBytes,
|
||||
string contentType = "application/xml")
|
||||
{
|
||||
|
|
@ -176,7 +244,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
new ActionDescriptor());
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(byte[] contentBytes,
|
||||
private static HttpContext GetHttpContext(byte[] contentBytes,
|
||||
string contentType = "application/json")
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
|
|
@ -197,6 +265,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public decimal Age { get; set; }
|
||||
}
|
||||
|
||||
private sealed class UserLogin
|
||||
{
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
// 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.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
||||
{
|
||||
public class JsonOutputFormatterTests
|
||||
{
|
||||
[Fact]
|
||||
public void Creates_SerializerSettings_ByDefault()
|
||||
{
|
||||
// Arrange
|
||||
// Act
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(jsonFormatter.SerializerSettings);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ChangesTo_DefaultSerializerSettings_TakesEffect()
|
||||
{
|
||||
// Arrange
|
||||
var person = new User() { Name = "John", Age = 35 };
|
||||
var expectedOutput = JsonConvert.SerializeObject(person, new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Formatting = Formatting.Indented
|
||||
});
|
||||
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
jsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
|
||||
var outputFormatterContext = GetOutputFormatterContext(person, typeof(User));
|
||||
|
||||
// Act
|
||||
await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal(expectedOutput,
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8)
|
||||
.ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CustomSerializerSettingsObject_TakesEffect()
|
||||
{
|
||||
// Arrange
|
||||
var person = new User() { Name = "John", Age = 35 };
|
||||
var expectedOutput = JsonConvert.SerializeObject(person, new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Formatting = Formatting.Indented
|
||||
});
|
||||
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
jsonFormatter.SerializerSettings = new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Formatting = Formatting.Indented
|
||||
};
|
||||
|
||||
var outputFormatterContext = GetOutputFormatterContext(person, typeof(User));
|
||||
|
||||
// Act
|
||||
await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
|
||||
var streamReader = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8);
|
||||
Assert.Equal(expectedOutput, streamReader.ReadToEnd());
|
||||
}
|
||||
|
||||
private OutputFormatterContext GetOutputFormatterContext(object outputValue, Type outputType,
|
||||
string contentType = "application/xml; charset=utf-8")
|
||||
{
|
||||
var mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType);
|
||||
|
||||
return new OutputFormatterContext
|
||||
{
|
||||
Object = outputValue,
|
||||
DeclaredType = outputType,
|
||||
ActionContext = GetActionContext(mediaTypeHeaderValue),
|
||||
SelectedEncoding = Encoding.GetEncoding(mediaTypeHeaderValue.Charset)
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext(MediaTypeHeaderValue contentType)
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
request.Setup(r => r.ContentType).Returns(contentType.RawValue);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.AcceptCharset).Returns(contentType.Charset);
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(f => f.Body).Returns(new MemoryStream());
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||
httpContext.SetupGet(c => c.Response).Returns(response.Object);
|
||||
return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null);
|
||||
}
|
||||
|
||||
private sealed class User
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Age { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(
|
||||
() => testFormatter.WriteResponseContentHeaders(formatterContext));
|
||||
() => testFormatter.WriteResponseHeaders(formatterContext));
|
||||
Assert.Equal("No encoding found for output formatter " +
|
||||
"'Microsoft.AspNet.Mvc.Test.OutputFormatterTests+TestOutputFormatter'." +
|
||||
" There must be at least one supported encoding registered in order for the" +
|
||||
|
|
@ -111,7 +111,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
formatterContext.ActionContext = actionContext;
|
||||
|
||||
// Act
|
||||
testFormatter.WriteResponseContentHeaders(formatterContext);
|
||||
testFormatter.WriteResponseHeaders(formatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Encodings.UTF16EncodingLittleEndian.WebName, formatterContext.SelectedEncoding.WebName);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ 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()
|
||||
{
|
||||
|
|
@ -95,7 +93,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
private HttpContext GetHttpContext(HttpResponse response, bool registerDefaultFormatter = true)
|
||||
{
|
||||
var defaultFormatters = registerDefaultFormatter ? new List<IOutputFormatter>() { _jsonformatter } :
|
||||
var defaultFormatters = registerDefaultFormatter ? new List<IOutputFormatter>() { new JsonOutputFormatter() } :
|
||||
new List<IOutputFormatter>();
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var mockFormattersProvider = new Mock<IOutputFormattersProvider>();
|
||||
|
|
@ -129,8 +127,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Override using the selected encoding.
|
||||
context.SelectedEncoding = Encoding;
|
||||
var jsonFormatter = new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false);
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
await jsonFormatter.WriteResponseBodyAsync(context);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using System.Threading.Tasks;
|
|||
using BasicWebSite;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
|
|
@ -186,6 +187,29 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JsonViewComponent_RendersJson()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = new HttpClient(server.CreateHandler(), false);
|
||||
var expectedBody = JsonConvert.SerializeObject(new BasicWebSite.Models.Person()
|
||||
{
|
||||
Id = 10,
|
||||
Name = "John"
|
||||
});
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("https://localhost/Home/JsonTextInView");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("text/html", response.Content.Headers.ContentType.MediaType);
|
||||
|
||||
var actualBody = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedBody, actualBody);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> HtmlHelperLinkGenerationData
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|||
using ConnegWebsite;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public class JsonOutputFormatterTests
|
||||
{
|
||||
private readonly IServiceProvider _provider = TestHelper.CreateServices("FormatterWebSite");
|
||||
private readonly Action<IApplicationBuilder> _app = new FormatterWebSite.Startup().Configure;
|
||||
|
||||
[Fact]
|
||||
public async Task JsonOutputFormatter_ReturnsIndentedJson()
|
||||
{
|
||||
// Arrange
|
||||
var user = new FormatterWebSite.User()
|
||||
{
|
||||
Id = 1,
|
||||
Alias = "john",
|
||||
description = "Administrator",
|
||||
Designation = "Administrator",
|
||||
Name = "John Williams"
|
||||
};
|
||||
|
||||
var serializerSettings = new JsonSerializerSettings();
|
||||
serializerSettings.Formatting = Formatting.Indented;
|
||||
var expectedBody = JsonConvert.SerializeObject(user, serializerSettings);
|
||||
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/JsonFormatter/ReturnsIndentedJson");
|
||||
|
||||
// Assert
|
||||
var actualBody = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(expectedBody, actualBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,9 +28,7 @@ namespace ApiExplorer
|
|||
typeof(ApiExplorerVisbilityDisabledByConventionController)));
|
||||
|
||||
options.OutputFormatters.Clear();
|
||||
options.OutputFormatters.Add(new JsonOutputFormatter(
|
||||
JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false));
|
||||
options.OutputFormatters.Add(new JsonOutputFormatter());
|
||||
options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
using BasicWebSite.Models;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace BasicWebSite.Components
|
||||
{
|
||||
[ViewComponent(Name = "JsonTextInView")]
|
||||
public class JsonTextInView : ViewComponent
|
||||
{
|
||||
public IViewComponentResult Invoke()
|
||||
{
|
||||
return Json(new Person()
|
||||
{
|
||||
Id = 10,
|
||||
Name = "John"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,5 +55,10 @@ namespace BasicWebSite.Controllers
|
|||
Context.Response.StatusCode = 204;
|
||||
await Context.Response.WriteAsync("Hello world");
|
||||
}
|
||||
|
||||
public IActionResult JsonTextInView()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace BasicWebSite.Models
|
||||
{
|
||||
public class Person
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
@Component.Invoke("JsonTextInView")
|
||||
|
|
@ -28,7 +28,7 @@ namespace ConnegWebsite
|
|||
// JsonOutputFormatter cannot write in the first attempt because it does not support the
|
||||
// request content type.
|
||||
objectResult.Formatters.Add(new PlainTextFormatter());
|
||||
objectResult.Formatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false));
|
||||
objectResult.Formatters.Add(new JsonOutputFormatter());
|
||||
|
||||
return objectResult;
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ namespace ConnegWebsite
|
|||
var objectResult = new ObjectResult(input);
|
||||
objectResult.Formatters.Add(new HttpNotAcceptableOutputFormatter());
|
||||
objectResult.Formatters.Add(new PlainTextFormatter());
|
||||
objectResult.Formatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(), false));
|
||||
objectResult.Formatters.Add(new JsonOutputFormatter());
|
||||
return objectResult;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace ConnegWebsite
|
||||
{
|
||||
|
|
@ -15,8 +17,10 @@ namespace ConnegWebsite
|
|||
{
|
||||
result.Formatters.Add(new PlainTextFormatter());
|
||||
result.Formatters.Add(new CustomFormatter("application/custom"));
|
||||
result.Formatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: true));
|
||||
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
jsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
|
||||
result.Formatters.Add(jsonFormatter);
|
||||
}
|
||||
|
||||
base.OnActionExecuted(context);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace FormatterWebSite.Controllers
|
||||
{
|
||||
public class JsonFormatterController : Controller
|
||||
{
|
||||
public IActionResult ReturnsIndentedJson()
|
||||
{
|
||||
var user = new User()
|
||||
{
|
||||
Id = 1,
|
||||
Alias = "john",
|
||||
description = "Administrator",
|
||||
Designation = "Administrator",
|
||||
Name = "John Williams"
|
||||
};
|
||||
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
jsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
|
||||
|
||||
var objectResult = new ObjectResult(user);
|
||||
objectResult.Formatters.Add(jsonFormatter);
|
||||
|
||||
return objectResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue