如何使用ServiceStack客户端使用文件

thu*_*utt 14 c# servicestack

我正在尝试使用ServiceStack以RESTful方式将文件返回到ServiceStack客户端.

我已经阅读了有关SO(此处此处)的其他问题,建议使用HttpResult和FileInfo对象或MemoryStream来允许将ContentType标头更改为相关的文件类型.

当我通过浏览器调用服务时,这对我有用,正确的文件会自动开始下载.我如何使用其中一个ServiceStack客户端使用该文件?

我正在使用Request DTO并尝试使用类似的东西返回

return new HttpResult(new FileInfo("file.xml"), asAttachment:true) {
   ContentType = "text/xml"
};
Run Code Online (Sandbox Code Playgroud)

例如,如何使用JsonServiceClient消耗它?

Chr*_*Ray 15

我有类似的要求,也要求我跟踪流文件下载的进度.我大致这样做了:

服务器端:

服务:

public object Get(FooRequest request)
{
    var stream = ...//some Stream
    return new StreamedResult(stream);
}
Run Code Online (Sandbox Code Playgroud)

StreamedResult类:

public class StreamedResult : IHasOptions, IStreamWriter
{
    public IDictionary<string, string> Options { get; private set; }
    Stream _responseStream;

    public StreamedResult(Stream responseStream)
    {
        _responseStream = responseStream;

        long length = -1;
        try { length = _responseStream.Length; }
        catch (NotSupportedException) { }

        Options = new Dictionary<string, string>
        {
            {"Content-Type", "application/octet-stream"},
            { "X-Api-Length", length.ToString() }
        };
    }

    public void WriteTo(Stream responseStream)
    {
        if (_responseStream == null)
            return;

        using (_responseStream)
        {
            _responseStream.WriteTo(responseStream);
            responseStream.Flush();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

客户端:

string path = Path.GetTempFileName();//in reality, wrap this in try... so as not to leave hanging tmp files
var response = client.Get<HttpWebResponse>("/foo/bar");

long length;
if (!long.TryParse(response.GetResponseHeader("X-Api-Length"), out length))
    length = -1;

using (var fs = System.IO.File.OpenWrite(path))
    fs.CopyFrom(response.GetResponseStream(), new CopyFromArguments(new ProgressChange((x, y) => { Console.WriteLine(">> {0} {1}".Fmt(x, y)); }), TimeSpan.FromMilliseconds(100), length));
Run Code Online (Sandbox Code Playgroud)

该"的copyfrom"扩展方法是直接从该项目这里的源代码文件"StreamHelper.cs"借来的:一个流副本进度报告(荣誉给恩宁Dieterichs)

并感谢mythz和ServiceStack的任何贡献者.伟大的项目!

  • 很好的答案,我喜欢它:).另外还有@ bamboo的[Reactive Observable Streaming Client](https://gist.github.com/bamboo/5078236). (2认同)

myt*_*thz 13

您不会使用ServiceStack的.NET ServiceClients来使用文件,因为它们主要用于发送DTO.

您可以使用任何普通的WebRequest来下载文件,在ServiceStack的v3.9.33中引入了一些方便的WebRequest扩展HTTP Utils,使这很容易,例如:

对于文本文件:

var xmlFile = downloadUrl.GetXmlFromUrl(responseFilter: httpRes => {
        var fileInfoHeaders = httpRes.Headers[HttpHeaders.ContentDisposition];
    });
Run Code Online (Sandbox Code Playgroud)

其中fileInfoHeaders包含W3C ContentDisposition HTTP标头,例如,当返回a时FileInfo,ServiceStack返回:

attachment;filename="file.xml";size={bytesLen};
creation-date={date};modification-date={date};read-date={date};
Run Code Online (Sandbox Code Playgroud)

要下载二进制文件,您可以使用:

var rawBytes = downloadUrl.GetBytesFromUrl(httpRes => ...);
Run Code Online (Sandbox Code Playgroud)