I need to develop a webservice which will be exposed to a java client over SOAP. We have a well defined schema in place which we use to communicate between both the systems. Now I need to expose an operation on my WCF contract which takes the Schema object and store it inside our DB.
I have followed the following for developing the webservice.
Host it over basichttp in wcf
Create an object model of the schema using xsd.exe
Take the schema as a parameter on the operation something like DoThis(SchemaObject schema)
Since this is going to be exposed in WCF, I have gone and modified the xsd tool generated object model. Our schema has mutiple level of nesting, and is a combination of 4 different schema linked together. The object graph generated by xsd tool has abstract classes, inheritence etc.
For this to work, I have gone and defined DataContract attrbute on everyclass and added the namespace to it, which was already there in the XmlTypeAttribute. Also I have added DataMemebers to each properties.
Some of the properties in the schema are arrays which was defined by the tool using xmlarrayitem attribute.
Now when I send a request using SOAP UI, the object is not getting deserialized as expected. Almost all the fields are coming as null, which has some sort of inheritence hierarchy. I have added KnownType attribute to the appropriate datacontracts, but still not working.
My question is:
Is this the right way to develop a webservice.
Is there a way to avoid putting the datacontract and data members and just work witht he serialization attributes added by the xsd tool?
Is it necessary to use datacontract attribute, will it not work with the xmlserialization attributes as it works inthe case xml deserialization?
WCF supports two types of serialization - DataContractSerializer and XmlSerializer.
XSD.exe generates strong type entities with all necessary XmlSerializer attributes. You do not need to add any DataContract or DataMemeber attributes to work with generated classes in WCF.
See MSDN for more details - http://msdn.microsoft.com/en-us/library/ms733901.aspx
Be also very careful with your entities generated by xsd.exe. As you probably already seen WCF server will eat many serialization changes you can do in these files but that will be breaking change for clients because they relay on XSD.
If possible I would remain these auto-generated entities without changes to guarantee that interface is not broken. You may introduce separate DTO classes for using in Business Layer. You can implement inheritence hierarchy over there.
Bunch of Unit Tests can help if you feel that auto-generated classes need to be changed. These Test Cases should generate different data sets, serialize them into XML and check that XML over XSD.
Technically, I don't see any particular flaw in the way you are implementing the service.
But from the architectural point of view it's too complicated for me. It's always easier to send 'flat' data-structures and hide complexity somewhere else.
I would suggest the following steps
Develop some special 'transport' scheme, maximally flattening it. It makes changes of the service easier when your model changes. And also it makes less painful to generate and cope with xsd.
Code special transformators on both sides of the channel to translate normal model to 'flat' and then vice-versa.
Related
I'm trying to figure out how the WSCF Blue DataContract generation feature works.
It's documented here: http://alexmg.com/post/2009/09/01/Data-contract-generation-is-now-available-in-WSCFblue.aspx
I have a set of WSDL and XSD files from which we can use the "regular" method to create web service code.
The service generated does not allow you to use data contracts at the client end, meaning we get lots of Array types instead of List types.
Or more accurately, we can't get Lists, only Arrays so this means it's not using DataContracts.
So, when generating service code on the server side I get two options.
Use the regular option, generates an abstract class from which we create a concrete Service class
Use the "Generate Data Contract" option. This creates a .cs file containing just classes representing the the Xsd types, no abstract classes for the service.
So if I then try to generate the service classes with the regular options, I now have lots of duplicate classes representing the Xsd types.
I clearly have the wrong end of the stick.
Has anybody managed to make WSCF.blue work with DataContracts instead of the XmlSerializer?
The .NET Framework ships with System.Runtime.Serialization.Json.DataContractJsonSerializer and System.Web.Script.Serialization.JavaScriptSerializer, both of which de/serialize JSON. How do I know when to choose one of these types over the other? MSDN doesn't make it clear what their relative advantages are.
We have several projects that consume or emit JSON, and the class selected for each thus far has depended on the opinion of the primary dev on each project. Some are simple, two have complex logic regarding producing managed types from JSON (the types do not map closely to the streams) but don't have any emphasis on speed, one requires speed. None interact with WCF, at least as of now.
While I'm interested in alternative libraries, I am hoping that somebody might have an answer to my question too.
The DataContractJsonSerializer is intended for use with WCF client applications where the serialized types are typically POCO classes with the DataContract attribute applied to them. No DataContract, no serialization. The mapping mechanism of WCF makes the sending and receiving very simple, but only if your platform is homogeneous. If you start mixing in different toolsets, your program might go sideways.
The JavaScriptSerializer can serialize any type, including anonymous types (one way), and does so in a more conformant way. You lose the "automagic" of WCF, but you gain more integration options.
As you can see by the comments, there are a lot of options out there for AJAX serialization, and to address your speed vs. maintainability questions, it might be worth investigating them to find a solution that meets the needs of all the teams, to reduce maintainability issues in the long term as everybody does things their own way.
2014-04-07 UPDATE:
I suggest using JSON.NET if you can. See http://james.newtonking.com/json Feature Comparison for a review of the 3 libraries considered in this question.
2015-05-26 UPDATE:
If your company requires the use of commercially licensable products, or you need every last bit of performance, you may also want to check out https://servicestack.net/.
Both do approximately the same but using very different infrastructure thus applying different restrictions on the classes you want to serialize/deserialize and providing different degree of flexibility in tuning the serialization/deserialization process.
For DataContractJsonSerializer you must mark all classes you want to serialize using DataContract atrtibute and all members using DataMember attribute. As well as if some of you classes have enum members, then the enums also must be marked as DataContract and each enum member - with EnumMember attribute.
Also DataContractJsonSerializer allows you fine control over the whole process of serialization/deserialization by altering types resolution logic and replacing the types you serialize with surrogates.
For JavaScriptSerializer you must provide parameterless constructor if you plan on deserializing objects from json string.
For me, I usually use JavaScriptSerializer in presentation logic, where there's a simple model I want to render in Json together with page, without additional ajax requests. And I even usually don't have to deserialize them back to c# - so there's no overhead at all. But if it's persistence logic, where I want to save objects into a data store (usually no-sql storage), to load them later, I prefer using DataContractJsonSerializer because the overhead of putting attributes is worth of flexibility in the serialization/deserialization process tuning, especially when it comes to loading of serialized data into the objects of the newer version, with updated definitions
Personally, I think that DataContractJsonSerializer reeks of over-engineering. I'd skip it and go with JavaScriptSerializer. In the event where JavaScriptSerializer isn't available, you can use FridayThe13th (a library I wrote ;p).
We were given external SOAP services that we have to consume in our project. All of these provide WSDL data, but a lot of them are not .NET services (most of them were written in Java). We have generated a number of client proxies with wsdl.exe tool. This tool does what it's supposed to do, it creates proxies for us to consume.
The problem appears once we try to call methods on these services using generated proxies. We intercept all SOAP requests for logging purposes and XML data looks different from the one specified in WSDL schema.
For instance, if a field is called "Name", our proxies will serialize it as "nameField". I guess this is because the property called "Name" uses a backing field called "nameField". Services on the other side obviously can't interpret this kind of naming convention.
This wouldn't be happening if our ASMX proxies used the old XmlSerializer, but for some reason they opt for DataContractSerializer, which completely messes up serialization and breaks compatibility between clients and services.
My colleagues have resorted to manually constructing XML data and then sending it with HttpWebRequest class. I think this is completely unacceptable in 2011, this is what automated proxy generation is for.
My question is: why is this happening? Why are our proxies using DataContractSerializer and thus ignoring all xml serialization attributes in the process? Is there a way to force them to use XmlSerializer once again?
We use .NET 4.0.
If you are using WCF the default is DataContractSerializer. And if the types do not have explicit [DataContract]/[DataMember] markers, then DataContractSerializer will use the fields, which sounds like what is happening.
To use XmlSerializer instead, add [XmlSerializerFormat] to your service. See MSDN.
You could also try adding [XmlType] or [XmlRoot] to your classes (if it isn't already there).
I'm writing a program that builds up a tree structure made up of classes that inherit from an abstract Node class. There are a number of different type of nodes built into my program. However, I also want to allow more advanced users to be able to reference my library and write their own derivations of Node. These plug-in libraries are then loaded when my app starts up through Assembly.Load(). Thus all the potential Node types used by my application will not be known until run time.
In addition, I want to be able to serialize and deserialize these trees to and from XML files. I have some experience with XMLSerializer, DataContractSerializer, and implementing IXmlSerializable. Typically, I go with DataContractSerializer as it usually requires less code then implementing IXmlSerializable, and can serialize private fields where XmlSerializer can not.
Yet with this project I also have to consider that other users will be creating classes that derive from my class, and will also have to add whatever code or attributes are required to serialize them as well.
Considering this are there reasons I should go with one serialization mechanism over another?
If the serialization and deserialization will only occur within your application, and if there is no requirement that anyone else be able to read the serialized data, then the serialization format doesn't impact the API: as far as a user of the API is concerned, you will serialize into an opaque file and deserialize from the same.
In this case, use DataContractSerializer, as it can serialize into binary if necessary.
for some time now I have been trying to solve the following problem and I'm starting to run out of ideas:
I have generated a set of C# classes from an xsd schema using the xsd.exe tool and deserializing xml files works fine. The problem is that apart from the convenience and safety of using the auto generated classes, I also need information about the xml hierarchy, ie I need to establish parent-child relationships between the objects created during deserialization. Note that I want to avoid keeping a separate xml hierarchy structure (like a DOM tree), but rather make the generated objects keep track of their parents and children.
I have managed to pull this off in java using JAXB by:
Defining a common base class for all deserialized objects. This base class contains a list of children and a reference to a parent object (if any).
Using the Unmarshaller.Listener functionality that provides a callback on completed object deserialization. This callback provides a reference to the parent of the recently deserialized object, which makes establishing parent-child relationships trivial.
How would I go about doing this in C#? I have had a look at the MSDN docs and done quite a lot of googling, but haven't been able to find any useful information.
I wrote an article some time ago about this exact problem, perhaps it can help you.
http://www.thomaslevesque.com/2009/06/12/c-parentchild-relationship-and-xml-serialization/
XmlSerializer should maintain simple object hierarchies for serialization and deserialization. Complex things such as arrays or lists containing more than one type of object are a bit tricker. . . but possible.