I'm using ServiceStack.ServiceClient.Web.XmlServiceClient to connect to a webservice. Is there a way to add an attachment to the request?
More info:
What I am trying to do is avoid using Microsoft.Web.Services2 because I am using Mono. I'm trying to upload an XML datafile, along with an XML request. Just like in this question:
Upload report unit via webservice in C# .net to jasperserver
To upload files the best (and fastest) way is to not encode it as a normal request variable but simply upload it to the web service as a normal HTTP Upload with ContentType multipart/form-data, i.e. how HTML forms currently send files to a url.
ServiceStack has built-in support for processing uploaded files this way where a complete example of how to do this in ServiceStack's RestFiles example project.
To upload files using the ServiceClient you can use the .PostFile<T>() method seen in this example:
var fileToUpload = new FileInfo(FilesRootDir + "TESTUPLOAD.txt");
var response = restClient.PostFile<FilesResponse>(WebServiceHostUrl + "files/README.txt",
fileToUpload, MimeTypes.GetMimeType(fileToUpload.Name));
All uploaded files are made available via the base.RequestContext.Files
collection which you can easily process with the SaveTo() method (either as a Stream or a file).
foreach (var uploadedFile in base.RequestContext.Files)
{
var newFilePath = Path.Combine(targetDir.FullName, uploadedFile.FileName);
uploadedFile.SaveTo(newFilePath);
}
Similarly related to return a file response (either as an Attachment or directly) you just need to return the FileInfo in a HttpResult like:
return new HttpResult(FileInfo, asAttachment:true);
Multiple File Uploads
You can also use the PostFilesWithRequest
APIs available in all .NET Service Clients to upload multiple streams within a single HTTP request. It supports populating Request DTO with any combination of QueryString
and POST'ed FormData in addition to multiple file upload data streams, e.g:
using (var stream1 = uploadFile1.OpenRead())
using (var stream2 = uploadFile2.OpenRead())
{
var client = new JsonServiceClient(baseUrl);
var response = client.PostFilesWithRequest<MultipleFileUploadResponse>(
"/multi-fileuploads?CustomerId=123",
new MultipleFileUpload { CustomerName = "Foo,Bar" },
new[] {
new UploadFile("upload1.png", stream1),
new UploadFile("upload2.png", stream2),
});
}
Example using only a Typed Request DTO. The JsonHttpClient
also includes async equivalents for each of the PostFilesWithRequest
APIs:
using (var stream1 = uploadFile1.OpenRead())
using (var stream2 = uploadFile2.OpenRead())
{
var client = new JsonHttpClient(baseUrl);
var response = await client.PostFilesWithRequestAsync<MultipleFileUploadResponse>(
new MultipleFileUpload { CustomerId = 123, CustomerName = "Foo,Bar" },
new[] {
new UploadFile("upload1.png", stream1),
new UploadFile("upload2.png", stream2),
});
}