In my Startup.ConfigureServices method I have:
services.AddMvc(setupAction =>
{
setupAction.ReturnHttpNotAcceptable = true;
setupAction.OutputFormatters.Add(new XmlSerializerOutputFormatter());
setupAction.InputFormatters.Add(new XmlSerializerInputFormatter());
});
I've also tried:
services.AddMvc(setupAction =>
{
setupAction.ReturnHttpNotAcceptable = true;
setupAction.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
setupAction.InputFormatters.Add(new XmlDataContractSerializerInputFormatter());
});
My POST method's signature looks like:
[HttpPost("xunit")]
public IActionResult PostXunitResults([FromBody] XunitResult results)
XunitResult looks like:
[Serializable]
[XmlRoot("assemblies")]
public class XunitResult
{
[XmlIgnore]
public const string MimeType = "application/xml";
[XmlAttribute("timestamp")]
public string Timestamp { get; set; }
[XmlElement("assembly")]
public List<Assembly> Assemblies { get; set; }
}
[Serializable]
[XmlType("assembly")]
public class Assembly
{
...
With this setup I can run tests to check that my model deserializes the XML correctly:
[Fact]
public void WhenYouDeserializeXunitResultsIntoAnXunitResultsObject_ThenTheObjectIsPopulatedCorrectly()
{
var serializer = new XmlSerializer(typeof(XunitResult));
XunitResult results;
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(_xunitResults)))
{
results = (XunitResult)serializer.Deserialize(stream);
}
results.Assemblies.Should().NotBeNull();
}
... which it does.
When I try to use XunitResult
as a [FromBody]
argument to the post method, the model is not rendered correctly in Swagger:
- Swagger does not display
XunitResult
correctly in the example, it renders the root as 'XunitResult' instead of 'assemblies' as defined in theXMLRootAttribute
onXunitResult
. - Also, the same model does not render the Timestamp property in
XunitResult
as an attribute, it renders it as an element. This is just an example. The other XmlAttributes in the class are rendered as elements as well, and not as attributes like they should be. - The assemblies element is rendered as an
assembly
should be if it were inside of theassemblies
element.
view screenshot for the above 2 items here
The XML model should look similar to this:
<?xml version="1.0" encoding="utf-8"?>
<assemblies timestamp="02/27/2018 14:32:47">
<assembly name="API.Test.dll" environment="64-bit .NET Standard [collection-per-class, parallel (8 threads)]" test-framework="xUnit.net 2.3.1.3858" run-date="2018-02-27" run-time="14:32:47" total="9" passed="5" failed="3" skipped="1" time="0.161" errors="0">
<errors />
<collection total="1" passed="0" failed="1" skipped="0" name="Test collection for API.Test.API.Results.TestResultPost2" time="0.000">
<test name="API.Test.API.Results.TestResultPost2.TestWeWontGetTo" type="API.Test.API.Results.TestResultPost2" method="TestWeWontGetTo" time="0" result="Fail">
<failure exception-type="System.Exception">
<message><![CDATA[System.Exception : exception in setup]]></message>
<stack-trace><![CDATA[ at API.Test.API.Results.TestResultPost2..ctor() in /Users//Documents///API.Test/Controller/TestResultsPost.cs:line 60]]></stack-trace>
</failure>
</test>
</collection>
...
And when I try to post XML according to the model in swagger, OR if I try to post valid XML, the results
variable in the PostXunitResults
method is null.
If I inspect the body of the call via Request.Body
, then the first part of the XML that I posted is gone, only the last part is in the Body
stream.
Any help to figure this out would be great!