We facing a serious issue, but before saying that it's a bug in .net, I'd like to know if someone understand what's happening and why.
That's our configuration :
1 project DAL
1 project proxy
many others project that use DAL with WCF services as well.
They communicate with wcf services.
We have added some properties in one object in the DAL
We havn't updated service references in the proxy project.
(1)In the proxy with a breakpoint, we can see everything is retrieved properly except of course the new properties (service reference not updated => nothing abnormal)
The proxy is returning a JSON with WebMessageFormat.JSON ( we using the default provided serialization)
The response of the method called in proxy that call the (1) one in DAL is empty.
So it's definitely a problem in the JSON serialization ? no ?
Worst, we decided to changed from WebMessageFormat.JSON to WebMessageFormat.XML to see if the same happened, ==> It didn't
Last thing, no problem with other projects that hadn't been updated (they not using JSON ser)
Does someone have faced the same issue, or know why this is happening ?
Any help would be really nice :)
Thanks in advance to everyone and sorry for my english.
(This is not a definite answer, but a suspicion. However, this was too much to include as a comment.)
Note: I am assuming the following from your question (please correct/clarify if wrong).
The proxy project calls DAL through WCF and not the other way around. This would explain (1), and properties not updated through each layer.
A client calls the proxy project, which exposes itself through WCF too (this would explain the proxy project returning a WebMessageFormat.JSON response)
The issue here may be, as you say, with the serialization of the proxy response itself. While it's always advisable that you update your project references, in such a case it is possible that the generated classes are not mapping exactly to the response that they describe.
My take so far is that the changes in the classes had changed the internal responses in such a way that the references can no longer be mapped correctly to the response type, which is likely the ones from the mapped classes. The XML serializer is likely a separate implementation of the serializer, so it is likely that the JSON serializer has the problem failing on this specific case. You could check if this is the case by checking if there are any first chance exception in your internal output, or by adding debugging outside of your own code. This would likely confirm that the JSON serialization is facing an issue.
It may be actually be a bug, or an unsupported scenario when properties to map are not present.
I would advise that you use the DataContractSerializer with JSON if you are going to be consuming serialized JSON data from WCF (Set up your data contracts of course). I've ran into a few problems with JSON serializer, and realized it's a bit iffy with .NET
Another solution is to use this JSON serializer with .NET:
http://james.newtonking.com/json
Do you have object of type date or any other non primitive data type in the response data, I have faced problem when i try to include date object in the response data, for a quick work around I changed the
data type to string, it worked for me.
Related
I was given a wsdl by a third party.
This wsdl is defined using MessageContract (which I'm sorry to say, after much Googling I still don't understand what the differences are when using MessageContract vs ServiceContract from a client perspective)
After instantiating an new complex object of Type BaseComplex, which consists of arrays of ComplexA[] and ComplexB[] , where ComplexA has Decimal and Decimal? properties defined, I then call the service method passing in the BaseComplex type. (I unfortunately cannot debug the service request locally because of firewall, however, I have verified that the BaseComplex.ComplexA.Decimal field HAS A VALUE just before making the call to the service.)
Once the code is placed on the server, my team has used WireShark to see exactly what's in the packets going across the wire. When we look at this, ComplexA.Decimal field has been omitted... Not even empty tags.
The only step I can think of that happens between the client.SendRequest(BaseComplex) call and what the WireShark output shows, is the .Net framework's Xml serialization. I've Google'd the crap out of this issue but have not come across anything to point me in the right direction.
Why is my client failing to make the request xml properly?
A couple of notes:
I have pulled the wsdl given to me into SoapUI and when running this on the server, we see successful results. ( I use the same values in my testing when running through code)
I am only the consumer/client of this wsdl and have no control over the wsdl/service definitions.
I have no real understanding of why the service was done using a MessageContract and not a ServiceContract... (I've never had this problem before with ServiceContract)
One of the most interesting aspects to the problem is that the ComplexBase has a Decimal field defined, and this field is serialized properly. That is to say that Request.DecimalProperty serializes but Request.ComplexA.DecimalProperty does not.
Some other notes is that this is only a problem with Decimal and nullable Decimal fields in the ComplexA type. ComplexA.DecimalProperty and ComplexA.NullableDecimalProperty are failing to serialize.
Any and all help is very appreciated. Please request if a sample is necessary, (I didn't include on this post because it will need to be masked for security reasons)
So, I've figured this out.
The wsdl defined objects have the decimal and nullable decimals along with a bool of each that is defined as DecimalFieldIsSpecified. For some ungodly reason it's necessary to MANUALLY set these to true in order for the xmlserializer to pick up the fields....
I have been following this tutorial to add protobuf-net to my WCF project. I have a shared DTO library. Both server and Client use those DTO classes. I have attributed all my Service methods with [OperationContract] attributes, but i have not assigned any [DataContract] attributes on my DTO classes.
I added the protobuf-net Nuget package and added the configuration to the web.config.
I am using IIS Express to test my service, and thought that i should be ok with what i had done so far. However, after testing a few calls, i noticed that i forgot to add protobuf-net to my client and yet everything worked as expected (ie. no errors from serialization or deserialization).
I suspect that protobuf is not used in my program at all, and that i am missing something. I'd like to avoid using [DataContract] attributes but i could live with adding them, if that is what is need to get protobuf-net working.
What else am i missing?
A year ago I faced the same problem, where protoBuf seems to be an excellent option, with WCF it has some shortcomings.
I created an open source project to overcome these shortcomings, it uses protobu-net library and adds functionality to it, such that you don't need to share assemblies anymore with client. It however again requires you to put DataContract attributes though currently.
You can give it a try: https://github.com/maingi4/ProtoBuf.Wcf
DISCLAIMER: I am creator and owner of the above project.
I am working on the asp.net web api where i have to return back objects in json. With respect to making a better approach and easy for (android/ios)mobile developer to consume these Web APIs and parse json objects, what is best approach for making these objects definitions remain shared amongst webapi project and mobile project, so that if we have to change any property then it can easily be reflected on both projects in a better way. It would be great if someone explains it in detail.
There is no such sync method as you are asking.
On your WebAPI server side you'll define the objects and then return them in your API methods. JSON serialization will be automatically handled by the framework, using your serialization engine of choice (i.e. JSON.NET). Remember that with WebAPI you don't decide the output format server side, you just return a response containing the object(s) and then the framework reads the HTTP HEADERS of the request to determine whether the client asked for JSON or XML and then returns what was asked.
The best thing you can do is define a clear API with nice conventions and keep it documented, and if you change anything have the documentation reflect the changes. Avoid making breaking changes, and if you really must, deprecate a property or an object for at least a couple of versions before removing it.
That's the way all public API work anyway.
I am building a test-stub for a webservice, implementing the interface retrieved from the production webservice using svcutil. When calling a method on the stub i get the exception;
Object of type
'Sbsys.Services.HostService.DokumentBoks.DKALWSAfsendService.MaterialeType[]'
cannot be converted to type
'Sbsys.Services.HostService.DokumentBoks.DKALWSAfsendService.MaterialeType[]'.
where 'Sbsys.Services.HostService.DokumentBoks' is the namespace of the consuming client, and 'DKALWSAfsendService' is the namespace containing the generated proxy classes for the service.
Any ideas on whats going on?
Bonus info: When using the production service everything works as intended
Solved: I had a suspicion that it might be a versioning problem, and moved my servicereference to an isolated project, containing nothing else. Referenced this from both the consuming client and the webservice stub, hoping that this would solve any problems with building multiple times or whatever. Presto. Problem gone.
Any chance that the wsdl/contract in prod is different from the one you call against ? If the proxy has been generated against the prod and use on another instance of the service with a different contract, you might have that kind of weird message.
Sometime this error occurs because of Generate Serializable Assembly option in Project properties (especially if you are using per-generated serialization assembly using sgen). Try setting this option in Project properties to Off and see if it works. After you turn this option off you will need to per-generate your assembly using sgen. There is some good discussion and background thread in this Q&A for this.
Ok, not really sure how to word, but will try my best.
I have a number of WCF services that are setup and run awaiting an object to come in for processing.
WCFServiceA
WCFServiceB
WCFServiceC
Service A will run some processing and decide to send the object onto Service B or C.
So my object has [DataContract] attribute on all classes in it and [DataMember] on all properties.
So so far so good.
But now I well lose all the functionality from my object, as this is now basically a serialised version of the object.
So is it best practice if I want to use a full complex object to include the same assembly in all 3 services as a reference and send things across as "KnownTypes"?? Providing the basic DataContract and DataMember for anything using the services that does not know these types so they can still create these object for the services to run with?
Hope I have worded this correctly and you understand my question here.
:EDIT:
To try and clarify.
The object I am sending can have a "Policy" attached to it, this policy object is a class and can be one of several types, vehicle, house, life, pet policy etc.
But the actual type will not be known by the receiving service. Hence the need for KnownTypes.
I think I just answered my own question!! :)
That was a good explanation of the problem. The draw back I see in this approach is if you are going to update the object , say adding new properties or removing some , all the 3 service needs to be updated with the new assembly.
Using of the known types can sometimes lead to backward compatibility issues when you want to upgrade the objects in live depending on the setup.
Or create a DTO (Data transfer object) with just the properties and pass it across the services as a data contract and strip the complex logic in to a helper class which can be referenced by the services.