C# Web API HttpResponseMessage内容返回不完整

C# Web API HttpResponseMessage内容返回不完整,c#,asp.net-web-api,httpresponse,C#,Asp.net Web Api,Httpresponse,我想返回使用Web API 5.0从我的数据库生成的csv 它工作正常,只是返回的csv被截断 我想问题出在MemoryBuffer管理上,但我找不到它在哪里 我的代码(已解决): IEnumerable masterTripList=\u obsvMasterRepo.GetObsTrips(容器名称、日期年、端口、obsvCode、obsvTripCode、obsvProgCode、lastModifiedDateYear、lastModifiedBy、状态码); IList masterT

我想返回使用Web API 5.0从我的数据库生成的csv 它工作正常,只是返回的csv被截断

我想问题出在MemoryBuffer管理上,但我找不到它在哪里

我的代码(已解决):

IEnumerable masterTripList=\u obsvMasterRepo.GetObsTrips(容器名称、日期年、端口、obsvCode、obsvTripCode、obsvProgCode、lastModifiedDateYear、lastModifiedBy、状态码);
IList masterTripModelList=新列表();
foreach(masterTripList中的MasterObsTrip trip)
masterTripModelList.Add(新的MasterObsTripModel(trip));
var stream=newmemoryStream();
var writer=新的StreamWriter(流);
CsvFileDescription outputFileDescription=新CsvFileDescription
{
分隔符字符=',',//逗号分隔
FirstLineHasColumnNames=true,//第一条记录中没有列名
FileCultureName=“nl nl”//使用荷兰使用的格式
};
CsvContext cc=新的CsvContext();
cc.Write(masterTripModelList、writer、outputFileDescription);
writer.Flush();
流位置=0;
HttpResponseMessage response=新的HttpResponseMessage(HttpStatusCode.OK);
response.Content=新的流内容(stream);
response.Content.Headers.ContentType=新的MediaTypeHeaderValue(“应用程序/八位字节流”);
response.Content.Headers.ContentDisposition=新的ContentDispositionHeaderValue(“附件”);
response.Content.Headers.ContentDisposition.FileName=“ObserverTripList.csv”;
stream.Flush();
返回响应;

谢谢

在重置流之前,我会尝试执行writer.Flush()。Position=0

此外,如果您经常需要CSV内容,我还建议您自己创建一个CSV内容类

public class CsvContent<T> : HttpContent
    {
        private readonly MemoryStream _stream = new MemoryStream();
        public CsvContent(CsvFileDescription outputFileDescription, string filename, IEnumerable<T> data)
        {
            var cc = new CsvContext();
            var writer = new StreamWriter(_stream);
            cc.Write(data, writer, outputFileDescription);
            writer.Flush();
            _stream.Position = 0;

            Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            Headers.ContentDisposition.FileName = filename;

        }
        protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            return _stream.CopyToAsync(stream);
        }

        protected override bool TryComputeLength(out long length)
        {
            length = _stream.Length;
            return true;
        }
    }
公共类CsvContent:HttpContent
{
私有只读内存流_stream=新内存流();
公共CSV内容(CsvFileDescription outputFileDescription、字符串文件名、IEnumerable数据)
{
var cc=new CsvContext();
var writer=新的StreamWriter(_stream);
cc.Write(数据、写入器、输出文件描述);
writer.Flush();
_流位置=0;
Headers.ContentType=新的MediaTypeHeaderValue(“应用程序/八位字节流”);
Headers.ContentDisposition=新的ContentDispositionHeaderValue(“附件”);
Headers.ContentDisposition.FileName=文件名;
}
受保护的重写任务SerializeToStreamAsync(流、TransportContext上下文)
{
返回_stream.CopyToAsync(流);
}
受保护的覆盖布尔TryComputeLength(out long length)
{
长度=_stream.length;
返回true;
}
}
然后你的控制器动作减少到

IEnumerable<MasterObsTrip> masterTripList = _obsvMasterRepo.GetObsTrips(vesselName, dateYear, port, obsvCode, obsvTripCode, obsvProgCode, lastModifiedDateYear, lastModifiedBy, statusCode);
        IList<MasterObsTripModel> masterTripModelList = new List<MasterObsTripModel>();
        foreach (MasterObsTrip trip in masterTripList)
            masterTripModelList.Add(new MasterObsTripModel(trip));

        CsvFileDescription outputFileDescription = new CsvFileDescription
        {
            SeparatorChar = ',', // comma delimited
            FirstLineHasColumnNames = true, // no column names in first record
            FileCultureName = "nl-NL" // use formats used in The Netherlands
        };
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK) {
           Content = new CsvContent<MasterObsTripModel> (outputFileDescription, 
                                                      "ObserverTripList.csv", 
                                                       masterTripModelList);
        }
        return response;
IEnumerable masterTripList=\u obsvMasterRepo.GetObsTrips(容器名称、日期年、端口、obsvCode、obsvTripCode、obsvProgCode、lastModifiedDateYear、lastModifiedBy、状态码);
IList masterTripModelList=新列表();
foreach(masterTripList中的MasterObsTrip trip)
masterTripModelList.Add(新的MasterObsTripModel(trip));
CsvFileDescription outputFileDescription=新CsvFileDescription
{
分隔符字符=',',//逗号分隔
FirstLineHasColumnNames=true,//第一条记录中没有列名
FileCultureName=“nl nl”//使用荷兰使用的格式
};
HttpResponseMessage response=新的HttpResponseMessage(HttpStatusCode.OK){
内容=新的CSV内容(outputFileDescription,
“ObserverTripList.csv”,
masterTripModelList);
}
返回响应;

这可以通过在CsvContent类中创建CsvFileDescription来进一步简化。

避免调用
stream.Flush()
,因为流的实际写入会在以后发生……尝试看看这是否解决了您的问题。..Thx Kiran,但删除流。Flush不会改变任何事情,好的……我觉得其他的都没问题……只是想确定一下,你有没有试着查看内存流中的实际内容,看看它是否包含全部内容?您可以尝试将此内存流写入磁盘文件,看看它是否确实包含全部内容…是的,我在服务器上生成了该文件,其中包含了我的全部数据ethmm,我不确定发生了什么…您是否可以共享复制?(您使用的是哪个版本的Web API?)有类似这样的讨论-建议使用MediaTypeFormatter序列化(并在需要时反序列化)来自ApiController的返回。好奇的是,如果控制器返回类型是Csv流,您会如何将其与您的方法进行比较?@mishrsud i返回HttpResponseMessage,内容属性设置为CSVContent实例。这允许我访问响应头消息。
public class CsvContent<T> : HttpContent
    {
        private readonly MemoryStream _stream = new MemoryStream();
        public CsvContent(CsvFileDescription outputFileDescription, string filename, IEnumerable<T> data)
        {
            var cc = new CsvContext();
            var writer = new StreamWriter(_stream);
            cc.Write(data, writer, outputFileDescription);
            writer.Flush();
            _stream.Position = 0;

            Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            Headers.ContentDisposition.FileName = filename;

        }
        protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            return _stream.CopyToAsync(stream);
        }

        protected override bool TryComputeLength(out long length)
        {
            length = _stream.Length;
            return true;
        }
    }