Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#文件上传的分块传输,结合对ServiceStack中路由参数的访问_C#_.net_<img Src="//i.stack.imgur.com/WM7S8.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">servicestack_Chunked Encoding - Fatal编程技术网 servicestack,chunked-encoding,C#,.net,servicestack,Chunked Encoding" /> servicestack,chunked-encoding,C#,.net,servicestack,Chunked Encoding" />

c#文件上传的分块传输,结合对ServiceStack中路由参数的访问

c#文件上传的分块传输,结合对ServiceStack中路由参数的访问,c#,.net,servicestack,chunked-encoding,C#,.net,servicestack,Chunked Encoding,我希望使用IRequiresRequestStream接口使用ServiceStack(v3)和分块传输编码来实现大文件上传(视频文件)。标准的文件上传似乎无法处理我们的客户正在上传的一些较大的视频文件,因此我们希望为这些文件启用分块传输编码 我已经成功地测试了分块传输编码的文件上传,但是还有一些参数也需要随文件一起发送 由于IRequiresRequestStream绕过ServiceStack请求对象解析器,请求对象中与流相邻的任何其他参数显然都不会被填充。作为解决方案,我可以看到以下选项:

我希望使用
IRequiresRequestStream
接口使用ServiceStack(v3)和分块传输编码来实现大文件上传(视频文件)。标准的文件上传似乎无法处理我们的客户正在上传的一些较大的视频文件,因此我们希望为这些文件启用分块传输编码

我已经成功地测试了分块传输编码的文件上传,但是还有一些参数也需要随文件一起发送

由于
IRequiresRequestStream
绕过ServiceStack请求对象解析器,请求对象中与
相邻的任何其他参数显然都不会被填充。作为解决方案,我可以看到以下选项:

  • 查询字符串参数,可通过
    this.Request.QueryString
    集合访问
  • 自定义标题参数,可通过
    this.Request.Headers
    集合访问
  • 路径,可通过
    RequestBinder
    访问
  • 我已经成功地实现了选项1和2,但不知何故,这两个选项都感觉不够平静。我更喜欢使用
    Path->RequestDTO
    ,但我正在努力使用
    RequestBinder

    服务:

    public object Any(AttachmentStreamRequest request)
    {
        byte[] fileBytes = null;
    
        using (var stream = new MemoryStream())
        {
            request.RequestStream.WriteTo(stream);
            length = stream.Length;
            fileBytes = stream.ToArray();
        }
    
        string filePath = @"D:\temp\test.dat";
        File.WriteAllBytes(filePath, fileBytes);
    
        var hash = CalculateMd5(filePath);
        var requestHash = this.Request.QueryString["Hash"];
        var customerId = this.Request.QueryString["CustomerId"];
        var fileName = this.Request.QueryString["FileName"];
    
        // nicer would be
        // var requestHash = request.Hash;
        // var customerId = request.CustomerId;
    
        // save file....
    
        // return response
        return requestHash == hash
                   ? new HttpResult("File Valid", HttpStatusCode.OK)
                   : new HttpResult("Invalid Hash", HttpStatusCode.NotAcceptable);
    }
    
    请求:

    [Route("/upload/{CustomerId}/{Hash}", "POST", Summary = @"POST Upload attachments for a customer", Notes = "Upload customer attachments")]
    public class AttachmentStreamRequest : IRequiresRequestStream
    {
        // body
        public Stream RequestStream { get; set; }
    
        // path    
        public int CustomerId { get; set; }
    
        // query
        public string FileName { get; set; }
    
        // query
        public string Comment { get; set; }
    
        // query
        public Guid? ExternalId { get; set; }
    
        // path
        public string Hash { get; set; }
    }
    
    网络客户:

    private static async Task<string> SendUsingWebClient(byte[] file, string hash, customerId)
    {
        var client = (HttpWebRequest)WebRequest.Create(string.Format("http://localhost.fiddler:58224/upload/{0}/{1}", customerId, hash));
        client.Method = WebRequestMethods.Http.Post;
        client.Headers.Add("Cookie", "ss-pid=XXXXXXXXXXX; ss-id=YYYYYYYYYY");
    
        // the following 4 rows enable streaming 
        client.AllowWriteStreamBuffering = false;
        client.SendChunked = true;
        client.ContentType = "application/json";
        client.Timeout = int.MaxValue;
    
        using (var fileStream = new MemoryStream(file))
        {
            fileStream.Copy(client.GetRequestStream());
        }
    
        return new StreamReader(client.GetResponse().GetResponseStream()).ReadToEnd();
    }
    
    使用WebClient发送私有静态异步任务(字节[]文件、字符串哈希、customerId)
    {
    var client=(HttpWebRequest)WebRequest.Create(string.Format(“http://localhost.fiddler:58224/upload/{0}/{1}(customerId,hash));
    client.Method=WebRequestMethods.Http.Post;
    添加(“Cookie”,“ss pid=XXXXXXXXXX;ss id=YYYYYY”);
    //以下4行启用流式处理
    client.AllowWriteStreamBuffering=false;
    client.SendChunked=true;
    client.ContentType=“application/json”;
    client.Timeout=int.MaxValue;
    使用(var fileStream=newmemorystream(文件))
    {
    Copy(client.GetRequestStream());
    }
    返回新的StreamReader(client.GetResponse().GetResponseStream()).ReadToEnd();
    }
    
    我猜简单的方向是沿着下面的路线,但这似乎是一个混乱

    RequestBinders.Add(typeof(AttachmentStreamRequest), httpReq => { 
        var dto = new AttachmentStreamRequest(); 
        var segments = base.Request.PathInfo.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
    
        dto.CustomerId = segments[1].As<int32>();
        dto.Hash = segments[2].As<string>();
    
        // Stream copy to dto.RequestStream and other params etc....
    
        return dto;
    });
    
    RequestBinders.Add(typeof(AttachmentStreamRequest),httpReq=>{
    var dto=新的AttachmentStreamRequest();
    var segments=base.Request.PathInfo.Split(新[]{'/'},StringSplitOptions.RemoveEmptyEntries);
    dto.CustomerId=段[1].As();
    dto.Hash=segments[2].As();
    //流复制到dto.RequestStream和其他参数等。。。。
    返回dto;
    });
    

    在这个场景中,我用谷歌搜索了一下
    RequestBinders
    的例子。我确信必须有内置的ServiceStack方法来解析
    路径
    ,但我正在努力解决这个问题。有人想分享一个例子吗?

    最近我还研究了使用自定义标题的分块传输。不幸的是,我发现它在HttpWebRequest类和.NET Framework中都不受开箱即用的支持。唯一对我有效的解决方案是通过TCP实现分块传输HTTP通信。它不像行乞时听起来那么复杂。您只需要打开TCP客户端连接,根据需要格式化头,将流分块并发送

    以下是分块传输协议的定义: