Incidentally there's an even easier way to share types on both the client and the server by bypassing the proxy generation altogheter. Because of the way Service Contracts work you can share the Service contract (and any DataContracts) directly in binary form on the client and through that interface directly serialize into target objects.This is more efficient yet since you won't get the overhead of a generated proxy of any kind. This should work for clients as long as you can reliably keep the client and server service contracts in sync. Hey dude, just some quick comments:-WCF uses what is called DataContractFormat (similar to binary ISerializable semantics) however so it’s a Field based approach that deals with object state rather than the object interface (ie. Fields rather than Properties).-What do you mean?For really designing the message on the wire you should use MessageContract, not DataContract.And,in 'closed scenarios' I would opt for doing just contract assembly sharing and the use the ChannelFactory approach.Cheers,Christian. Christian, looking at MessageContract is much more low level though, where you need to get down all the way to the protocol level. Yes it gives you a lot more control but it's also a bit more work and shouldn't typically be necessary.
I don't think MessageContract would be appropriate for publishing your business objects in a generic way.In the end I'm not worried about what goes over the wire - I'm worried about what I can consume on the other end and making sure that it's a reasonable representation of my original data. The more I look at default generated proxies from a service that doesn't have explicit data contracts, the more I think that that's just not an option for sharing data.It seems to me you can do quite a bit with a DataContract to get the class interface you want if you are using proxy generated classes.And yes you're right, using shared contract assemblies is definitely the way to go if that's available. I figured that out a bit later.
Rick,You write: 'With ASMX this process is straight forward: All I have to do is define my Web Service class mark it up with WebService and each of the individual WebMethod attributes for each of the exposed methods. Because the entity classes are marked as serializable and include a few strategic XmlIgnore attributes for several properties the process just works. ASMX creates the appropriate service wrappers and can take my objects directly as return values.'
Sep 16, 2010 It’s a common problem – you want to return an object from a WCF service as XML, but you either want, or need, to deliver some or all of the property values as XML Attributes instead of XML Elements; but you can’t because the DataContractSerializer doesn’t support attributes (you’re most likely to have seen this StackOverflow QA if you’ve done a web search). DataContract is under namespace System.Runtime.Serialization. During design time, DataContract Attribute is used to indicate which class should be represented as XSD. DataMember Attribute indicates which class member to be used in external representation. During my discussion with many people, they think about DataContract with a different passion.
Is it really that straight-forward? You had previously posted on how it wasn't that straight-forward and I'm wondering if something changed since that last post to make you change your mind.So far, the most 'straight-forward' way I know of to pass back a custom type from a web service involves editing the proxy class directly and removing the generated version of a custom class in favor of the real one.
That's not hard, but it does get aggravating trying to keep the proxy in sync during development. Mike - With WCF this mapping mechanism is indeed somewhat easier.IF. you design classes that include DataContract attributes which is reasonably easy to do if you're generating your business entities for example. This sort of thing wasn't really possible with ASMX Web services where the only way to deal with this was to plug into the Web Service pipeline as you mention (on either end of the connection).Then again the SOA nazis will tell you that we should never do this anyway - messages are just that messages and shouldn't be part fo the business layer in any way. While I see the logic in that, I find myself with applications that need to get entity data over the wire and writing custom converters (or worse hand copying data each time) is just not a realistic proposition. Obviously this thread has been quiet a while, but I thought I would leave a comment anyways as I was struck by your comment 'starting to think more in terms of services and message rather objects and object oriented architecture'.
SOA vs OOP, this really is a false dichotomy is not it? And not a particularly good excuse for the lack of support MS tools seem to provide for pure.Net development using WCF, that is,.Net client and.Net server, without losing all the goodness of well designed objects that should meet the business needs in general.I am firmly for OOP but nonetheless have been using WCF a while now with XML Serialization option (as there is no way I am going back through vast legacy of classes or indeed custom tools built up over years). Said tools exist to generate business classes from XSD and service contracts from WSDL to compensate for what visual studio and ms utilities don't provide in the code output as proxy. The approach is very much 'schema first' if not 'contract first' and I think entirely legitimate.I do not think it is in any way in opposition to a services model to built OOP libraries for server usage and expose only selected methods and desired types at the client via a service.
Surely that is the point, not to abandon the good of the OOP and shared component philosophy? The fact MS seem obsessed with pandering to Java devotees who will never use MS technology anyway, be it services or not, is not really an excuse for lack of built in support for pure.Net developers to generate proxy types on the client somewhat richer than at present.
A case in point is types inheriting base classes that provide routines for tasks like sorting, searching, and validation, all necessary on a thin client, even when disconnected from the network, and should not involve recoding to achieve.Or maybe I am a dinosaur and just don't know it yet.?! @Richard - I agree with your assessment and I feel closer to that with my own work, than true contract first as the SOA bigots would have it, because frankly in the end nobody really cares about the contract. Somewhere, somehow the contract needs to be consumed and put to use and very few if any Web Services are open enough to even worry about the whole concept of messaging for its own sake rather than exposing APIs.I've been working on a number of services recently that were clearly designed with contract first in mind and those have been an absolute disaster to consume.
They were horribly designed because apparently the people who did designed with the Contract First message in their head but no idea how to build a coherent interface that is actually reasonably easy to consume in the end. You end up with services that have two methods and pass one freaking message object that has fifty subobject variations on it and that's just plain crap.Unfortunately I've seen this kind of stuff from a variety of vendors who've published their APIs this way and the customers who need to consume this stuff suffer for this kind of misdirected logic.No doubt that there can be good and bad design for any approach including Contract First and maybe I've just had bad luck in this respect but I'm not encouraged from what I've seen.
Hi, i been follow your posts from at.Net Web Services and passing objects (and Data)Im having a similar architecture as you describe, i have bussines objects that are entitys and others more complex, currently i have some winforms, and in this presentation i access entitys and more complex logic.Now i need to separate presentation to run on a client and biz in server, my goal is to have this entity object go and comeback from presentation and server abstracting the transfer medium, what you finally think is the better approach (Remoting, WebServices/WCF) taking 1. Architecture, 2.agility as parameters?Also you mention you code-generate your entitys clases, how you accomplish this? Some VS add?Thanks. Hi Rick,I was having the same issues as you described for the inability to cast Entity objects that come back from a WCF service to the underlying type. Due to the definitions in reference.cs.I discovered that if my consuming web application was only a Visual Studio 'Web Site' instead of a 'Web Application'.
Then the proxy class generated for my WCF service doesn't even get the dreaded reference.cs file generated for it. And I was able to retrieve Entity objects from the WCF service and assign them to variables of the underlying Entity type without any problems.I really don't know why this is the case, but for me, I'm happy to just access my WCF services (that do all the real work) from a simple 'Web Site'.
Particulary if I can avoid all of these casting and namespace issues.Have you encountered this 'Web Application' / 'Web Site' difference?Cheers,Glenn.
While the
Serializable
attribute is workable, it is inadequate for service-oriented interaction between clients and services. It denotes all members in the type as serializable and therefore part of the data schema for that type. It is much better to have an opt-in approach, where only members the contract developer wants to explicitly include in the data contract are included. The Serializable
attribute forces the data type to be serializable in order to be used as a parameter in a contract operation, and does not offer clean separation between the serviceness aspect of the type (ability to use it as a WCF operation parameter) and the ability to serialize it. The attribute offers no support for aliasing type name or members, or for mapping a new type to a predefined data contract. The attribute operates directly on member fields, and completely bypasses any logical properties used to access those fields. It would be better to allow those properties to add their values when accessing the fields. Finally, there is no direct support for versioning because any versioning information is supposedly captured by the formatters. Consequently, it is difficult to deal with versioning over time.
Yet again, the solution is to come up with new WCF service-oriented opt-in attributes. The first of these attributes is the
DataContractAttribute
defined in the System.Runtime.Serialization
namespace: