I need to generate or define new class based on deserialization serialized class. So I want to transfer class definition from server to client to have access to it's properties later.
Is it possible and how?
Proper way to do it would be to either expose a schema definition for your service for clients to consume & generate strongly type class definitions from that or provide a DLL with your DTO contract definitions (class/interface definitions) to the client.
If you chose neither of those approaches (no schema & no dll with interfaces) but still
want to generate a class definition, you can in an improper way generate .cs class definitions, from a sample data of the service (call the services couple of times and intercept the responses or use some http client). However this approach does not guarantee that you will get an accurate or/and complete generation. Basically you can go from:
XML->XSD->C# cs class file (or even XML to C# cs file directly)or JSON->C# class file
And deserializing object to dynamic especially when you don't own both the server & client code is pretty much the worst thing you can do. And this way you didn't transfer you class definition to the client. Deserializng to dynamic objects is actually no desrialization at all as matter of fact, it gives you a dictionary of strings with syntactical sugar to access them as properties at runtime with not compile time support which can be equal to a disaster. In short don't do it unless you own all the code (not that it's a good idea then either but maybe you could get by somehow)
One portable way to transfer the property definitions and the data itself is to use the JSON serializer.
You can deserialize into a dynamic object using JSON.Net
Deserialize json object into dynamic object using Json.net
Related
I need to have a REST server (written in C#) pass a JSON object to/from my typescript client running in a browser. The best way to do this is define the class on the C# side that then creates a JSON object passed to the client where that JSON object matches the class structure in the client.
Which leads to the obvious question - is there a way to define the classes in C# and then run some program that will create the .ts class definitions? Or the reverse where I write out the classes in .TS and a program then creates matching .cs classes?
What I want to avoid is having to make sure any member added on one side is then added exactly the same on the other side.
And in a perfect world, the comments written for the class members are carried across too.
Update: I know I can write such a tool. However I'm hoping it already exists as that's a lot of work.
Type lite http://type.litesolutions.net/ gets you halfway. Just the data member signature.
As you know json doesn't carry behaviour just data. So no functions will not be available on the other side. It's not a "transpiler"
And in a perfect world, the comments written for the class members are carried across too.
Doesn't do this.
I created a library which allows you to create JS-models for knockout and backbone out of c#-classes (mainly for domain-classes, so it comes with stuff like DataAnnotations-support, etc).
I added support for Typescript, as well as a small tool to create the files directly.
Check it out and if you have time, I'd love some feedback :)
https://jsmapper.codeplex.com/
Cheers,
Richard
I have an ASP.NET MVC application where I declare a few C# models for my data. However, I also process the data on client side and it would be nice if I could somehow get a JavaScript representation of a C# class so I do not have to re-declare the same data structures in JavaScript. Ideally, in my client code I would reference a script with class name as a query string parameter and it would return the JS code defining the constructor for the needed C# class. E.g.
<script src="/model/get?type=Myapp.User"></script>
Of course, it would all happen in runtime with help of reflection.
Is there any existing solution that does that? Thank you.
You can return instances of objects as JSON using built in JsonResult class, but for type information you will need to build something yourself (again likely returning as JSON).
Json.Encode(MyObject)
or get newtonsofts json library (its better), It has many options, including type information, which can be useful for inheritance.
However.... any circular references are problems. Quite often its better to make an anonymous object with a minimal object structure that your view needs, then encode that.
I have some WCF services which employes default DataContractSerialization. Some of the service methods return Dictionary objects. One of the clients are generating XSD files from WCF services (biztalk related) and he is requesting to convert all dictionary types to a new dictionary type which implements IXmlSerializable.
I wonder, if there will be any unexpected results of this conversion which may affect the DataContract serialization somehow?
Update:
Server and client share the same domain dlls, clients do not generate them from service. Maybe in the question I was missing the main point; I wonder if an object is to be serizalized through datacontract serialization, implementing IXmlSerializable in the object will cause any problems.
Is your client sharing dlls with the service?
Unless he is sharing libraries (dlls) with service then making changes at the service end won't make any difference. Your WCF is returning data, not classes. That data is being reconstituted into classes which are created by the client based on the definitions in the WSDL your service returns. You can't control those generated libraries (by making chnages on the server) unless you share dlls between the client and the server.
If he wants to wrap the generated dictionaries in an IXmlSerializable dictionary then he can, or if he wants to generate a different type of dictionary then he can probably do that as well, but I don't think there is anything you can do server side.
Tell your client to use the following serializable dictionary when they need to serialize a dictionary result from a service call: C# Serializable Dictionary – a Working Example
It accepts an ordinary dictionary as constructor argument thus converts any dictionary into a serializable one. You can also return SerializableDictionary type as the service call result if you like.
There is an unexpected problem; since domain objects are already implementing data contract serialization, there is no way to implement IXmlSerializable without modifying the whole serialization mechanism.
In our project we are consuming WCF webservices exposed at Central location as services with basicHttpBinding.
In client desktop application we need consume those webservices. I am able to generate proxy class using WSDL.exe.
But, I need to convert data/class given by the webservice into my local class, for that now I am xmlserialzing those class/objects given by webservice and deserializing into my local classes as both classes schema matches exactly same.
Is there any better way that I can follow?
or
Do I need to assign each property from one class to another?
thanks
nRk.
declare class manually instead of generating. This is the most DRY solution.
try Automapper
If you have control on your local classes (they are not generated code; or you are generating them, yourself) you can use xml attributes to decorate your class, so you can serialize and deserialize it to that xml you work with and you do not have to have specific names for your properties. In addition to this, you may have additional properties on your local class.
If you have not control on defining your local classes, then you have to define a converter or as elder_george mentioned, use AutoMapper.
Using a manual written converter IMO is the fastest way and you can define them as implicit converter operators on your local class.
I've done the serialize/deserialize thing myself just as you had. If your classes have the same properties as the proxy classes you could write a helper method that uses reflection to iterate through the properties of the proxy and set the corresponding properties of your class. As long as the property names are the same, that one method should work on all classes.
A few thoughts:
use assembly sharing via WCF; this allows you to use the same actual assembly at both ends. As long as this is a DTO assembly, this is fine (not hugely portable, though). This is /reference (also /r) in svcutil.exe, or you can do it via the IDE
use DataContractSerializer and round-trip (like you are already; just that WCF maps most closely to DataContractSerializer, not XmlSerializer)
I'm still new to the ASP.NET world, so I could be way off base here, but so far this is to the best of my (limited) knowledge!
Let's say I have a standard business object "Contact" in the Business namespace. I write a Web Service to retrieve a Contact's info from a database and return it. I then write a client application to request said details.
Now, I also then create a utility method that takes a "Contact" and does some magic with it, like Utils.BuyContactNewHat() say. Which of course takes the Contact of type Business.Contact.
I then go back to my client application and want to utilise the BuyContactNewHat method, so I add a reference to my Utils namespace and there it is. However, a problem arises with:
Contact c = MyWebService.GetContact("Rob);
Utils.BuyContactNewHat(c); // << Error Here
Since the return type of GetContact is of MyWebService.Contact and not Business.Contact as expected. I understand why this is because when accessing a web service, you are actually programming against the proxy class generated by the WSDL.
So, is there an "easier" way to deal with this type of mismatch? I was considering perhaps trying to create a generic converter class that uses reflection to ensure two objects have the same structure than simply transferring the values across from one to the other.
You are on the right track. To get the data from the proxy object back into one of your own objects, you have to do left-hand-right-hand code. i.e. copy property values. I'll bet you that there is already a generic method out there that uses reflection.
Some people will use something other than a web service (.net remoting) if they just want to get a business object across the wire. Or they'll use binary serialization. I'm guessing you are using the web service for a reason, so you'll have to do property copying.
You don't actually have to use the generated class that the WSDL gives you. If you take a look at the code that it generates, it's just making calls into some .NET framework classes to submit SOAP requests. In the past I have copied that code into a normal .cs file and edited it. Although I haven't tried this specifically, I see no reason why you couldn't drop the proxy class definition and use the original class to receive the results of the SOAP call. It must already be doing reflection under the hood, it seems a shame to do it twice.
I would recommend that you look at writing a Schema Importer Extension, which you can use to control proxy code generation. This approach can be used to (gracefully) resolve your problem without kludges (such as copying around objects from one namespace to another, or modifying the proxy generated reference.cs class only to have it replaced the next time you update the web reference).
Here's a (very) good tutorial on the subject:
http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wsproxy.mspx