diff --git a/Mvc.sln b/Mvc.sln index e476c49ffc..0a7055d74d 100644 --- a/Mvc.sln +++ b/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 diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlDataContractSerializerOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlDataContractSerializerOutputFormatter.cs new file mode 100644 index 0000000000..efc07b7c2c --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlDataContractSerializerOutputFormatter.cs @@ -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 +{ + /// + /// This class handles serialization of objects + /// to XML using + /// + public class XmlDataContractSerializerOutputFormatter : XmlOutputFormatter + { + /// + /// Initializes a new instance of + /// with default XmlWriterSettings + /// + public XmlDataContractSerializerOutputFormatter() + :this(GetDefaultXmlWriterSettings()) + { + } + + /// + /// Initializes a new instance of + /// + /// The settings to be used by the . + public XmlDataContractSerializerOutputFormatter([NotNull] XmlWriterSettings writerSettings) + :base(writerSettings) + { + } + + /// + /// Create a new instance of for the given object type. + /// + /// The type of object for which the serializer should be created. + /// A new instance of + public virtual DataContractSerializer CreateDataContractSerializer([NotNull] Type type) + { + return new DataContractSerializer(type); + } + + /// + 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); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlOutputFormatter.cs new file mode 100644 index 0000000000..53dc95bfe5 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlOutputFormatter.cs @@ -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 +{ + /// + /// Abstract base class from which all XML Output Formatters derive from. + /// + 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; + } + + /// + /// Gets or sets the settings to be used by the XmlWriter. + /// + public XmlWriterSettings WriterSettings { get; private set; } + + /// + /// Gets the default XmlWriterSettings. + /// + /// Default + public static XmlWriterSettings GetDefaultXmlWriterSettings() + { + return new XmlWriterSettings + { + OmitXmlDeclaration = true, + CloseOutput = false, + CheckCharacters = false + }; + } + + /// + /// Creates a new instance of using the given stream and the WriterSettings. + /// + /// The stream on which the XmlWriter should operate on. + /// A new instance of + public virtual XmlWriter CreateXmlWriter([NotNull] Stream writeStream, [NotNull] XmlWriterSettings xmlWriterSettings) + { + return XmlWriter.Create(writeStream, xmlWriterSettings); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlSerializerOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlSerializerOutputFormatter.cs new file mode 100644 index 0000000000..e74dc5db2d --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/XmlSerializerOutputFormatter.cs @@ -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 +{ + /// + /// This class handles serialization of objects + /// to XML using + /// + public class XmlSerializerOutputFormatter : XmlOutputFormatter + { + /// + /// Initializes a new instance of + /// with default XmlWriterSettings. + /// + public XmlSerializerOutputFormatter() + :this(GetDefaultXmlWriterSettings()) + { + } + + /// + /// Initializes a new instance of + /// + /// The settings to be used by the . + public XmlSerializerOutputFormatter([NotNull] XmlWriterSettings writerSettings) + :base(writerSettings) + { + } + + /// + /// Create a new instance of for the given object type. + /// + /// The type of object for which the serializer should be created. + /// A new instance of + public virtual XmlSerializer CreateXmlSerializer([NotNull] Type type) + { + return new XmlSerializer(type); + } + + /// + 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); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs index c1f3ddf6c7..f6c7f634e4 100644 --- a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs +++ b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs @@ -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()); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs new file mode 100644 index 0000000000..2370d00b66 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs @@ -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("" + + "10", + 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("" + + "TestString" + + "10TestLevelOne string" + + "", + 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("" + + "" + + "10", + 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("" + + "" + + "10", + 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("" + + "\r\n 10\r\n", + 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(); + var headers = new Mock(); + 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(); + response.SetupGet(f => f.Body).Returns(new MemoryStream()); + var httpContext = new Mock(); + 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); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerOutputFormatterTests.cs new file mode 100644 index 0000000000..2ffd2ab87f --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerOutputFormatterTests.cs @@ -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("10", + 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("TestString" + + "TestLevelOne string" + + "10", + 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("" + + "10", + 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("" + + "10", + 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("\r\n 10\r\n", + 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(); + var headers = new Mock(); + 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(); + response.SetupGet(f => f.Body).Returns(new MemoryStream()); + var httpContext = new Mock(); + 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); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/XmlOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/XmlOutputFormatterTests.cs new file mode 100644 index 0000000000..35d74ef7e3 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/XmlOutputFormatterTests.cs @@ -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 _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(); + 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("" + + "10", + 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(); + 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("10", + new StreamReader(response.Body, Encoding.UTF8).ReadToEnd()); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs index 7435777fb6..57daadadcf 100644 --- a/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs +++ b/test/Microsoft.AspNet.Mvc.Test/MvcOptionSetupTest.cs @@ -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(mvcOptions.OutputFormatters[0].Instance); Assert.IsType(mvcOptions.OutputFormatters[1].Instance); Assert.IsType(mvcOptions.OutputFormatters[2].Instance); + Assert.IsType(mvcOptions.OutputFormatters[3].Instance); + Assert.IsType(mvcOptions.OutputFormatters[4].Instance); } } } \ No newline at end of file diff --git a/test/WebSites/FormatterWebSite/Controllers/HomeController.cs b/test/WebSites/FormatterWebSite/Controllers/HomeController.cs index 873094da3a..e8d8f0cdaf 100644 --- a/test/WebSites/FormatterWebSite/Controllers/HomeController.cs +++ b/test/WebSites/FormatterWebSite/Controllers/HomeController.cs @@ -12,5 +12,11 @@ namespace FormatterWebSite.Controllers { return Content(dummyObject.SampleInt.ToString()); } + + [HttpPost] + public DummyClass GetDummyClass(int sampleInput) + { + return new DummyClass { SampleInt = sampleInput }; + } } } \ No newline at end of file diff --git a/test/WebSites/FormatterWebSite/Controllers/XmlSerializerController.cs b/test/WebSites/FormatterWebSite/Controllers/XmlSerializerController.cs new file mode 100644 index 0000000000..0a0c154ad5 --- /dev/null +++ b/test/WebSites/FormatterWebSite/Controllers/XmlSerializerController.cs @@ -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 }; + } + } +} \ No newline at end of file