Web API HttpResponseMessage内容返回不完整

Bru*_*rez 5 c# httpresponse asp.net-web-api

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

我假设问题出在MemoryBuffer管理上,但我无法找到它的位置.

我的代码(已解决):

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

        var stream = new MemoryStream();
        var writer = new StreamWriter(stream);

        CsvFileDescription outputFileDescription = new CsvFileDescription
        {
            SeparatorChar = ',', // comma delimited
            FirstLineHasColumnNames = true, // no column names in first record
            FileCultureName = "nl-NL" // use formats used in The Netherlands
        };
        CsvContext cc = new CsvContext();
        cc.Write(masterTripModelList,writer,outputFileDescription);
        writer.Flush();
        stream.Position = 0;
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new StreamContent(stream);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        response.Content.Headers.ContentDisposition.FileName = "ObserverTripList.csv";
        stream.Flush();
        return response;
Run Code Online (Sandbox Code Playgroud)

谢谢

Dar*_*ler 6

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

此外,如果您经常需要CSV内容,我还建议您自己创建一个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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后你的控制器动作减少到......

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;
Run Code Online (Sandbox Code Playgroud)

通过在CsvContent类中包含CsvFileDescription的创建,可以进一步简化这一过程.