ServiceStack client add attachment

2019-02-07 15:08发布

问题:

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

回答1:

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),
        });
}