We have a distributed system in which a Java-based server cache communicates with a C# front end, currently through object serialization.
One 'nice to have' feature that we've been kicking around for a while is the idea that when the server representation of an object changes, i.e. we add a new attribute, we shouldn't have to release an update for the front-end as well. Right now that's obviously not a possibility - you change the structure of an object, you change its serialized form, and the deserialization doesn't work (or at best captures only what it is used to picking up and no new fields).
I was wondering if anyone had encountered a similar problem before, and what sort of solutions they went through for solving it? One bright spark in the office has suggested we send XML to the client and it should directly build the UI from what is contained within that message - no construction of an object in between - but that of course brings its own problems.
All advice welcome :)
Cheers,
Dave.
you can define a "extra fields" Map<String, Object> as one of the fields in the objects you are planning updates for
however you will still need to tell the client to use it (but it will still be captured even if they don't use it regardless) and new types for the fields can break the front end when the client can't deserialize it
I would probably take a look at google protocol buffers. That protocol supports different protocol versions on the client and server side.
Use a serialization format which is more flexible.
Do not change existing DTO's, extend them
By doing so, the server can send an extended DTO, while the client deserializes the base DTO.
Many serialization frameworks have fields which is marked as optional, which you tag all the new fields with.
Related
I'm in the process of converting an asp.net application from MVC controllers to ApiController. So far everything is going pretty smooth, except I've had a few hicccups.
The problem I'm having right now is a few methods are having requests of the form:
sort:FieldName
dir:DESC
filter[0][field]:FieldName
filter[0][data][type]:string
filter[0][data][value]:deadeawd
(the content type is application/x-www-form-urlencoded;)
And the sort and the dir can easily be captured within a model class, and I've done so, but I don't know how to capture the filter[0] fields. (there could be filter[1] and so on as well, just how many there are is not known ahead of time, ie the data structure is dynamic).
Currently the application grabs the form data, and a method builds a query string based on the data there, but in Web API we no longer have access to the form data directly.
I could use a dynamic object, or a NameValueCollection, but I'm just trying to figure out what's the best option, what's the intended usage, and what's the best practice.
(in case you're wondering, the request data can't be changed, it's from a framework that we are using and don't have an easy way to override how it does things)
The answer we ended up going with was to change the framework so it sent a proper JSON object.
It was quite a bit of work, and it means it might be difficult to update it, but we're looking at moving away from the framework soon anyways, and we don't want the trivial little details of this framework to alter our API in a negative way.
If anyone is interested, the dynamic or NameValueCollection probably would've worked, and I don't think there is a best practice, because passing data like this is already bad practice.
I'd like to create C# code that accesses a WebService that has only 1 method:
public string HandleRequest(string xml).
The request itself is sent in xml, where the xml content specifies which type of action to perform and required/optional parameters as well.
The response from the service is also returned in xml and may be different per each request type that is sent.
I'd like to design a solution that will facilitate interacting with this service, and that will allow me to:
Dynamically generate an xml from given parameters (action type, other optional args, etc). Currently the xml is loaded from a file that was already created
Parse the response in an easy way (creating a strongly typed object from it?)
What's a good solution for doing this? I find it hard to come up with one, as the request/response xml is dynamic and may change from call to call.
Some additional info:
The service is Java based and is hosted under Tomcat (Axis 1.2)
There's no wsdl document for the service (even if there was, i wouldn't be able to automatically generate some strongly typed request/response classes, as the service itself receives and outputs only XML and not some complex type).
That sounds like an XML-RPC implementation could be what you are after. From Wikipedia;
XML-RPC works by sending a HTTP request to a server implementing the
protocol. The client in that case is typically software wanting to
call a single method of a remote system. Multiple input parameters can
be passed to the remote method, one return value is returned. The
parameter types allow nesting of parameters into maps and lists, thus
larger structures can be transported. Therefore XML-RPC can be used to
transport objects or structures both as input and as output
parameters.
Wikipedia also lists some Java Implementations of this protocol.
While, I've not used this specifically, I've worked with a service designed around a bastardised version of JSON-RPC. As it didn't follow the spec truely, we couldn't utilise any pre-existing implementations.
Personally, I didn't see the benefit of using such a protocol as we still needed to have clear definitions of the operations exposed by the service along with their associated constraints such as mandatory parameters etc. In addition to that, we had to handle the serialisation/deserialisation of JSON (XML in your case) to the associated object model. This was largely due to the vendor we were interacting with and their lack of conformance to the spec. If yours is conformant, then you may find that the existing implementations provided might give you a neat way of handling this.
Note the critisims regarding bloat of XML-RPC on Wikipedia too. It might pay to look into JSON-RPC as an alternative. There are certainly a few implementations listed that you can check out.
Edit: I didn't read your question properly. Sorry. I thought you were looking at providing a service. I'd still look at the links around XML-RPC/JSON-RPC as it may give you an idea as to how to knock up a test client. As far as .NET goes, I looked at the Jayrock codebase to get an idea of how the JSON-RPC protocol was implemented and if we could have used that in our scenario. You can get a rough idea as to how they handle the requests and responses. From memory, they may even have a test harness or sample code showing how to call the service. That could give you some ideas.
I'm just starting out really with WCF and Web Services in general. I have a pretty firm understanding on the purposes behind them and how they work, but I was wondering what the capabilities with them are if you wished to return something other than Text; such as a straight HTML form, or an image.
I've done some simple googling but alas all I can find is how to handle data passed from a form, rather than how to return a form.
I hope someone could give me a good starting point on what I should be looking at. I looked at a thread stating to look at Streaming with WCF but that may seem a bit excessive and was wondering if someone could give me some general advice and input.
Many thanks,
Ronald.
WCF services can return any object that the runtime can seralize. We return custom objects in our services with no issues, provided it's a .NET Client consuming them. Other languages may have to work harder to de-serialize complex objects.
(Meaning you have to write more code because non-Visual Studio IDE's probably won't know how to auto-generate the required client code.)
It probably depends on the actual binding but, for the sake of simplicity, assume that you bind your WCF service over http. Then, everything you pass to and from the service should somehow be translated to string. Simple types, ints, doules, strings, are easily convertible. Compound types - also, as they consist of simple types. When it comes to specific types like images or html forms, you always try to find a way to convert them at one side and convert back on the other side. In many cases the serializer can do it for you, for example if you return byte[], the data will be encoded as base64 string. If the serializer fails for some reason, you have to find your own way to pass your specific types. Please also remember that for WCF, it is you to select a particular serializer:
http://nirajrules.wordpress.com/2009/08/26/wcf-serializers-xmlserializer-vs-datacontratserializer-vs-netdatacontractserializer/
WCF is designed to build web API using standard or custom protocols. If you use the default configuration, WCF will output objects serialized using SOAP, but JSON is available too, for instance.
WCF is certainly able to output plain HTML, but it isn't designed with this goal in mind. It is meant to be used for communication between processes.
I've looked at quite a few of the questions on the site, but I'm still having trouble fulling understanding where to begin.
I've never done anything with webservices before, so bear with me.
The current project I've been assigned is to write a webservice that queries a database and returns the data back to the client. (using .NET 2008 programming in C#)
So far, I've been able to do basic data types no problem, but I'm not 100% sure where to go from there. I've been returning an XmlDocument type, but I'm not sure that that's the best way, or even the correct way to do it.
Currently creating an ASP.NET Web service, though it's been suggested I use a WCF Web service.
Can anyone shed light on where to go from here? Or perhaps a a link to a tutorial on sending and recieving large amounts of data via webservices?
EDIT: The answers are great so far, but I'm still not 100% sure how to answer. I think the webservice will be interacted with a combination of client programs, but also websites, if that is all possible... That's how new I am to this.
Depending on the structure of the data that you're sending back to the client, I wouldn't recommend using XmlDocument as the return type. It will add a lot of unnecessary bulk to your response.
You really didn't state the protocol that you want to support, but if you're transporting data via HTTP, then sending your data back to the client as a JSON-formatted string would streamline it better.
You can define that you're returning your complex type formatted as JSON like this:
[WebGet(ResponseFormat=WebMessageFormat.Json, UriTemplate="GetComplexObject/{id}")]
public MyComplexType GetComplexObject(int id){
//do work to get your object
return myObject;
}
WCF will take care of serializing your object as JSON if MyComplexType is defined as a DataContract...
[DataContract]
public class MyComplexType{
[DataMember]
String Name {get;set;}
}
If you're looking for REST-ful services, then WCF is probably the preferred approach using the WebHttp functionality.
The WCF team put together a great series of walk-throughs on using WCF WebHttp (which is new to .NET 4). They assume a little knowledge of web http programming, but they're pretty good and hopefully help put you on the right track.
I hope this helps!! Good luck.
http://msdn.microsoft.com/en-us/library/ms733127.aspx
WCF uses this concept of a data contract - which provides serialization help on complex objects.
If you decide to use WCF there is a tutorial available at : http://dotnetslackers.com/articles/ajax/JSON-EnabledWCFServicesInASPNET35.aspx .
In general, this article gives a walk through of building an ASP.NET web service that sends JSON.
JSON is faster than XML, and is becoming a standard for most new web services. I highly recommend the JSON.NET library for JSON serialization.
There are two ways that I have implemented this using a regular ASPX.NET web service:
Have the same underlying object libraries on the client and the server and functions to translate the data from the web service object to the client object.
Have the same underlying object libraries on the client and the server and pass data to/from the server as a string representation of the data object (usually XML format, but could be JSON or another similar format)
The first option I found is VERY cumbersome. The web service will claim that its versions of the libraries are unique, even if you have the same classes/objects on both the server and the client. Even if the namespace is the same, the object returned from the web service will have the web service namespace in it somewhere, so you have to write functions to convert them. I know of a way to fix this, but it is not worth the effort, at least not for me.
The second option is the one I am using right now. I again have one library on both client and server. It has objects that get and hold data from the database. I then have generic utility functions that serialize objects to and from XML strings. When I send data from the server I serialize it to an XML string on the server and deserialize it at the client. I do the reverse when sending data to the server. I also break up large amounts of data being passed to/from the web service to reduce errors and data transfer time.
WCF may be better. Never used it. But the above is what I have done with standard web services.
The best way to send data back to client it's throught xml, because almost all languages know how to handle xml document.
If you want to return something that it's in some way language dependent is't not worst to implement if you want your web service to be implemented using virtually all languages posible.
Another posibility is to return json objects.
This is a general question concerning the Workflow Foundation (.NET 3.5) and versioning the data that it works with. We have a lot of custom activities that work with some data and this data may be interesting also for the future analysis of the already completed workflows (provided that we configure the tracking in such a way that it stores it in a serialized form).
It may be necessary to show the data from the past in the UI, but the data inevitably changes the structure (class definition / internal structure if it's dynamic) and the redeployed version of our library will contain the new data definition while the serialized data in the tracking database will be still in the old structure.
Is it better to use dynamic structures that don't change from the beginning (like a property bag) or rather later deal with the redeployment and somehow transform the serialized BLOB into the new one ? Have you ever used some approach in a similar scenario ?
A lot depends on how you deploy your application. If you use a strong name and deploy to the GAC or multiple private assembly paths deserializing a workflow will deserialize the exact version of your class. That means that you code must be able to work with multiple versions and that can be a bit of a pain. Storing data in a property bag is not going to help you there. If you use assembly redirects to point to the current version of an activity solves that part and I suppose using a property bag would make life simpler then. That said I tend to stick with dependency properties and regular serializable classes so far.
I did a series of blog posts about long running workflows and versioning where you run into exactly the same problem. Check here for more details.