【问题标题】:C# Uploading a memorystream object to Web APIC# 将内存流对象上传到 Web API
【发布时间】:2023-03-22 15:19:01
【问题描述】:

我在内存中有一个 CSV 文件,我想上传到 Web API。

如果我将 CSV 文件保存到磁盘并上传,它就会被接受。

但是,我想避免额外的工作,并通过简单地将我拥有的文本作为 MemoryStream 对象上传来使代码更简洁(我认为这是正确的格式?)。

以下代码用于上传文件:

string webServiceUrl = "XXX";
string filePath = @"C:\test.csv";
string cred = "YYY";

using (var client = new WebClient()){
    client.Headers.Add("Authorization", "Basic " + cred);
    byte[] rawResponse = client.UploadFile(webServiceUrl, "POST", filePath);   
    Console.WriteLine(System.Text.Encoding.ASCII.GetString(rawResponse));
}  

如果我有一个包含所有内容的字符串,并且我想以相同的方式上传它而不必将其保存到文件中,我该怎么办?

WebClient.UploadData 或 WebClient.UploadString 可能吗?

谢谢

编辑:

我尝试了你所说的,但使用了本地文件(以防字符串有问题),但我得到了同样的错误。

我认为代码将使用您的解决方案

string webServiceUrl = "XXX";
string file = @"C:\test.csv";     
string cred = "YYY";

FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
byte[] postArray = r.ReadBytes((int)fs.Length); 

using (var client = new WebClient())
{
    client.Headers.Add("Authorization", "Basic " + cred);
    using (var postStream = client.OpenWrite(webServiceUrl, "POST"))
    {     
          postStream.Write(postArray, 0, postArray.Length); 
    }              
}

有什么想法吗?

【问题讨论】:

  • 使用 WebClient UploadData 覆盖之一。传入 MemoryStream 的 ToArray 作为 byte[] 参数。

标签: c# csv upload webclient


【解决方案1】:

使用来自 WebClient 的 OpenWrite()

using (var postStream = client.OpenWrite(endpointUrl))
{
    postStream.Write(memStreamContent, 0, memStream.Length);
}

如文档所述:

OpenWrite 方法返回用于向资源发送数据的可写流。


更新

上传前尝试将MemoryStream的位置设置为0。

memoryStream.Position = 0;

当您将文件复制到 MemoryStream 中时,指针会移动到流的末尾,因此当您尝试读取它时,您会得到一个空字节,而不是您的流数据。

MSDN - CopyTo()

复制从当前流中的当前位置开始,复制操作完成后不会重置目标流的位置。

【讨论】:

  • 你遇到了哪个错误?
  • 远程服务器返回错误:(500)内部服务器错误。没有比这更具体的了。
  • @Roffemon 你能调试服务器吗?此错误消息意味着服务器无法将 Stream 作为输入处理。
  • 不能,这是我无权访问的服务器。第二个代码块与第一个非常相似,所以我在处理流时一定做错了什么?我试试看能不能解决,谢谢!
  • @Roffemon 在发布到服务器之前检查你的 MemStream 在调试器中的位置。
【解决方案2】:

我终于设法解决了。

首先,我使用 CURL 发出了一个有效的请求。 我分析了数据包数据并制作了数据包的例外副本。

我做了很多改变,然而,最后的改变是使用我在网上找到的不同功能,它从来没有像 CURL 那样用“Last-Boundary”关闭数据包。

所以通过修改函数,确保它正确地编写了一个 Last-Boundary,它终于可以工作了。

另外,另一个关键的事情是将 PreAuthenticate 设置为 true,网上的例子并没有这样做。

所以,总而言之: 1. 确保数据包结构正确。 2. 如果您需要进行身份验证,请确保您预先进行身份验证。

webrequest.PreAuthenticate = true;
webrequest.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}", cred); 
  1. 如果使用 https,请不要忘记添加 SSL(如果您进行身份验证,您可能会这样做):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |安全协议类型.Ssl3;

希望这对某人有所帮助。

感谢之前的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    相关资源
    最近更新 更多