首页 > 解决方案 > 从 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#.net

解决方案


从 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()on Taskor Task<T>
  • Dispose()使用完对象后始终调用IDisposable它们(将它们包装在using块中)

推荐阅读