WCF Upload file - c#

I've never used WCF before but I want to create a simple service. I want the computer to upload a file from the local machine. I've got this in my interface:
[OperationContract]
[WebInvoke(Method = "GET",UriTemplate = "/File")]
Stream GetFile();
In the method, I just do this:
return new FileStream(#"c:\myfile.zip", FileMode.Open);
When I run this from the client, the Result property contains the stream itself. This is fine, and it works, but I'd rather the client access the file from the server itself instead of copying the entire thing across. What would be the URL for the uploaded file so that the client can access it directly from the server? I assumed it's http://computername:port/something... (I believe this is a REST service?)

Let's try to think over what you are saying.
A user can access a file directly. In that case it is fair to think, that any user could access any file on any computer. It's obvious, that it's not so.
WCF provides some special interface to access the files on computer, where it is running. This is also a big security hole.
any other ideas?
In any case, if you want to share the file on web, you should make a public interface for it.
This could be an IIS server, which will return it from the server machine, or this could be just your WCF server.
Anyway, what you did is right. Stream returns a file over network and it has no overhead of copying (duplicating) some information, like you may think.
UPDATE:
To enable streaming you can look into this article
UPDATE 2:
If you really need to stream a video file, Smooth Streaming could be an option

I think you are getting things bit mixed up here. You expose a WCF service with an operation returning a Stream. That this is a filestream is an implementation detail. You could just as well return a memory stream or a network stream or anything which derives from Stream really. If you want to have the client direct access to the file you need to share it so it can access it. On Windows you could create a shared folder (but you really don't want to expose that on the internet) or you setup a ftp or http server.
I have not tinkered around with WCF and streaming but I would expect that when you supply a stream from the server that it works more or less out of the box (meaning it streams the file rather than downloading it in one big chunk). Have a look at this MSDN article which details some restrictions around streaming with WCF.

Related

Concurrency management in WCF

i have implemented a fairly simple wcf service which handles the file transfers from my clients to the server the problem is when a client sends a file request.
all of the bandwidth is allocated to that single client and others have to wait until the requested file transfer is completed.
So my question is how to make the service more efficient and let the users share the bandwidth
[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode =InstanceContextMode.PerCall,
ConcurrencyMode=ConcurrencyMode.Multiple)]
I set the InstanceContextMode attribute to PerCall but that didn't do the trick
UPDATE : This Project is similar to mine
http://www.codeproject.com/Articles/33825/WCF-TCP-based-File-Server
WCF does not have proper load balancing, you will have to develop one yourself.
If you are transferring files, lets assume download, you should send packets of data rather than the complete file at once. When doing this, add 'delays/sleeps' to the process to limit the amount of bytes the server sends on each time window, this will make room for other requests.
It's questionable that it's desirable to serve up files through a WCF endpoint. The reasons against doing this are pretty much exactly the problems you have been having. It works for a few clients at a time - but scaling out requires hosting new instances of the service behind a load balancer.
It would be worth considering hosting your files with some kind of storage service and have your WCF service simply return a link or handle to the file. Then the file can be retrieved offline. Microsoft have created Azure Blob Storage for this exact purpose.
Appreciate this does not address your original question, and understand the scope of your requirement may not accommodate a large reworking.
Another option is to use chunking channel if you are transferring large files. Examples: MSDN, codeplex.
Although I agree with #hugh position.

Download very large files (8GB+) - combining WCF and WebClient?

I have quite some trouble creating a WCF service that supports downloads of very large files. I have read a lot of guides on how to set transferMode attribute to Streamed, increase all messageSize and bufferSize attributes to Int32.MaxValue, and still I have no luck. (I am also returning the stream as the message body via the MessageBodyMember attribute, and metadata is sent via the headers using the MessageHeader attributes).
If I set all these attributes, I can download smaller files fine, but when I try to download 1-2GB files I simply get a 400 bad request error which makes it rather hard to debug...
My service should ideally support file sizes of at least 8GB. Is this even doable with WCF? The various messageSize attributes of the web.config file seem to be limited to Int32.MaxValue which equals a maximum file size of 2GB.
From my studies I have found that it seems I will have to use WebClient.DownloadFile instead.
Files should only be available for download to users who have the required rights. With WCF my download method could take a token-parameter that the server could check and return the stream only if the user had rights to download the requested file. This does not seem straight forward using the WebClient approach. If anyone has some guidelines on how to do this (via the WebClient), I would very much appreciate it.
Ideally my WCF service should administer and provide user tokens and somehow bind to every individual file what tokens are currently legal (tokens should be usable only once). Download should then happen via the WebClient.
Thanks in advance for any clues.
You can do this in WCF. Many moons ago I built a service that did this (we didn't have a web server as part of our configuration). We used WCF streaming:
http://msdn.microsoft.com/en-us/library/ms733742.aspx
The strategy to deal with large payloads is streaming. While messages,
especially those expressed in XML, are commonly thought of as being
relatively compact data packages, a message might be multiple
gigabytes in size and resemble a continuous data stream more than a
data package. When data is transferred in streaming mode instead of
buffered mode, the sender makes the contents of the message body
available to the recipient in the form of a stream and the message
infrastructure continuously forwards the data from sender to receiver
as it becomes available.

Question about C#, servers, XML

So I'm working on a project for my internship and have hit a bit of a brick wall. Unfortunately, the only people I know who are qualified to help me at the office are on vacation at the moment, and Google has been unfortunately unhelpful (or my search skills inadequate), so I thought I'd ask here.
The project is basically to make a server to mimic one that the company (which makes phone apps) already has. What I need to do is have one of their apps send a request to my server (I will have to modify the app to do this, but don't know how), and have my server reply with an XML response that the app already knows how to process. (The main purpose is so that we can see how the app responds when the real server sends it an error by simulating it on my server.)
Now, I already have a few sample HTTP requests and their associated XML responses handy, taken from simulations with the app and the real server. The app is written in C#, and currently sends HTTP web requests to the real server's online location, which responds to these HTTP web requests with XML. My server, however, will not have an online location, so the app will have to be modified to work with sockets on a local host.
My questions:
1) My boss said to create an XML file to associate certain requests with certain XML responses, but I have no idea what he means or how to do this. (He said it could also be done with a .ini file.) Does anyone know?
2) Once I have this XML file that can make these associations, how can I incorporate it into my server so that my server can check the request it received against its table of valid requests and figure out which response to send back?
3) How can one modify the app from using HTTP web requests and responses to using sockets?
If you have any questions/clarifications that you need in order to better answer this, please don't hesitate to ask me.
Thanks!
What you're describing is a web service. Unfortunately, his advice to change a setting in an .ini file make it sound like they have a proprietary system for doing this, rather than using a standard ASMX (which requires IIS) or WCF (which can either run in IIS or as a standalone service, which it sounds like is what you'd want) service.
Without more information about what they're using, I don't know that you'll be able to get much help here.
In response to question #3:
HTTP is a protocol that already runs on a specific socket (normally using port 80).
An internet socket is an endpoint that is used to transport data between processes. If you want to run your own protocol, you will need to create a new socket (with TCP or UDP) on a specific port.
This will however require you to create your own client and server in order to exchange data between them.
To get started, here is a very simple client-server example in C# using a custom socket.
Good luck!
Ask your boss if this client communicates with soap, if so then just go to MSDN and find tutorials on implementing an ASMX webservice, follow the tutorial through and you'll have a shell to start with.
First I'd like to say that it sounds like you have some unclear requirements that you should probably clarify with your boss. If you're not exactly sure what he means you should find out because nothing sucks more than having to support someone's creative interpretation of requirements.
1) It sounds like your boss just wants a way to easily change associations for testing without having to rebuild the app so he's asking you to store those associations in an xml/ini file that can easily be modified. In c# you can easily go between XML and DataSet objects so this should be trivial. I would create the data structure in a DataSet first and then use the GetXml method of the DataSet to output the xml format.
2) In .NET you can store objects in Cache and create a Cache Dependency that is a file association. Thus whenever the file is modified the Cache is purged. Whenever your program handles a request it pulls the object from Cache, if the object isn't in Cache then you have a condition block rebuild it from the xml/ini file on disk. I would have that condition block call out to a function that then loads the above mentioned xml format into a dataset that is then stored in the Cache with a Cache Dependency.
3) If you are trying to test an applications i/o, modifying it to use a different transport layer sounds like a bad idea. If the app currently works over HTTP to send requests then just route the HTTP request. I would suspect that the app probably has a configuration somewhere defining the path of the webservice it currently calls out to, once you know what that path is you can either change it, or if that's not possible setup a DNS rule on the server running the app to route it to the location of your application. On windows this is as simple as adding a line to the hosts file.

