Asp.net web api 从SQL server分块下载web API文件

Asp.net web api 从SQL server分块下载web API文件,asp.net-web-api,chunks,Asp.net Web Api,Chunks,我希望从Sqlserver中分块下载文件,并使用pushstreamcontent或web API中的streamcontent将其响应到我的客户端。实现这一目标的正确方法是什么 我有两种想法 多个调用:从客户端调用WEb API,并在初始调用时获取文件元数据。传递Chunksize和Contentstart参数并下载块。 单次调用:在服务器端的Tempfolder中下载文件,并在单次调用中将流内容推送到客户端。 我相信这会让你度过难关: public HttpResponseMessage G

我希望从Sqlserver中分块下载文件,并使用pushstreamcontent或web API中的streamcontent将其响应到我的客户端。实现这一目标的正确方法是什么

我有两种想法

多个调用:从客户端调用WEb API,并在初始调用时获取文件元数据。传递Chunksize和Contentstart参数并下载块。 单次调用:在服务器端的Tempfolder中下载文件,并在单次调用中将流内容推送到客户端。
我相信这会让你度过难关:

public HttpResponseMessage Get([FromUri]string filename)
        {
            string path = HttpContext.Current.Server.MapPath("~/" + filename);
            if (!File.Exists(path))
            {
                throw new HttpResponseException("The file does not exist.", HttpStatusCode.NotFound);
            }

            try
            {
                MemoryStream responseStream = new MemoryStream();
                Stream fileStream = File.Open(path, FileMode.Open);
                bool fullContent = true;
                if (this.Request.Headers.Range != null)
                {
                    fullContent = false;

                    // Currently we only support a single range.
                    RangeItemHeaderValue range = this.Request.Headers.Range.Ranges.First();


                    // From specified, so seek to the requested position.
                    if (range.From != null)
                    {
                        fileStream.Seek(range.From.Value, SeekOrigin.Begin);

                        // In this case, actually the complete file will be returned.
                        if (range.From == 0 && (range.To == null || range.To >= fileStream.Length))
                        {
                            fileStream.CopyTo(responseStream);
                            fullContent = true;
                        }
                    }
                    if (range.To != null)
                    {
                        // 10-20, return the range.
                        if (range.From != null)
                        {
                            long? rangeLength = range.To - range.From;
                            int length = (int)Math.Min(rangeLength.Value, fileStream.Length - range.From.Value);
                            byte[] buffer = new byte[length];
                            fileStream.Read(buffer, 0, length);
                            responseStream.Write(buffer, 0, length);
                        }
                        // -20, return the bytes from beginning to the specified value.
                        else
                        {
                            int length = (int)Math.Min(range.To.Value, fileStream.Length);
                            byte[] buffer = new byte[length];
                            fileStream.Read(buffer, 0, length);
                            responseStream.Write(buffer, 0, length);
                        }
                    }
                    // No Range.To
                    else
                    {
                        // 10-, return from the specified value to the end of file.
                        if (range.From != null)
                        {
                            if (range.From < fileStream.Length)
                            {
                                int length = (int)(fileStream.Length - range.From.Value);
                                byte[] buffer = new byte[length];
                                fileStream.Read(buffer, 0, length);
                                responseStream.Write(buffer, 0, length);
                            }
                        }
                    }
                }
                // No Range header. Return the complete file.
                else
                {
                    fileStream.CopyTo(responseStream);
                }
                fileStream.Close();
                responseStream.Position = 0;

                HttpResponseMessage response = new HttpResponseMessage();
                response.StatusCode = fullContent ? HttpStatusCode.OK : HttpStatusCode.PartialContent;
                response.Content = new StreamContent(responseStream);
                return response;
            }
            catch (IOException)
            {
                throw new HttpResponseException("A generic error occured. Please try again later.", HttpStatusCode.InternalServerError);
            }
        }
注意:使用Web API时,不需要手动以文本形式解析范围标头。Web API会自动为您解析它,并为每个范围提供From和To属性。From和To的类型可以为null,因为这些属性可以为null,比如bytes=-100和bytes=300-。这些特殊情况必须小心处理

另一个要考虑的特殊情况是哪里大于资源大小。在本例中,它相当于为null,在这里您需要返回从开始到资源结尾的值。 如果返回完整的资源,通常状态代码设置为200 OK。如果只返回部分资源,则状态代码通常设置为206 PartialContent

此解决方案是本文的一部分,它涵盖了许多其他内容,我鼓励您查看: