tags:

views:

786

answers:

4

I have created a schema as an agreed upon interface between our company and an external company. I am now creating a WCF C# web service to handle the interface.

I ran the XSD utility and it created a C# class. The schema was built in BizTalk, and references other schemas, so all-in-all there are over 15 classes being generated.

I put [DataContract} attribute in front of each of the classes. Do I have to put the [DataMember] attribute on every single property?
When I generate a test client program, the proxy does not have any code for any of these 15 classes.

We used to use this technique when using .asmx services, but not sure if it will work the same with WCF. If we change the schema, we would want to regenerate the WCF class, and then we would haev to each time redecorate it with all the [DataMember] attributes? Is there an newer tool similar to XSD.exe that will work better with WCF?

Thanks,

Neal Walters

SOLUTION (buried in one of Saunders answer/comments):

Add the XmlSerializerFormat to the Interface definition:

    [OperationContract]
    [XmlSerializerFormat]     // ADD THIS LINE 
    Transaction SubmitTransaction(Transaction transactionIn);

Two notes: 1) After I did this, I saw a lot more .xsds in the my proxy (Service Reference) test client program, but I didn't see the new classes in my intellisense. 2) For some reason, until I did a build on the project, I didn't get all the classes in the intellisense (not sure why).

A: 

Classes that use [DataContract] will serialize to a very limited schema. For instance, there will be no attributes, only elements. This is intentional, and is done for performance and interoperability.

In general, a schema of the kind you may be working with may be much more complicated. Such a schema will not be usable with the Data Contract Serializer. You will need to use the XML Serializer instead.

In particular, don't edit the classes created by XSD.EXE. In fact, you should never edit generated code, as your edits will be removed as soon as the code is generated again. These classes should already have the attributes on them that will be needed for WCF to work with them.

What happens if you just use them as-is?

John Saunders
1) When I generate a test client program, the proxy does not have any code for any of these 15 classes. My understanding is that WCF requires the [DataContract] and [DataMember] to properly expose. All elements is fine with me. 2) I totally agree about not wanting to change the code, that's why I posted the question. 3) What should I search to learn more about XmlSerializer? Does it generate C# code from .xsd files? I may have used it at last client, but need to access my gmail (blocked here).
NealWalters
Use [XmlSerializerFormat] on each web service operation that requires XML Serialization. The XSD utility has already done all the other work for you.
John Saunders
@Downvoter: reason for the downvote?
John Saunders
I was not downvoter - but - you seem to be missing my point. I have an existing approved XSD that I need to use in WCF as C# class. I'm used to doing schema first, then c# web-service second, and then that will build WSDL. [I found that email on Blackberry, and in prior company, used svcutil.exe /serializer:xmlserializer, but that was a different issue. We had an issue there of a complex C# class not serializing properly to BizTalk that was consuming WCF.]
NealWalters
I'm getting your point. Use the classes generated by XSD.EXE, but you have to configure each operation to use the XML Serializer by using the `[XmlSerializerFormat]` attribute on the `[OperationContract]`. Is there a problem with doing this? That will turn on the XML Serializer for that particular operation (method) of the web service.
John Saunders
So when VS2008 came out with WCF, the XSD utility was never upgraded to support WCF serialization decorators? Is that true???Today, we ran XSD.exe from both 2005 and 2008 and compared differences of the C# generated code, which was only the .42 vs .1432 in the Version number (of the System.CodeDom.Compiler.GeneratedCodeAttribute).
NealWalters
You asked "Is there a problem with doing this?". The problem is that the XSD will probably have several changes over the next few weeks, I anticipate having to rebuild the C# class many times.
NealWalters
I'm also looking into the "XSDObjectGen" utility.
NealWalters
Sorry, it finally hit me. The [OperationContract] is not in the C# generated code, but in my Ixxxx.cs file. So I don't have to change it each time I regenerated. See post above to my original question that show the syntax. Note: the XmlSerializerFormat is is not part of the OperationContract attribute, it is simply another attribute.
NealWalters
Sorry, false start. I thought I had it, but not yet. I removed [DataContract] that I had added, so now my generated .CS is "untouched". I added [XmlSerializerFormat] on the interface. Still my class does not appear in the proxy after rebuilding it.
NealWalters
Sorry again, it must be Monday morning. The XmlSerializer helped, but I was getting the classes using Intellisense, so I thought it didn't work. I had to do a build of my client program before the Intellisense started working. I'm a happy camper now, I think.
NealWalters
@Neal: XSD.EXE is unrelated to WCF. It is related to the old XML Serialization technology. Because Data Contract Serialization does not support arbitrary schemas, WCF is able to use XML Serialization if necessary. In order to do this, it is necessary to tell WCF to use the XML Serializer instead of the Data Contract Serializer, on a case by case basis.
John Saunders
Please comment or confirm on my new answer.
NealWalters
+4  A: 

Neal, besides all the options John has given you, you should also check out the WCSF.blue tool on Codeplex: http://wscfblue.codeplex.com/

It's a "contract first" approach to doing WCF, and one of the many options it offers is to create a WCF DataContract file from your XSD:

alt text

This then pops up a dialog in which you can set a slew of parameters on how to create your C# class file from the XSD:

alt text

Quite useful, even if you want to use it for nothing more than converting XSD to C# classes that work as WCF DataContracts :-)

Also see this blog post for more explanations on the XSD DataContract generation process.

marc_s
Thanks, downloading now...
NealWalters
Posted questions in their CodePlex discussion here: http://wscfblue.codeplex.com/Thread/View.aspx?ThreadId=204204 - how to work with an XSD that was created with BizTalk 2006/R2 in VS2005.
NealWalters
Please comment or confirm on my new answer.
NealWalters
+1  A: 

I'm shocked that no one pointed me to this utility, which I believe is what I was asking for:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.xsddatacontractimporter.aspx

I haven't tried it yet, but it looks like XsdDataContractImporter was what I was looking for, or the SVCUTIL with the /dataContractOnly flag.

I learned this when interviewing a candidate yesterday. She said DataContract serialization is faster and would be preferred to use.

Neal

NealWalters
+1  A: 

Hi Neal, Re: your XsdDataContract class mentioned in your followup, IMO, This is a niche class (as is ServiceContractGenerator etc) so i'm not surprised no one pointed you to it. You still need to package it up to make it really useful. I'm pretty sure that code sample covers only very basic use cases so I would expect to do a lot of work with that to get it to a proper working state. . And like i mentioned on the WSCF forum, Svcutil, wscf, xsd.exe and others all use this class and related classes in the code gen process.

Regards the serializer performance, there are really good posts on Youssef Moussaoui's blog on the different serializers and their performance especially http://blogs.msdn.com/youssefm/archive/2009/07/10/comparing-the-performance-of-net-serializers.aspx

There’s also a really good discussion here on Connect regarding the two serializers (XS and DCS) and a useful point that XS is still the way forward for WSDL/XSD First development as the DCS is only intended to support a simplified programming model and thus doesn’t support various xml constructs. http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=451277

Hope this helps, Cheers, Benjy

Santosh Benjamin
Thanks, we've been debating several days last week the pros cons of DataContract vs XmlSerializer. Our new WCF expert seems to think that using XmlSerializer is not taking full advantage of WCF features. Do you think that is true? I'm headed to read the blogs you mentioned now.
NealWalters