Changes to enable XML Output Formatters.
- Unit / Functional tests for the same.
This commit is contained in:
parent
1a4bd25e0f
commit
2920c55116
4
Mvc.sln
4
Mvc.sln
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.21902.1
|
||||
VisualStudioVersion = 14.0.22013.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
|
||||
EndProject
|
||||
|
|
@ -67,7 +67,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
ProjectSection(SolutionItems) = preProject
|
||||
global.json = global.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ConnegWebsite", "test\WebSites\ConnegWebSite\ConnegWebsite.kproj", "{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AntiForgeryWebSite", "test\WebSites\AntiForgeryWebSite\AntiForgeryWebSite.kproj", "{A353B17E-A940-4CE8-8BF9-179E24A9041F}"
|
||||
EndProject
|
||||
Global
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// 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.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// This class handles serialization of objects
|
||||
/// to XML using <see cref="DataContractSerializer"/>
|
||||
/// </summary>
|
||||
public class XmlDataContractSerializerOutputFormatter : XmlOutputFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="XmlDataContractSerializerOutputFormatter"/>
|
||||
/// with default XmlWriterSettings
|
||||
/// </summary>
|
||||
public XmlDataContractSerializerOutputFormatter()
|
||||
:this(GetDefaultXmlWriterSettings())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="XmlDataContractSerializerOutputFormatter"/>
|
||||
/// </summary>
|
||||
/// <param name="writerSettings">The settings to be used by the <see cref="DataContractSerializer"/>.</param>
|
||||
public XmlDataContractSerializerOutputFormatter([NotNull] XmlWriterSettings writerSettings)
|
||||
:base(writerSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of <see cref="DataContractSerializer"/> for the given object type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of object for which the serializer should be created.</param>
|
||||
/// <returns>A new instance of <see cref="DataContractSerializer"/></returns>
|
||||
public virtual DataContractSerializer CreateDataContractSerializer([NotNull] Type type)
|
||||
{
|
||||
return new DataContractSerializer(type);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task WriteResponseBodyAsync([NotNull] OutputFormatterContext context)
|
||||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
|
||||
var tempWriterSettings = WriterSettings.Clone();
|
||||
tempWriterSettings.Encoding = context.SelectedEncoding;
|
||||
using (var xmlWriter = CreateXmlWriter(response.Body, tempWriterSettings))
|
||||
{
|
||||
var dataContractSerializer = CreateDataContractSerializer(context.DeclaredType);
|
||||
dataContractSerializer.WriteObject(xmlWriter, context.Object);
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// 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.IO;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class from which all XML Output Formatters derive from.
|
||||
/// </summary>
|
||||
public abstract class XmlOutputFormatter : OutputFormatter
|
||||
{
|
||||
public XmlOutputFormatter([NotNull] XmlWriterSettings xmlWriterSettings)
|
||||
{
|
||||
SupportedEncodings.Add(Encodings.UTF8EncodingWithoutBOM);
|
||||
SupportedEncodings.Add(Encodings.UTF16EncodingLittleEndian);
|
||||
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/xml"));
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/xml"));
|
||||
|
||||
WriterSettings = xmlWriterSettings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the settings to be used by the XmlWriter.
|
||||
/// </summary>
|
||||
public XmlWriterSettings WriterSettings { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default XmlWriterSettings.
|
||||
/// </summary>
|
||||
/// <returns>Default <see cref="XmlWriterSettings"/></returns>
|
||||
public static XmlWriterSettings GetDefaultXmlWriterSettings()
|
||||
{
|
||||
return new XmlWriterSettings
|
||||
{
|
||||
OmitXmlDeclaration = true,
|
||||
CloseOutput = false,
|
||||
CheckCharacters = false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="XmlWriter"/> using the given stream and the WriterSettings.
|
||||
/// </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)
|
||||
{
|
||||
return XmlWriter.Create(writeStream, xmlWriterSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// 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.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// This class handles serialization of objects
|
||||
/// to XML using <see cref="XmlSerializer"/>
|
||||
/// </summary>
|
||||
public class XmlSerializerOutputFormatter : XmlOutputFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="XmlSerializerOutputFormatter"/>
|
||||
/// with default XmlWriterSettings.
|
||||
/// </summary>
|
||||
public XmlSerializerOutputFormatter()
|
||||
:this(GetDefaultXmlWriterSettings())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="XmlSerializerOutputFormatter"/>
|
||||
/// </summary>
|
||||
/// <param name="writerSettings">The settings to be used by the <see cref="XmlSerializer"/>.</param>
|
||||
public XmlSerializerOutputFormatter([NotNull] XmlWriterSettings writerSettings)
|
||||
:base(writerSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of <see cref="XmlSerializer"/> for the given object type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of object for which the serializer should be created.</param>
|
||||
/// <returns>A new instance of <see cref="XmlSerializer"/></returns>
|
||||
public virtual XmlSerializer CreateXmlSerializer([NotNull] Type type)
|
||||
{
|
||||
return new XmlSerializer(type);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task WriteResponseBodyAsync([NotNull] OutputFormatterContext context)
|
||||
{
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
|
||||
var tempWriterSettings = WriterSettings.Clone();
|
||||
tempWriterSettings.Encoding = context.SelectedEncoding;
|
||||
using (var xmlWriter = CreateXmlWriter(response.Body, tempWriterSettings))
|
||||
{
|
||||
var xmlSerializer = CreateXmlSerializer(context.DeclaredType);
|
||||
xmlSerializer.Serialize(xmlWriter, context.Object);
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
options.OutputFormatters.Add(new TextPlainFormatter());
|
||||
options.OutputFormatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
|
||||
indent: false));
|
||||
options.OutputFormatters.Add(
|
||||
new XmlDataContractSerializerOutputFormatter(XmlOutputFormatter.GetDefaultXmlWriterSettings()));
|
||||
options.OutputFormatters.Add(
|
||||
new XmlSerializerOutputFormatter(XmlOutputFormatter.GetDefaultXmlWriterSettings()));
|
||||
|
||||
// Set up ValueProviders
|
||||
options.ValueProviderFactories.Add(new RouteValueValueProviderFactory());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,209 @@
|
|||
// 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.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Core
|
||||
{
|
||||
public class XmlDataContractSerializerOutputFormatterTests
|
||||
{
|
||||
[DataContract(Name = "DummyClass", Namespace = "")]
|
||||
public class DummyClass
|
||||
{
|
||||
[DataMember]
|
||||
public int SampleInt { get; set; }
|
||||
}
|
||||
|
||||
[DataContract(Name = "TestLevelOne", Namespace = "")]
|
||||
public class TestLevelOne
|
||||
{
|
||||
[DataMember]
|
||||
public int SampleInt { get; set; }
|
||||
[DataMember]
|
||||
public string sampleString;
|
||||
}
|
||||
|
||||
[DataContract(Name = "TestLevelTwo", Namespace = "")]
|
||||
public class TestLevelTwo
|
||||
{
|
||||
[DataMember]
|
||||
public string SampleString { get; set; }
|
||||
[DataMember]
|
||||
public TestLevelOne TestOne { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlDataContractSerializerOutputFormatterWritesSimpleTypes()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8)
|
||||
.ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlDataContractSerializerOutputFormatterWritesComplexTypes()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new TestLevelTwo
|
||||
{
|
||||
SampleString = "TestString",
|
||||
TestOne = new TestLevelOne
|
||||
{
|
||||
SampleInt = 10,
|
||||
sampleString = "TestLevelOne string"
|
||||
}
|
||||
};
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<TestLevelTwo xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleString>TestString</SampleString>" +
|
||||
"<TestOne><SampleInt>10</SampleInt><sampleString>TestLevelOne string</sampleString>" +
|
||||
"</TestOne></TestLevelTwo>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8)
|
||||
.ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlDataContractSerializerOutputFormatterWritesOnModifiedWriterSettings()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter(
|
||||
new System.Xml.XmlWriterSettings
|
||||
{
|
||||
OmitXmlDeclaration = false,
|
||||
CloseOutput = false
|
||||
});
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8).ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlDataContractSerializerOutputFormatterWritesUTF16Output()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType(),
|
||||
"application/xml; charset=utf-16");
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
formatter.WriterSettings.OmitXmlDeclaration = false;
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
|
||||
"<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body,
|
||||
Encodings.UTF16EncodingLittleEndian).ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlDataContractSerializerOutputFormatterWritesIndentedOutput()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
formatter.WriterSettings.Indent = true;
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
var outputString = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body,
|
||||
Encoding.UTF8).ReadToEnd();
|
||||
Assert.Equal("<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
"\r\n <SampleInt>10</SampleInt>\r\n</DummyClass>",
|
||||
outputString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task VerifyBodyIsNotClosedAfterOutputIsWritten()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlDataContractSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
||||
}
|
||||
|
||||
private OutputFormatterContext GetOutputFormatterContext(object outputValue, Type outputType,
|
||||
string contentType = "application/xml; charset=utf-8")
|
||||
{
|
||||
return new OutputFormatterContext
|
||||
{
|
||||
Object = outputValue,
|
||||
DeclaredType = outputType,
|
||||
ActionContext = GetActionContext(contentType)
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext(string contentType)
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
request.Setup(r => r.ContentType).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.AcceptCharset).Returns(contentType.Split('=')[1]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
// 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 System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Core
|
||||
{
|
||||
public class XmlSerializerOutputFormatterTests
|
||||
{
|
||||
public class DummyClass
|
||||
{
|
||||
public int SampleInt { get; set; }
|
||||
}
|
||||
|
||||
public class TestLevelOne
|
||||
{
|
||||
public int SampleInt { get; set; }
|
||||
public string sampleString;
|
||||
}
|
||||
|
||||
public class TestLevelTwo
|
||||
{
|
||||
public string SampleString { get; set; }
|
||||
public TestLevelOne TestOne { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlSerializerOutputFormatterWritesSimpleTypes()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8)
|
||||
.ReadToEnd());
|
||||
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlSerializerOutputFormatterWritesComplexTypes()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new TestLevelTwo
|
||||
{
|
||||
SampleString = "TestString",
|
||||
TestOne = new TestLevelOne
|
||||
{
|
||||
SampleInt = 10,
|
||||
sampleString = "TestLevelOne string"
|
||||
}
|
||||
};
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<TestLevelTwo xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleString>TestString</SampleString>" +
|
||||
"<TestOne><sampleString>TestLevelOne string</sampleString>" +
|
||||
"<SampleInt>10</SampleInt></TestOne></TestLevelTwo>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8)
|
||||
.ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlSerializerOutputFormatterWritesOnModifiedWriterSettings()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
new System.Xml.XmlWriterSettings
|
||||
{
|
||||
OmitXmlDeclaration = false,
|
||||
CloseOutput = false
|
||||
});
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body, Encoding.UTF8)
|
||||
.ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlSerializerOutputFormatterWritesUTF16Output()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var outputFormatterContext =
|
||||
GetOutputFormatterContext(sampleInput, sampleInput.GetType(), "application/xml; charset=utf-16");
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
formatter.WriterSettings.OmitXmlDeclaration = false;
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
|
||||
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body,
|
||||
Encodings.UTF16EncodingLittleEndian).ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlSerializerOutputFormatterWritesIndentedOutput()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
formatter.WriterSettings.Indent = true;
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
outputFormatterContext.ActionContext.HttpContext.Response.Body.Position = 0;
|
||||
var outputString = new StreamReader(outputFormatterContext.ActionContext.HttpContext.Response.Body,
|
||||
Encoding.UTF8).ReadToEnd();
|
||||
Assert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <SampleInt>10</SampleInt>\r\n</DummyClass>",
|
||||
outputString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task VerifyBodyIsNotClosedAfterOutputIsWritten()
|
||||
{
|
||||
// Arrange
|
||||
var sampleInput = new DummyClass { SampleInt = 10 };
|
||||
var formatter = new XmlSerializerOutputFormatter(
|
||||
XmlOutputFormatter.GetDefaultXmlWriterSettings());
|
||||
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
||||
|
||||
// Act
|
||||
await formatter.WriteAsync(outputFormatterContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputFormatterContext.ActionContext.HttpContext.Response.Body);
|
||||
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
||||
}
|
||||
|
||||
private OutputFormatterContext GetOutputFormatterContext(object outputValue, Type outputType,
|
||||
string contentType = "application/xml; charset=utf-8")
|
||||
{
|
||||
return new OutputFormatterContext
|
||||
{
|
||||
Object = outputValue,
|
||||
DeclaredType = outputType,
|
||||
ActionContext = GetActionContext(contentType)
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext(string contentType)
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
request.Setup(r => r.ContentType).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.AcceptCharset).Returns(contentType.Split('=')[1]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// 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.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public class XmlOutputFormatterTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly Action<IBuilder> _app = new FormatterWebSite.Startup().Configure;
|
||||
|
||||
public XmlOutputFormatterTests()
|
||||
{
|
||||
_services = TestHelper.CreateServices("FormatterWebSite");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlDataContractSerializerOutputFormatterIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.Handler;
|
||||
var headers = new Dictionary<string, string[]>();
|
||||
headers.Add("Accept", new string[] { "application/xml;charset=utf-8" });
|
||||
|
||||
// Act
|
||||
var response = await client.SendAsync("POST",
|
||||
"http://localhost/Home/GetDummyClass?sampleInput=10", headers, null, null);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(200, response.StatusCode);
|
||||
Assert.Equal("<DummyClass xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite\">" +
|
||||
"<SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(response.Body, Encoding.UTF8).ReadToEnd());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task XmlSerializerOutputFormatterIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.Handler;
|
||||
var headers = new Dictionary<string, string[]>();
|
||||
headers.Add("Accept", new string[] { "application/xml;charset=utf-8" });
|
||||
|
||||
// Act
|
||||
var response = await client.SendAsync("POST",
|
||||
"http://localhost/XmlSerializer/GetDummyClass?sampleInput=10", headers, null, null);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(200, response.StatusCode);
|
||||
Assert.Equal("<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
||||
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>",
|
||||
new StreamReader(response.Body, Encoding.UTF8).ReadToEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,10 +73,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
setup.Setup(mvcOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3, mvcOptions.OutputFormatters.Count);
|
||||
Assert.Equal(5, mvcOptions.OutputFormatters.Count);
|
||||
Assert.IsType<NoContentFormatter>(mvcOptions.OutputFormatters[0].Instance);
|
||||
Assert.IsType<TextPlainFormatter>(mvcOptions.OutputFormatters[1].Instance);
|
||||
Assert.IsType<JsonOutputFormatter>(mvcOptions.OutputFormatters[2].Instance);
|
||||
Assert.IsType<XmlDataContractSerializerOutputFormatter>(mvcOptions.OutputFormatters[3].Instance);
|
||||
Assert.IsType<XmlSerializerOutputFormatter>(mvcOptions.OutputFormatters[4].Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,5 +12,11 @@ namespace FormatterWebSite.Controllers
|
|||
{
|
||||
return Content(dummyObject.SampleInt.ToString());
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public DummyClass GetDummyClass(int sampleInput)
|
||||
{
|
||||
return new DummyClass { SampleInt = sampleInput };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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;
|
||||
|
||||
namespace FormatterWebSite
|
||||
{
|
||||
public class XmlSerializerController : Controller
|
||||
{
|
||||
public override void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
var result = context.Result as ObjectResult;
|
||||
if (result != null)
|
||||
{
|
||||
result.Formatters.Add(new XmlSerializerOutputFormatter());
|
||||
}
|
||||
|
||||
base.OnActionExecuted(context);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public DummyClass GetDummyClass(int sampleInput)
|
||||
{
|
||||
return new DummyClass { SampleInt = sampleInput };
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue