I was curious as to how I would accomplish the following with webservices:
Authenticate a user.
Accept a CSV or XML file.
Process the file and put it into an SQL database.
Someone mentioned in a previous post that I should use a webservice. I can't seem to find any resources that explain how to begin something like this. All the simple examples seem to just show how you can serve XML given a query.
I want to know how to accept stuff and also, how this would differ from an upload control on an authenticated webpage. I don't think I really understand webservices and their benefits.
How would the user sending the XML file interface with my webservice?
If you want to do large file uploads, then a web service may cause some issues, because some web service platforms (including .NET) have default settings limiting the size of the data.
The advantage of a web service is that it does all the mapping of the request to/from XML, so you can return a .NET type, and don't need to muck around with processing request parameters.
However, you may have to put more effort into maintaining state, etc.
For logins, what you can do is have a login function that returns some kind of identifier which can be used to verify the user as valid for that session - one way of doing this being to have columns in your user table for lastActive and sessionGUID, and when they log in you generate a new sessionGUID and return that, and on that and any other valid request they make you update the lastActive, and if there is a request too long after the lastActive time, then you refuse the request... there's any number of similar ways of doing that, but hopefully you get the general idea - you don't want to require the login details each time, but you can generate a temporary identifier and use that.
For accepting an XML file, you'd want to use something like XDocument or XMLReader to read the data that you receive. Assuming you're not talking about the parsing of the XML format that the web service itself uses, you're most likely to be receiving a string and then pushing that into an XDocument and then using the standard XDocument functions to process the data. If the document would be large, then XMLReader should be more efficient.
For reading a CSV file, there are some (free and non-free) CSV readers which help avoid some of the issues you can have, giving you a nice API for processing a string or strings of CSV data. If you know that the source data doesn't have non-structural commas, though, you can just take the string and split it by commas, and then strip any quotes around the values. That tends to get flaky quite fast if there might be addresses or other data that could have commas in, though.
The XML should be able to be passed via the web service just fine - it should be encoded and decoded, so it's then compliant strings being passed out.
As for storing it in a database, there's any number of ways to do that - you can use ADO.NET to store things in a database without further libraries, you can create a database structure in Visual Studio or SQL Server Management Studio and then use SQLMetal or Linq to SQL to generate classes for saving the data, you can use a 3rd party database mapping tool (such as Castle ActiveRecord), or whatever. It depends what you know and how much you're willing to learn. That's really separate to the web service. When you define a web service in .NET you effectively define standard functions with attributes marking them as web services, so the database side is standard .NET database stuff that's not necessarily any different to what you'd do for an ASP.NET website, or even a desktop program.
A web service is not really appropriate for sending an arbitrary file. It can be done, but if that's your only reason for creating the web service, you might as well just stick to HTTP.
If the file has a specific format or specific contents then you might want to create a web service for that. The purpose of an ASMX or WCF web service is to provide discoverability and strong typing to the data (among other things, but I'm sticking to the basics for the moment). From the perspective of the client, instead of trying to create some ugly XML or CSV blob and chuck it over HTTP, you use an actual service proxy with POCO classes:
MyService service = new MyService();
MyData data = new MyData() { ID = 3, Name = "Test", Date = DateTime.Now };
service.Save(data);
Visual Studio (and equivalent tools in Java and some other platforms) will take care of generating the proxy for you, so really all you have to do is write the above code.
But if you're just trying to send any data, this won't get you anywhere, because you can't generate a proxy for raw XML. Well, you can, but it would just be an XmlDocument and that accomplishes nothing in terms of usability, type safety or discoverability.
Don't get confused by the "XML" in "XML Web Service". It's not a tool for sending around vanilla XML. Rather, XML refers to the format of the message, as it is transmitted over the wire, as opposed to a POST string (id=3&name=Test&date=2010-01-24) or a binary RPC call as used in .NET Remoting.
In terms of authentication, if you do decide to use WCF, you just have to use the right binding. A WCF proxy is normally configured by default to use wsHttpBinding, which uses integrated Windows authentication to secure the messages. Again, assuming you use Visual Studio, this is all done pretty much automatically for you unless you decide to change the defaults.
Related
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.
Basically I am trying to make a generic client which will retrieve the Methods Names, Parameters that it takes and Parameter that it returns from the any kind of web service. I thought of parsing the WSDL xml for that, but in that the required information is scattered over different elements. then I saw the SOAP Envelopes which contains the exact information I need. so I thought of downloading the web service page and doing the series of string operations so that I get extract the data I need from particular tag. but I guess there might be any C# functions which can give me this data containing the Request and Response headers information.
Can anybody please guide me.
Thanks in advance.
The only valid approach is through WSDL because it is the only real description of the service. Those "help pages" are just a feature of ASMX. WCF for example doesn't have this help page showing examples of SOAP messages. Also examples of SOAP messages don't really cover the whole content of the message - it doesn't correctly show which elements are mandatory and which are not. It doesn't correctly show advanced features like XSD choices etc. If you want to write generic client you must parse WSDL. It is really BIG task. Also be aware that WSDL can reference other WSDLs and XSDs.
To make things much more easier you should check available classes in .NET framework to deal with service descriptions. For example System.ServiceModel.Description.MetadataExchangeClient and other classes from that namespace.
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.
I have a "simple" task. I have an existing project with a web service written in C# which has a method that will send a huge XML file to the client. (This is a backup file of data stored on the server that needs to be sent somewhere else.) This service also had some additional authentication/authorization set up.
And I have an existing Delphi 2007 application for WIN32 which calls the web service to extract the XML data for further processing. It's a legacy system that runs without a .NET installation.
Only problem: the XML file is huge (at least 5 MB) and needs to be sent as a whole. Due to system requirements I cannot just split this up into multiple parts. And I'm not allowed to make major changes to either the C# or the Delphi code. (I can only change the method call on both client and server.) And I'm not allowed to spend more than 8 (work) hours to come up with a better solution or else things will just stay unchanged.
The modification I want to add is to compress the XML data (which reduces it to about 100 KB) and then send it to the client as a binary stream. The Delphi code should then accept this incoming stream and de compress the XML data again. Now, with a minimum of changes to the existing code, how should this be done?
(And yes, I wrote the original client and server in the past and it was never meant to send that much data at once. Unfortunately, the developer who took it over from me had other ideas, made several dumb changes, did more damage and left the company before my steel-tipped boot could connect to his behind so now I need to fix a few things. Fixing this web service has a very low priority compared to the other damage that needs to be restored.)
The server code is based on legacy ASMX stuff, the client code is the result of the Delphi SOAP import with some additional modifications.
The XML is a daily update for the 3000+ users which happens to be huge in it's current design. We're working on this but that takes time. There are more important items that need to be fixed first, but as I said, there's a small amount of time available to fix this problem quickly.
This sounds like a good candidate for an HttpHandler
My good links are on my work computer (I'll add them when I get to work), but you can look to see if it will be a good fit.
-- edit --
Here are the links...
http://www.ddj.com/windows/184416694
http://visualstudiomagazine.com/articles/2006/08/01/create-dedicated-service-handlers.aspx?sc_lang=en&sc_mode=edit
What is the problem with a 5MB file in a soap message? I have written a document server that runs over soap and this server has no problem with large files.
If the size is a problem for you I would just compress and decompress the xml data. This can easily be done with one of the many (free) available components for compression of a TStream descendant.
If you get that kind of compression, merely convert each byte to its hex equivalent, which will only double the size, and send this. Then do the opposite on the other end. Or am I missing something?
I would agree with Brad Bruce, HttpHandler would be fast, and using GZIP or Deflate Compression with I might be wrong... browsers support natively. you can get easy great compression on text based data for cheap cpu time.
System.IO.Compression.GZipStream GZipStream = new System.IO.Compression.GZipStream("Your XML Doc Stream",System.IO.Compression.CompressionMode.Compress)