576 lines
22 KiB
C#
576 lines
22 KiB
C#
// Copyright (c) .NET Foundation. 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 System.Xml;
|
|
using System.Xml.Serialization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Http.Features;
|
|
using Microsoft.AspNetCore.Mvc.Formatters.Xml.Internal;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Logging.Testing;
|
|
using Microsoft.Extensions.Primitives;
|
|
using Microsoft.Net.Http.Headers;
|
|
using Moq;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
|
|
{
|
|
public class XmlSerializerOutputFormatterTest
|
|
{
|
|
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; }
|
|
}
|
|
|
|
public static IEnumerable<object[]> BasicTypeValues
|
|
{
|
|
get
|
|
{
|
|
yield return new object[] { "sampleString", "<string>sampleString</string>" };
|
|
yield return new object[] { 5, "<int>5</int>" };
|
|
yield return new object[] { 5.43, "<double>5.43</double>" };
|
|
yield return new object[] { 'a', "<char>97</char>" };
|
|
yield return new object[] { new DummyClass { SampleInt = 10 }, "<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
|
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>" };
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(BasicTypeValues))]
|
|
public async Task XmlSerializerOutputFormatterCanWriteBasicTypes(object input, string expectedOutput)
|
|
{
|
|
// Arrange
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(input, input.GetType());
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
public static TheoryData<bool, object, string> CanIndentOutputConditionallyData
|
|
{
|
|
get
|
|
{
|
|
var obj = new DummyClass { SampleInt = 10 };
|
|
var newLine = Environment.NewLine;
|
|
return new TheoryData<bool, object, string>()
|
|
{
|
|
{ true, obj, "<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
|
$"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">{newLine} <SampleInt>10</SampleInt>{newLine}</DummyClass>" },
|
|
{ false, obj, "<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
|
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>" }
|
|
};
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(CanIndentOutputConditionallyData))]
|
|
public async Task XmlSerializer_CanIndentOutputConditionally(bool indent, object input, string expectedOutput)
|
|
{
|
|
// Arrange
|
|
var formatter = new IndentingXmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(input, input.GetType());
|
|
outputFormatterContext.HttpContext.Request.QueryString = new QueryString("?indent=" + indent);
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
Assert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializer_CanModifyNamespacesInGeneratedXml()
|
|
{
|
|
// Arrange
|
|
var input = new DummyClass { SampleInt = 10 };
|
|
var formatter = new IgnoreAmbientNamespacesXmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(input, input.GetType());
|
|
var expectedOutput = "<DummyClass><SampleInt>10</SampleInt></DummyClass>";
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
Assert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public void XmlSerializer_CachesSerializerForType()
|
|
{
|
|
// Arrange
|
|
var input = new DummyClass { SampleInt = 10 };
|
|
var formatter = new TestXmlSerializerOutputFormatter();
|
|
|
|
var context = GetOutputFormatterContext(input, typeof(DummyClass));
|
|
context.ContentType = new StringSegment("application/xml");
|
|
|
|
// Act
|
|
formatter.CanWriteResult(context);
|
|
formatter.CanWriteResult(context);
|
|
|
|
// Assert
|
|
Assert.Equal(1, formatter.createSerializerCalledCount);
|
|
}
|
|
|
|
[Fact]
|
|
public void DefaultConstructor_ExpectedWriterSettings_Created()
|
|
{
|
|
// Arrange and Act
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
|
|
// Assert
|
|
var writerSettings = formatter.WriterSettings;
|
|
Assert.NotNull(writerSettings);
|
|
Assert.True(writerSettings.OmitXmlDeclaration);
|
|
Assert.False(writerSettings.CloseOutput);
|
|
Assert.False(writerSettings.CheckCharacters);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SuppliedWriterSettings_TakeAffect()
|
|
{
|
|
// Arrange
|
|
var writerSettings = FormattingUtilities.GetDefaultXmlWriterSettings();
|
|
writerSettings.OmitXmlDeclaration = false;
|
|
var sampleInput = new DummyClass { SampleInt = 10 };
|
|
var formatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
|
var formatter = new XmlSerializerOutputFormatter(writerSettings);
|
|
var expectedOutput = "<?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>";
|
|
|
|
// Act
|
|
await formatter.WriteAsync(formatterContext);
|
|
|
|
// Assert
|
|
var body = formatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializerOutputFormatterWritesSimpleTypes()
|
|
{
|
|
// Arrange
|
|
var expectedOutput =
|
|
"<DummyClass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
|
|
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><SampleInt>10</SampleInt></DummyClass>";
|
|
|
|
var sampleInput = new DummyClass { SampleInt = 10 };
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializerOutputFormatterWritesComplexTypes()
|
|
{
|
|
// Arrange
|
|
var expectedOutput =
|
|
"<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>";
|
|
|
|
var sampleInput = new TestLevelTwo
|
|
{
|
|
SampleString = "TestString",
|
|
TestOne = new TestLevelOne
|
|
{
|
|
SampleInt = 10,
|
|
sampleString = "TestLevelOne string"
|
|
}
|
|
};
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializerOutputFormatterWritesOnModifiedWriterSettings()
|
|
{
|
|
// Arrange
|
|
var expectedOutput =
|
|
"<?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>";
|
|
|
|
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
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializerOutputFormatterWritesUTF16Output()
|
|
{
|
|
// Arrange
|
|
var expectedOutput =
|
|
"<?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>";
|
|
|
|
var sampleInput = new DummyClass { SampleInt = 10 };
|
|
var outputFormatterContext =
|
|
GetOutputFormatterContext(sampleInput, sampleInput.GetType(), "application/xml; charset=utf-16");
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
formatter.WriterSettings.OmitXmlDeclaration = false;
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
var content = new StreamReader(
|
|
body,
|
|
new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: true)).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializerOutputFormatterWritesIndentedOutput()
|
|
{
|
|
// Arrange
|
|
var expectedOutput =
|
|
"<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>";
|
|
|
|
var sampleInput = new DummyClass { SampleInt = 10 };
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
formatter.WriterSettings.Indent = true;
|
|
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
var body = outputFormatterContext.HttpContext.Response.Body;
|
|
body.Position = 0;
|
|
|
|
var content = new StreamReader(body).ReadToEnd();
|
|
XmlAssert.Equal(expectedOutput, content);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyBodyIsNotClosedAfterOutputIsWritten()
|
|
{
|
|
// Arrange
|
|
var sampleInput = new DummyClass { SampleInt = 10 };
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
|
|
|
// Act
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
|
|
// Assert
|
|
Assert.NotNull(outputFormatterContext.HttpContext.Response.Body);
|
|
Assert.True(outputFormatterContext.HttpContext.Response.Body.CanRead);
|
|
}
|
|
|
|
public static IEnumerable<object[]> TypesForCanWriteResult
|
|
{
|
|
get
|
|
{
|
|
yield return new object[] { null, typeof(string), true };
|
|
yield return new object[] { null, null, false };
|
|
yield return new object[] { new DummyClass { SampleInt = 5 }, typeof(DummyClass), true };
|
|
yield return new object[] { null, typeof(object), true };
|
|
yield return new object[] {
|
|
new Dictionary<string, string> { { "Hello", "world" } }, typeof(Dictionary<string,string>), false };
|
|
yield return new object[] {
|
|
new[] {"value1", "value2"}, typeof(IEnumerable<string>), true };
|
|
yield return new object[] {
|
|
Enumerable.Range(1, 2).Select(i => "value" + i).AsQueryable(), typeof(IQueryable<string>), true };
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(TypesForCanWriteResult))]
|
|
public void CanWriteResult_ReturnsExpectedValueForObjectType(object input, Type declaredType, bool expectedOutput)
|
|
{
|
|
// Arrange
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(input, declaredType);
|
|
outputFormatterContext.ContentType = new StringSegment("application/xml");
|
|
|
|
// Act
|
|
var result = formatter.CanWriteResult(outputFormatterContext);
|
|
|
|
// Assert
|
|
Assert.Equal(expectedOutput, result);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("application/xml", false, "application/xml")]
|
|
[InlineData("application/xml", true, "application/xml")]
|
|
[InlineData("application/other", false, null)]
|
|
[InlineData("application/other", true, null)]
|
|
[InlineData("application/*", false, "application/xml")]
|
|
[InlineData("text/*", false, "text/xml")]
|
|
[InlineData("custom/*", false, null)]
|
|
[InlineData("application/xml;v=2", false, null)]
|
|
[InlineData("application/xml;v=2", true, null)]
|
|
[InlineData("application/some.entity+xml", false, null)]
|
|
[InlineData("application/some.entity+xml", true, "application/some.entity+xml")]
|
|
[InlineData("application/some.entity+xml;v=2", true, "application/some.entity+xml;v=2")]
|
|
[InlineData("application/some.entity+other", true, null)]
|
|
public void CanWriteResult_ReturnsExpectedValueForMediaType(
|
|
string mediaType,
|
|
bool isServerDefined,
|
|
string expectedResult)
|
|
{
|
|
// Arrange
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(new object(), typeof(object));
|
|
outputFormatterContext.ContentType = new StringSegment(mediaType);
|
|
outputFormatterContext.ContentTypeIsServerDefined = isServerDefined;
|
|
|
|
// Act
|
|
var actualCanWriteValue = formatter.CanWriteResult(outputFormatterContext);
|
|
|
|
// Assert
|
|
var expectedContentType = expectedResult ?? mediaType;
|
|
Assert.Equal(expectedResult != null, actualCanWriteValue);
|
|
Assert.Equal(new StringSegment(expectedContentType), outputFormatterContext.ContentType);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task XmlSerializerOutputFormatterDoesntFlushOutputStream()
|
|
{
|
|
// Arrange
|
|
var sampleInput = new DummyClass { SampleInt = 10 };
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
var outputFormatterContext = GetOutputFormatterContext(sampleInput, sampleInput.GetType());
|
|
|
|
var response = outputFormatterContext.HttpContext.Response;
|
|
response.Body = FlushReportingStream.GetThrowingStream();
|
|
|
|
// Act & Assert
|
|
await formatter.WriteAsync(outputFormatterContext);
|
|
}
|
|
|
|
public static IEnumerable<object[]> TypesForGetSupportedContentTypes
|
|
{
|
|
get
|
|
{
|
|
yield return new object[] { typeof(DummyClass), "application/xml" };
|
|
yield return new object[] { typeof(object), "application/xml" };
|
|
yield return new object[] { null, null };
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(TypesForGetSupportedContentTypes))]
|
|
public void XmlSerializer_GetSupportedContentTypes_Returns_SupportedTypes(Type type, object expectedOutput)
|
|
{
|
|
// Arrange
|
|
var formatter = new XmlSerializerOutputFormatter();
|
|
|
|
// Act
|
|
var result = formatter.GetSupportedContentTypes("application/xml", type);
|
|
|
|
// Assert
|
|
if (expectedOutput != null)
|
|
{
|
|
Assert.Equal(expectedOutput, Assert.Single(result).ToString());
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal(expectedOutput, result);
|
|
}
|
|
}
|
|
|
|
public static TheoryData<XmlSerializerOutputFormatter, TestSink> LogsWhenUnableToCreateSerializerForTypeData
|
|
{
|
|
get
|
|
{
|
|
var sink1 = new TestSink();
|
|
var formatter1 = new XmlSerializerOutputFormatter(new TestLoggerFactory(sink1, enabled: true));
|
|
|
|
var sink2 = new TestSink();
|
|
var formatter2 = new XmlSerializerOutputFormatter(
|
|
new XmlWriterSettings(),
|
|
new TestLoggerFactory(sink2, enabled: true));
|
|
|
|
return new TheoryData<XmlSerializerOutputFormatter, TestSink>()
|
|
{
|
|
{ formatter1, sink1 },
|
|
{ formatter2, sink2}
|
|
};
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(LogsWhenUnableToCreateSerializerForTypeData))]
|
|
public void XmlSerializer_LogsWhenUnableToCreateSerializerForType(
|
|
XmlSerializerOutputFormatter formatter,
|
|
TestSink sink)
|
|
{
|
|
// Arrange
|
|
var outputFormatterContext = GetOutputFormatterContext(new Customer(10), typeof(Customer));
|
|
|
|
// Act
|
|
var canWriteResult = formatter.CanWriteResult(outputFormatterContext);
|
|
|
|
// Assert
|
|
Assert.False(canWriteResult);
|
|
var write = Assert.Single(sink.Writes);
|
|
Assert.Equal(LogLevel.Warning, write.LogLevel);
|
|
Assert.Equal(
|
|
$"An error occurred while trying to create an XmlSerializer for the type '{typeof(Customer).FullName}'.",
|
|
write.State.ToString());
|
|
}
|
|
|
|
[Fact]
|
|
public void XmlSerializer_DoesNotThrow_OnNoLoggerAnd_WhenUnableToCreateSerializerForType()
|
|
{
|
|
// Arrange
|
|
var formatter = new XmlSerializerOutputFormatter(); // no logger is being supplied here on purpose
|
|
var outputFormatterContext = GetOutputFormatterContext(new Customer(10), typeof(Customer));
|
|
|
|
// Act
|
|
var canWriteResult = formatter.CanWriteResult(outputFormatterContext);
|
|
|
|
// Assert
|
|
Assert.False(canWriteResult);
|
|
}
|
|
|
|
private OutputFormatterWriteContext GetOutputFormatterContext(
|
|
object outputValue,
|
|
Type outputType,
|
|
string contentType = "application/xml; charset=utf-8")
|
|
{
|
|
return new OutputFormatterWriteContext(
|
|
GetHttpContext(contentType),
|
|
new TestHttpResponseStreamWriterFactory().CreateWriter,
|
|
outputType,
|
|
outputValue);
|
|
}
|
|
|
|
private static HttpContext GetHttpContext(string contentType)
|
|
{
|
|
var httpContext = new DefaultHttpContext();
|
|
var request = httpContext.Request;
|
|
request.Headers["Accept-Charset"] = MediaTypeHeaderValue.Parse(contentType).Charset.ToString();
|
|
request.ContentType = contentType;
|
|
httpContext.Response.Body = new MemoryStream();
|
|
return httpContext;
|
|
}
|
|
|
|
private class TestXmlSerializerOutputFormatter : XmlSerializerOutputFormatter
|
|
{
|
|
public int createSerializerCalledCount = 0;
|
|
|
|
protected override XmlSerializer CreateSerializer(Type type)
|
|
{
|
|
createSerializerCalledCount++;
|
|
return base.CreateSerializer(type);
|
|
}
|
|
}
|
|
|
|
public class Customer
|
|
{
|
|
public Customer(int id)
|
|
{
|
|
}
|
|
|
|
public int MyProperty { get; set; }
|
|
}
|
|
private class IndentingXmlSerializerOutputFormatter : XmlSerializerOutputFormatter
|
|
{
|
|
public override XmlWriter CreateXmlWriter(
|
|
OutputFormatterWriteContext context,
|
|
TextWriter writer,
|
|
XmlWriterSettings xmlWriterSettings)
|
|
{
|
|
var request = context.HttpContext.Request;
|
|
if (request.Query["indent"] == "True")
|
|
{
|
|
xmlWriterSettings.Indent = true;
|
|
}
|
|
|
|
return base.CreateXmlWriter(context, writer, xmlWriterSettings);
|
|
}
|
|
}
|
|
|
|
private class IgnoreAmbientNamespacesXmlSerializerOutputFormatter : XmlSerializerOutputFormatter
|
|
{
|
|
protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
|
|
{
|
|
var namespaces = new XmlSerializerNamespaces();
|
|
namespaces.Add("", "");
|
|
|
|
xmlSerializer.Serialize(xmlWriter, value, namespaces);
|
|
}
|
|
}
|
|
}
|
|
} |