c# - 从 c# [.NET] 发出 POST 请求时遇到问题
问题描述
我们API
为应用程序创建了一个通过POST
请求过程获取图像并以JSON
格式发送结果的应用程序。
我们尝试从 python、postman app、c# 等不同来源调用 API。python
我们可以使用和postman
应用程序成功调用端点,但c#
出现错误
c#代码[不工作]
byte[] img_data = System.IO.File.ReadAllBytes(@"file_path");
string url_ep = "http://ip:port/get";
Dictionary<string, byte[]> fl_image = new Dictionary<string, byte[]>();
fl_image.Add("image", img_data);
string data = JsonConvert.SerializeObject(fl_image);
var dataToSend = Encoding.UTF8.GetBytes(data);
var request = HttpWebRequest.Create(url_ep);
request.ContentType = "application/json";
request.ContentLength = dataToSend.Length;
request.Method = "POST";
request.GetRequestStream().Write(dataToSend, 0, dataToSend.Length);
var response = request.GetResponse();
System.IO.Stream dataStream = response.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
python代码[工作]
import requests
url = 'http://ip:port/get'
fl_image = {'image': open('file_path', 'rb')}
res = requests.post(url, files=fl_image)
print(res.json())
API端点
from flask import Flask, request
import numpy as np
import cv2 as cv
@app.route('/get', methods = ['POST'])
def get_image():
if request.method == 'POST':
file = request.files['image']
# Read file
f = file.read()
# convert string of image data to uint8
f1 = np.fromstring(f, np.uint8)
# decode image
f2 = cv.imdecode(f1,cv.IMREAD_COLOR)
解决方案
从 C# 发布数据的方式存在几个问题。最相关的是您尝试将文件作为 JSON 对象发布,文件内容为字符串。
这行不通:您的 python 服务器显然期望multipart/form-data
作为内容类型。
我还强烈建议您使用HttpClient
而不是旧HttpWebRequest
类来发送 HTTP 请求。
var filePath = @"file_path";
var url = "http://ip:port/get";
using (var client = new HttpClient())
using (var content = new MultipartFormDataContent())
using (var fileStream = File.OpenRead(filePath))
{
var imageContent = new StreamContent(fileStream);
// NOTE: the line below is not required, but useful when you know the media type
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(imageContent, "image", Path.GetFileName(filePath));
var response = await client.PostAsync(url, content);
var stringResponse = await response.Content.ReadAsStringAsync();
// do what you need with the response
}
其他小问题:
- 不要读取内存中的整个文件(使用
File.ReadAllBytes
),而是打开一个流进行读取。 - 尽可能使用
async
/await
,不要阻塞async
代码(不要使用.Result
,.Wait()
or.GetAwaiter().GetResult()
onTask
orTask<T>
) Dispose()
使用完对象后始终调用IDisposable
它们(将它们包装在using
块中)
推荐阅读
- python - 使用while循环猜游戏
- c# - 为什么是 IOptionsMonitor
.OnChange 没有被调用? - bash - POSIX sh:复合命令如何与管道一起使用?
- devops - 使用 VStest 并行运行测试不起作用
- php - PHP - 将变量的内容替换为名称
- mqtt - Thingsboard 断开 MQTT 客户端
- perl - 格式化哈希内容以生成报告
- angular - undefined[] 缺少类型中的以下属性
- python - 在 Pandas df 上运行 lower_case.translate 和 string.punctuation 的 AttributeError
- google-cloud-platform - 如何解决 terraform 中的“错误 409:这些数据存储实体的争用过多”?