Available options for hosting FTP server in .NET application

I need to implement an FTP service inside my .NET application (running as a Windows Service) and have not had much luck finding good/current source code or vendors. Ideally it needs to be able to respond to the basic FTP Protocol and accept the data stream from an upload via a stream, enabling me to process the data as it is being received (think on the fly hashing).
I need to be able to integrate it into my service because it will stack on top of our current code base with an existing custom TCP/IP communication protocol. I don't want to write (and then spend time debugging and performance testing) my own protocol, or implementation.
I have already found plenty of ftp client implementations, I just need an acceptable server solution.
There is an article about rolling your own FTP server in C# here. It's a bit old, but it might be complete enough for your requirements.
If you can get away from the need to process inbound data on-the-fly, I'd suggest just using an off-the-shelf FTP server (maybe even IIS), and process the received files from a folder. Your service could easily monitor this folder for new files. The other benefit of this is that files could be received even if your service is not running or restarting, and testing would be easier as you can drop your own files into the monitored folder.
Good luck!
Hope you find RemObjects free IP nice to use,
http://www.remobjects.com/ip.aspx
After installation you will see the samples.

WCF communication with several clients without IIS

we're working on a peer to peer comm software that would allow a number of grocery stores to sync their inventory with what we call "headquarters".
To so this, we're thinking WCF+WPF, and no IIS and web services. My experience with WCF is basically zero, so my question is whether a TCP comm solution using WCF would work. The data that's being transferred is quite limited, about 2MB for a compressed plain text file (so we're sending binary data!), and this is done once per day only. So bandwidth/load shouldn't be an issue here.
The idea at this point is to have a WCF "server" running at HQ. Stores make themselves known to that server and then send files back and forth (simliliar to a chat application).
What I'm not sure of: does every store need to have a WCF "server" (or endpoint)? How would the server (=HQ) send a file to one of the clients (=stores)? Every store can send a file to any other store, and the HQ, and every store can also "request" a file from any other store/HQ.
Two limitations: None of the machines/computers involved can run Windows server for budget reasons, and as stated before IIS is a no-go.
If you are only sending files back and forth, I might question whether or not WCF even makes any sense. Have you considered just using a file transfer protocol, like scp or sftp?
Every machine will have to accept connections and have a file drop location setup, and then yuor application will have to monitor that location for new files. I love WCF in general, but a file transfer protocol is going to have a leg up if that is all you want to do.
If you direct all of your traffic via the server then there's no reason why you couldn't achieve this with WCF. The server would host WCF services in IIS with the stores having a client that was able to upload and request files. With this method, stores would not be able to directly transfer fiels to each other, but they would have to do it via the main server, which would suit your needs if you don't have the budget for the other scenario.
If all transfers are made once per day, the requests for files would be made with each client requesting what files they require, followed by each client uploading any files that are required by the server or any other client. The final step would be the server distributing the required files to each client. Obviously, this is a simplified view of it, the actual process may require some more thinking.
You don't need to host WCF in IIS, but is there any particular reason you don't want to do that?
You can host WCF in a ServiceHost, but then you need to build, maintain and deploy a lot of server/service features that IIS provides for free, such as application process recycling, activation-based hosting, etc.
In any case, it almost sounds like you need peer to peer networking. You can do that with WCF using the NetPeerTcpBinding.
If you have an opportunity to redesign your application, I suggest you do. You can throw strings around in WCF but if you can create a data contract you can keep all your communication strongly typed.
If you have access to windows server 2008 then the new IIS can host your WCF even if it isn't using tcp. Otherwise you just need to write an application that opens a service host, which you would usually wrap into a windows service. But as #MArk Seemann pointed out, you get lots of freebies by running your service in IIS.
Don't have any experience with the PeerTcpBinding but I can tell you that the NetTcpBinding is nice and fast plus it comes with all sorts of goodies like encryption and authentication if you want it.

Categories

Resources