4

I'm attempting to test a [MessageContract] class against an existing sample message, and I'm looking for a way to simplify development by reading the sample message file into an instance of my [MessageContract] class and seeing how it worked out (I'm dealing with a particularly complex contract here, of non-WCF origin).

My [MessageContract] class looks something like this:

[MessageContract(IsWrapped = true, WrapperName = "wrapper", WrapperNamespace = "somens")]
public class RequestMessage
{
    [MessageHeader(Name = "HeaderElem", Namespace = "otherns")]
    public XElement CorrelationTimeToLive { get; set; }

    [MessageBodyMember(Name = "id", Namespace = "somens")]
    public XElement id { get; set; }
}

I can read the file into an instance of the Message class, using code such as the following:

var xr = XmlReader.Create("sample_message.xml");
var msg = Message.CreateMessage(xr, int.MaxValue, MessageVersion.Soap12);

That's not particulary helpful, however, because it doesn't allow me to test my [MessageContract] class at all.

Somewhere in the guts of WCF is a system for turning this Message instance into an instance of a particular [MessageContract] class, but what is it?

Mark
  • 11,257
  • 11
  • 61
  • 97

2 Answers2

5

I just learned how to do this the other day following a talk with a collegue. I think this is what you were asking to do.

namespace MessageContractTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string action = null;
            XmlReader bodyReader = XmlReader.Create(new StringReader("<Example xmlns=\"http://tempuri.org/\"><Gold>109</Gold><Message>StackOverflow</Message></Example>"));
            Message msg = Message.CreateMessage(MessageVersion.Default, action, bodyReader);
            TypedMessageConverter converter = TypedMessageConverter.Create(typeof(Example), "http://tempuri.org/IFoo/BarOperation");
            Example example = (Example)converter.FromMessage(msg);
        }
    }


    [MessageContract]
    public class Example
    {
        [MessageHeader]
        public string Hello;

        [MessageHeader]
        public double Value;

        [MessageBodyMember]
        public int Gold;

        [MessageBodyMember]
        public string Message;
    }
}
krystan honour
  • 6,523
  • 3
  • 36
  • 63
  • Obviously you need an action and the correct message version normally but this is how i know how to do this. In the end you will end up with an Example Object You can do similar things with the TypedMessageConverter converting to a string representation by using ToMessage – krystan honour Nov 10 '10 at 00:30
-2

You will need to deserialize the XML into an instance of your data contract. This is what WCF is doing for you under the covers.

Here is a quick tutorial that will show you how to invoke the DataContractSerializer manually for your XML.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • 2
    Uh, there's no `[DataContract]` here. This is a `[MessageContract]` with things like `[MessageHeader]` and `[MessageBodyMember]` properties. – Mark Sep 30 '10 at 16:01
  • 1
    Also, the XML file is not just the body part of the soap message, it's the WHOLE COMPLETE envelope. – Mark Sep 30 '10 at 16:03