【发布时间】:2018-01-01 17:18:32
【问题描述】:
我正在尝试动态创建一个 csv 文件并将流输出到浏览器。
这是我的 api 端点:
[System.Web.Http.HttpGet]
[System.Web.Http.Route("export-to-csv")]
public FileStreamResult ExportDeposits([FromUri(Name = "")]DepositSearchParamsVM depositSearchParamsVM)
{
if (depositSearchParamsVM == null)
{
depositSearchParamsVM = new DepositSearchParamsVM();
}
var records = _DepositsService.SearchDeposits(depositSearchParamsVM);
var result = _DepositsService.WriteCsvToMemory(records);
var memoryStream = new MemoryStream(result);
return new FileStreamResult(memoryStream, "text/csv") { FileDownloadName = "export.csv" };
}
这是我的服务方法:
public byte[] WriteCsvToMemory(IEnumerable<DepositSummaryVM> records)
{
using (var stream = new MemoryStream())
using (var reader = new StreamReader(stream))
using (var writer = new StreamWriter(stream))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords(records);
writer.Flush();
stream.Position = 0;
var text = reader.ReadToEnd();
return stream.ToArray();
}
}
这是错误信息:
{ "message": "发生错误。", "exceptionMessage": "错误 从 'System.IO.MemoryStream' 上的 'ReadTimeout' 获取值。",
"exceptionType": "Newtonsoft.Json.JsonSerializationException",
“堆栈跟踪”:“在 Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object 目标)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer,对象值,JsonContainerContract 合约,JsonProperty 成员、JsonProperty 属性、JsonContract& memberContract、Object& 成员值)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer,对象值,JsonObjectContract 合约,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer,对象值,JsonContract valueContract,JsonProperty 成员, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer,对象值,JsonObjectContract 合约,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer,对象值,JsonContract valueContract,JsonProperty 成员, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter,对象值,类型 objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter,对象值,类型 objectType)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、编码 有效编码)\r\n 在 System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、编码 有效编码)\r\n 在 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、HttpContent 内容)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型 类型、对象值、流 writeStream、HttpContent 内容、 TransportContext transportContext, CancellationToken cancelToken)\r\n--- 来自先前位置的堆栈跟踪结束 抛出异常的地方 ---\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)\r\n 在 System.Web.Http.Owin.HttpMessageHandlerAdapter.d__13.MoveNext()", “内部异常”:{ "message": "发生错误。", "exceptionMessage": "此流不支持超时。", "exceptionType": "System.InvalidOperationException", "stackTrace": " 在 System.IO.Stream.get_ReadTimeout()\r\n 在 GetReadTimeout(Object )\r\n 在 Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object 目标)" } }
【问题讨论】:
-
Http 使用 TCP 作为传输层。错误来自 TCP 层。TCP 是可靠的,因为每个数据报(最大 1500 字节)都会收到一个 ACK。如果没有收到 ACK,通常数据报是最多发送三遍。所以由于某种原因,ACK没有发生。所以第一个问题是什么时候发生错误?是第一次建立连接还是在接收到一些数据之后(以及接收到多少数据)?调试这些问题的最佳方法是使用像 wireshark 或 fiddler 这样的嗅探器。从查看 http 消息开始。每个 TCP 消息将由一个或多个 TCP 数据包组成。
-
这种类型错误的一个常见原因是http模式。 http 1.0 是流模式,而 http 1.1 是块模式。 Http 1.1 要求客户端发送下一个块消息,当它没有发送时会发生超时。因此,您可以使用嗅探器查看标头以了解正在使用的 http 模式。在每条 http 消息的末尾都有一个状态,完成时通常为 200。 100 继续。 400 - 500 是错误。因此,要正常修复,您需要在第一次请求时发送一个标头以指示您要使用 http 1.0 而不是 1.1。
-
我通过引用这个解决了这个问题:stackoverflow.com/questions/26038856/…
标签: c# csv memorystream csvhelper