views:

29

answers:

2

Say I have a non-.NET app which needs to write data to be deserialized by a .NET app via DataContractSerializer. Where's the specification describing the exact format necessary?

Such a spec should describe a lot of stuff, including:

  • Does the order of sibling elements matter?
  • Should the xml namespace URIs always begin with http://schemas.datacontract.org/2004/07/?
  • do z:Id and z:Ref values need to be sequental or anything? (assuming preserveObjectReferences==true) (ok, I guess MSDN says this case is not even interoperable)
  • etc

Seems like a simple question, doesn't it? Yet I don't see it addressed directly in MSDN. (all I found was forum-posts saying the non-.NET app needs to ask the .NET app for a WSDL spec file first. But that seems wrong.)

(I don't use anything from WCF other than the DataContractSerializer)

A: 

We use the WSDL to comunicate the service definition between Java and .net applications, it works fine for us.

One thing that you need to watch out for is which datatypes you use, use those that are understood by both systems, for example:

  • If you create the service in .net, do not use datasets
  • If you create the service in java do not use vectors
Shiraz Bhaiji
A: 

The DataContractSerializer is not part of WCF, it is part of the runtime serialization which WCF is dependent on.

I have in the past used the DataContractSerializer to deserialize objects from XML I have generated out of an xml transform. This could be down the lines of what you want to do.

In order to work out what the XML required for the Serializer I found it easier to write a small piece of code that serialized my object out to a string to see how it should be structured and what the XML namespaces were.

[TestFixture]
public class TestDataContractSerializerOutput
{
    [Test]
    public void Should_give_me_some_serialized_xml()
    {
        Foo foo = new Foo();
        foo.Bars.Add(new Bar { Name = "Wibble"});
        var dataContractSerializer = new DataContractSerializer(typeof(Foo), new[] { typeof(Bar) } );

        using (Stream stream = new MemoryStream())
        {
            dataContractSerializer.WriteObject(stream, foo);
            stream.Position = 0;

            using (StreamReader streamReader = new StreamReader(stream))
            {
                Trace.WriteLine(streamReader.ReadToEnd());
            }
        }
    }
}

[DataContract]
public class Foo
{
    public Foo()
    {
        Bars = new List<IBar>();
    }

    [DataMember]
    public IList<IBar> Bars { get; set; }
}

public interface IBar
{
    string Name { get; set; }
}

[DataContract]
public class Bar : IBar
{
    public string Name { get; set; }
}

With this information you can see how to structure the XML and you can also grab the xml schemas for extra validation.

Bronumski
Right, that's what I'm doing. But just by looking at the resulting output, I can't know the *constraints* I need to follow. For example, I may see `<root> <foo/> <bar/> </root>` in the XML, but does that mean `<root> <bar/> <foo/> </root>` would have worked too? I've listed other examples in the question.
Stefan Monov
Unfortunately I have changed jobs so I cannot look at the code I did before but I do remember that as long as it was well formed it was fairly leneant. All I would suggest is that you grab the schemas it needs from the schema folder in VisualStudio (C:\Program Files (x86)\Microsoft Visual Studio 10.0\Xml\Schemas):
Bronumski
Actually the schema for the namespace http://schemas.microsoft.com/2003/10/Serialization/Arrays isn't in there which rings a bell now. I think all I did was create a number of unit tests for really complex scenarios and make sure that they worked. As your object graph changes just keep your tests up to date.
Bronumski