I have to return an object using axis2 webservice. The object contains a list of other object. The WSDL shows up as xs:anyType. When retreiving the object from client it shows up as org.apache.axiom.om.impl.llom.OMElementImpl
how to use axis2 to retreive an object that contains a list
You cannot take a complex object, return it with a web service and expect the client to reconstruct a object perfectly identical to the original. Remember the wsdl is an abstraction of the web service implementation. Also, clients may be written in a language with a different feature set.
The trick is to have your web services return data types that are as simple as possible. Anything from elementary types to simple java beans based on elementary types will work well. In your case, return an array instead of a List.
I have mentionned Java because it sounded like you could be using this language. It may not be the case, but the general rules I have outlined still apply.
Phillippe A. is right.
Instead of lists of objects, you want to return arrays of objects.
Related
Can we send a Generic List ( List) as a parameter to a WCF OperationContract?
Seems like the only way to do it is to encapsulate the List as a DataMember inside another Class and specify the class as a DataContract:
But that doesn't look right to me. Is there any other way?
EDIT1:
intended Signature:
[OperationContract]
List<int> OperationName(List<CustomObject> objects);
This translates to CustomObject[] at the client. I am currently passing CustomObject[] from my client and it works fine, but I want to know why I can not pass
List <CustomObject>
which gives me a compile error saying there is no overloaded version of the function which takes the specified parameters (type mismatch error)
EDIT 2:
Related Questions:
1) I should be able to control this from the service itself. What if I am exposing my service to the entire world and the wsdl/Proxy is the only way they would know of the signature of my OperationContract?
2) What if I want to use both System.Array and System.Generic.List in different Operation Contracts in the same Service Contract?
List is an advanced type and may not be available to all the programming paradigms. Array, in comparision is perhaps available in all the programming paradigm. hence by default the translation will fall to array for a proxy wsdl
Now in this case, If you are sure that your client is .Net, you can change the client to use List. Since the service does not know what client's programming language is, the current design of svcutil where client decides whether it uses list or array is correct. If you make this setting available in service, you are ruling out clients which does not have the concept of List
Coming to your second question, as long as your operation contract names are different, you will be able to use the array and list distictly in the same service. Also note, OOP concepts are restricted in SOA, which means you can't have polymorphic methods.
the following question has more details about OOP and SOA
WCF Object Design - OOP vs SOA
I need to serialize an object to pass it as a parameter in a webservice. I followed the recommendations the the article:
DataContractSerializer Error using Entity Framework 4.0 with WCF 4.0
This Object is quit complex because it resembles a hierarchical data structure.
Now I have a problem, because the related objects (one to many objects) are not loading and their value is null.
This is not a problem if I use Dynamic proxies, however dynamic proxy objects do not serialize for use in a webservice.
I have tried to turn on / off lazy loading in the dbContext but it made no difference.
Any one knows how I can work around this problem, perhaps even loading a proxy object and copying it to a 'Real' Object?
Thanks
If it's a relationship that you really must have, your best bet is to load the data using the normal dynamic proxy object and use something like AutoMapper (or a manual conversion) to convert it into whatever you want to send across the service. You can then ensure that what you want to send gets loaded and populated.
Trying to tell EF and WCF to know how to automatically get it right for a complex hierarchical object just isn't worth the effort compared to doing the loading/conversion manually.
I have a WCF service method that expects an object and then retrieves its properties using reflection.
On the client side I create an anonymous type object
var obj = new {FirstName="John", LastName="Doe"}
and pass it to the method. I'm getting an exception:
Type '<>f__AnonymousType0`2[System.String,System.String]' cannot be serialized.
Consider marking it with the DataContractAttribute attribute, and marking all
of its members you want serialized with the DataMemberAttribute attribute.
See the Microsoft .NET Framework documentation for other supported types.
I can't mark the type or its members with serialization attributes because there is really no type nor properties declared explicitly. Is there a way to overcome that problem?
The answers suggesting that you can't use an anonymous type over WCF are wrong.
If you are using the default DataContractSerializer to serialize your types on the channel, then yes, the answers are correct. This is because the DataContractSerializer supports the following scenarios:
Types serialized using the Serializable attribute
Types serialized using XML Serialization
Types serialized using the DataContract attribute
Plain-Old-C#-Object (POCO) Serialization
Respectively, they fail with anonymous types because of the following:
You can't apply attributes to anonymous types.
XML Serialization requires a default parameterless constructor, which anonymous types do not have.
Same as 1.
Same as 2.
However, you are not forced to use the DataContractSerializer to serialize your messages in WCF. You can create a custom message formatter which you can use to perform the serialization yourself.
You have a problem if the types you are sending out as the results of requests are anonymous types. When you get the results back, it's going to have a definite name within a namespace (not in a .NET sense, but in a SOA sense) and you are going to have to handle the mapping of that concrete type back to the anonymous type. However, because you don't have access to the actual anonymous type or ways of constructing it in code (at least in a dynamic way), you have no choice but to pass it along as an object if it's passed back to you, which makes it kind of worthless, since everyone will have to use bad practices such as dynamic (not a bad practice in itself, but to get around these limitations in this case, yes), or cast-by-example.
So in the end I will say that while it certainly is possible to serialize anonymous types and send them over the wire, the work invovled is usually not worth it.
Don't do this.
It's an attempt to be clever. Don't. Just declare the datatype you need, and use it. If you need a more loosely-defined datatype, just use a key-value mapping of some sort.
It will take you 5 minutes to write something that can handle this for good. Using any technique like this will cost you hours of debugging at some future point down the road.
You could serialize the object into a JSON string and send it through WCF, like so:
//in WCF Server
dynamic mysentclass = new { FirstName = "John", LastName = "Doe" };
string jsonstring = JsonConvert.SerializeObject(mysentclass, Newtonsoft.Json.Formatting.Indented);
//send the string through WCF
//in WCF client
dynamic myreceivedclass = JsonConvert.DeserializeObject<dynamic>(jsonstring);
MessageBox.Show(myreceivedclass.FirstName.ToString() + " " + myreceivedclass.LastName.ToString());
The example uses Json.Net, which can be obtained here:
http://www.nuget.org/packages/Newtonsoft.Json/
You could also use System.Web.Script.Serialization.JavaScriptSerializer (in System.Web.Extensions.dll), which is not as powerful as Json.Net, but would suffice for simple objects.
No, there is not. While there are tricks and techniques to return objects of an anonymous type from a method, you cannot send them over WCF.
WCF needs to know all of its concrete types that will be sent across, since you're not really just calling a .NET method. Instead, the message call gets converted into a serialized message, and therefore, any "thing" being passed over a WCF call must be serializable - no exceptions.
You've already got the answer. It can't be done.
In fact, you can't pass an instance of an anonymous type from one method to another within your program. You certainly can't pass them between programs.
As said before, the objects must be deserializable and so you will have to define the structure beforehand. However, you can use inheritance to defining them, and hence lower the pain. WCF provides the KnownType attribute to allow a Service Operation to receive an object of the base class and deserialize it into an object of a derived class. So you will still only have one (or a few) Service Operations that can handle all your scenarios.
Please note that my experience in Silverlight/.Net and WCF is about two weeks of googling and deciphering tutorials. I need to attempt and provide feedback to a client on if Silverlight will be a possible solution to their application needing a RIA front end.
The client has a rather large .Net based application with a UI layer built which greatly relies on the creation and manipulation of specific (personal) classes and objects from the backend (which would be the server side).
A summery of what I understand to be the general procedure: one can pass simple objects containing simple data types, or more complex .Net type objects. Basically anything which can be understood by both client and server side, after serializing.
But what is the limitation to the complexity of an object I can pass? Or phrased otherwise, would silverlight and WCF be able to support the passing of a personalized object which may contain references to other classes/objects and variables etc?
Additional Info (in case it can help):
I am not allowed direct access to their backend code but with the information I have been given I can safely say their classes heavily use inheritance and overloading of functions/methods in the classes.
As far as I know there is nothing specific to Silverlight. There are some things to keep in mind though.
WCF serialization doesn´t like circular references.
All types need to specified in the contract. So watch out with inheritance etc.
In general using DTO's (Data Transfer Objects) and not exposing your business objects is the way to go.
The metaphor is one of message passing as opposed to passing objects. DTO's as Maurice said.
You can get pretty complex, but each object needs to have its contract defined.
Problem:
WCF contract objects cannot implement 2 types of lists (ie: List and List).
Long-winded explanation:
I'm building a WCF service on top of an existing core system, and I'm trying to work out the best way to implement some of my business objects.
The core system utilizes interfaces for all business objects - Person management functionality, for instance, requires that I pass in an object which implements IPerson. Nothing out of the ordinary here.
The goal is to have a contact object (Person) which can be used on the service side of things, and also implements IPerson so that it can be passed into the core without requiring a conversion layer. This all works just fine for items like Person.
The issue comes in for lists: a method in the core, for instance, might require a IPersonList to be passed in, and as anyone who's dealt with inherited generics will know, List does not inherit from IList.
In our currently running ASMX service, we implement this with some up/down casting in the web objects. "WebPerson" will inherit from List, and implement IList explicitly so that the IList properties do not show up on the WSDL.
In WCF, however, if you try to use this same object, you will get the following error:
Type 'Cssi.IBroker.Service.Cssi.Contracts.PersonList' with CollectionDataContractAttribute attribute is an invalid collection type since it has multiple definitions of interface 'IList`1'.
Apparently, now that the new WCF serializer knows how to serialize IList, it's no longer able to ignore the second explicit implementation.
If possible, I'd like to avoid creating a PersonList object just for the contracts and then converting to and from an IPersonList object for each call. Changing the core business logic to use concrete objects designed just for the WCF services isn't an option.
Help!
I ended up deciding the best route was a set of dedicated objects used only for the contracts. With them being dedicated to one task, I was able to keep them cleaner without having to compromise my internal design for the sake of the WSDL. For the WSDL objects themselves, I ended up using arrays instead of IList.
The extra step of conversion is a bit cumbersome, but less than trying to keep my core objects WCF friendly would be.