C#将memorystream对象上载到Web API

C#将memorystream对象上载到Web API,c#,csv,upload,webclient,C#,Csv,Upload,Webclient,我有一个CSV文件在内存中,我想上传到一个网络API 如果我将CSV文件保存到磁盘并上传,它将被接受 然而,我想避免额外的工作,并通过简单地上传作为MemoryStream对象的文本(我认为这是正确的格式?)使代码更干净 以下代码用于上载文件: string webServiceUrl = "XXX"; string filePath = @"C:\test.csv"; string cred = "YYY"; using (var client = new WebClient()){

我有一个CSV文件在内存中,我想上传到一个网络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); 
    }              
}
有什么想法吗?

从网络客户端使用

using (var postStream = client.OpenWrite(endpointUrl))
{
    postStream.Write(memStreamContent, 0, memStream.Length);
}
如文件所述:

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


更新 在上传之前,尝试将MemoryStream的位置设置为0

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

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

从网络客户端使用

using (var postStream = client.OpenWrite(endpointUrl))
{
    postStream.Write(memStreamContent, 0, memStream.Length);
}
如文件所述:

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


更新 在上传之前,尝试将MemoryStream的位置设置为0

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

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


我终于设法解决了它

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

我做了很多更改,但是,最后的更改是,使用我在网上找到的不同函数,它从未使用“最后一个边界”关闭数据包,而CURL则使用了

因此,通过修改函数,确保它正确地编写了最后一个边界,它最终工作了

另外,另一个关键的事情是将PreAuthenticate设置为true,在线示例并没有这样做

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

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

    希望这对别人有帮助


    谢谢你早些时候的帮助

    我终于解决了这个问题

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

    我做了很多更改,但是,最后的更改是,使用我在网上找到的不同函数,它从未使用“最后一个边界”关闭数据包,而CURL则使用了

    因此,通过修改函数,确保它正确地编写了最后一个边界,它最终工作了

    另外,另一个关键的事情是将PreAuthenticate设置为true,在线示例并没有这样做

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

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

    希望这对别人有帮助


    谢谢你早些时候的帮助

    使用WebClient上载数据覆盖之一。将MemoryStream的ToArray作为byte[]参数传入。使用WebClient UploadData覆盖之一。将MemoryStream的ToArray作为byte[]参数传入。您得到了哪个错误?远程服务器返回了一个错误:(500)内部服务器错误。没有比这更具体的了。@Roffemon您能调试服务器吗?此错误消息表示服务器无法将流作为输入处理。无法,这是我无权访问的服务器。第二个代码块与第一个代码块非常相似,所以我在处理流时一定是做错了什么?我试试看能不能解决,谢谢@Roffemon在发布到服务器之前,检查您的MemStream在调试器中的位置。您收到了哪个错误?远程服务器返回了一个错误:(500)内部服务器错误。没有比这更具体的了。@Roffemon您能调试服务器吗?此错误消息表示服务器无法将流作为输入处理。无法,这是我无权访问的服务器。第二个代码块与第一个代码块非常相似,所以我在处理流时一定是做错了什么?我试试看能不能解决,谢谢@Roffemon在发布到服务器之前,检查MemStream在调试器中的位置。