Deserializing array from XML data (in ServiceStack)

不打扰是莪最后的温柔 提交于 2019-12-05 12:22:19
mythz

You can use [CollectionDataContract(...)] to modify the serialization output for Arrays/Collections, see this previous answer for an example.

Debugging Serialization and Integration issues

The first step when trying to solve integration problems like this is to isolate the problem. i.e. remove everything else away and just focus on the problem. e.g. In this case I would just focus on the XML and the DTOs and decouple them from your services.

ServiceStack just uses .NET's Xml DataContractSerializer under the hood and doesn't add any extra transformations or byte overheads (it's just the raw DTOs serialized as-is), so if you can get it working outside of your services you can put the same DTOs back into your service and it will also work over the wire.

Handy ServiceStack Extension methods

ServiceStack provides convenient extension methods to serialize / de-serialize and analyze your data models:

Serialization / De-Serialization Extension methods

T.ToJson() / string.FromJson<T>()  //Serialize JSON
T.ToJsv() / string.FromJsv<T>()    //Serialize JSV  
T.ToXml() / string.FromXml<T>()    //Serialize XML

Handy Dump Utils

Recursively print a object-graph in Pretty JSV Dump Format

T.PrintDump()      

Print a string to the console resolving string.Format() args (if any)

string.Print(args)    

What do your Serialized DTOs look like

The first step you should be doing when trying to come up with the Shape of the DTOs is to populate and print them to see what it looks like. Looking at the chunk of XML output I came up with these DTOs:

[DataContract(Namespace = "http://SwitchKing.Common/Entities/RESTSimplified/2010/07")]
public class RESTDataSource
{
    [DataMember]
    public bool Enabled { get; set; }
    [DataMember]
    public string Description { get; set; }
}

[CollectionDataContract(ItemName = "RESTDataSource", Namespace = "http://SwitchKing.Common/Entities/RESTSimplified/2010/07")]
public class ArrayOfRESTDataSource : List<RESTDataSource>
{
    public ArrayOfRESTDataSource() { }
    public ArrayOfRESTDataSource(IEnumerable<RESTDataSource> collection) : base(collection) { }
}

Then populate and dump them:

var dto = new ArrayOfRESTDataSource { 
    new RESTDataSource { Enabled = true, Description = "MyTest" } };

dto.ToXml().Print();

Which prints to the Console:

<?xml version="1.0" encoding="utf-8"?><ArrayOfRESTDataSource xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://SwitchKing.Common/Entities/RESTSimplified/2010/07"><RESTDataSource><Description>MyTest</Description><Enabled>true</Enabled></RESTDataSource></ArrayOfRESTDataSource>

Which looks like what we want. If it doesn't tweak the above DTOs until you get the same chunk as your expected XML.

When you have the DTOs in the same shape of the XML you can start trying to serialize them:

var dto = xml.FromXml<ArrayOfRESTDataSource>();
dto.PrintDump();

Which will print this pretty object graph:

[
    {
        Enabled: True,
        Description: MyTest
    }
]

If all the fields are populated with the expected values then you are done and can update your ServiceStack web service DTOs.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!