Tags: , , , | Posted by AlexanderZeitler on 7/27/2011 8:48 PM | Comments (2)

Disclaimer: I know that there are things like FTP Winking smile

In one of my projects I need to transfer files from my WPF-Application to a server which is only available through HTTP.

Lets solve this using WCF Web API and it’s HttpClient:

Files are received by a resource method called “Upload”

[WebInvoke(Method = "POST", UriTemplate = "{filename}")]
public HttpResponseMessage Upload(string filename, HttpRequestMessage request) {
	
	// grab the posted stream
	Stream stream = request.Content.ContentReadStream;

	// write it to 
	using (FileStream fileStream = File.Create(string.Format(@"c:\projects\step\{0}", filename), (int)stream.Length)) {
		byte[] bytesInStream = new byte[stream.Length];
		stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
		fileStream.Write(bytesInStream, 0, bytesInStream.Length);
	}

	// http house keeping
	return new HttpResponseMessage(HttpStatusCode.Created, "");
}

The client POSTs the file:

HttpClient client = new HttpClient("http://localhost:52046/");

// enable support for files up to 10 MB size
HttpClientChannel channel = 
	new HttpClientChannel() { MaxRequestContentBufferSize = 1024 * 1024 * 10 };
client.Channel = channel;

FileStream file = new FileStream(_path, FileMode.Open);
StreamContent fileContent = new StreamContent(file);

string fileName = Path.GetFileName(_path);
client.Post(string.Format("file/{0}",fileName), fileContent);

This has been straight forward. Now we need to enable Streaming and receiving files greater than 64KB on the Server.

This is done by configuring the endpoint.

To be able to access the HttpEndpoint for our URI in the global.asax (when IIS hosting it), we need to implement a custom HttpConfigurableServiceHostFactory:

public class CustomServiceHostFactory : HttpConfigurableServiceHostFactory {
	public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) {
		var host = base.CreateServiceHost(constructorString, baseAddresses);

		foreach (HttpEndpoint endpoint in host.Description.Endpoints) {
			endpoint.TransferMode = TransferMode.Streamed;
			endpoint.MaxReceivedMessageSize = 1024 * 1024 * 10;
		}

		return host;
	}
}

To get it up and running, we need to assign it to our route definition for the resource handling our uploads:

RouteTable.Routes.MapServiceRoute<StepFileResource,CustomServiceHostFactory>("file",null,null);

Thanks to Pedro for helping me out of the configuration hell ;-)

…and by the way: Happy uploading with WCF Web API!

DotNetKicks-DE Image

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Comments are closed