从C#客户端向Python FastAPI发送Base64图片JSON遇500错误
问题描述
我已经完成基于Python FastAPI的代码整合,现在需要通过JSON发送Base64格式图片给后端处理,但C#客户端返回错误:System.Net.WebException: 'The remote server returned an error: (500) Internal Server Error'。以下是我的Python服务端代码和C#客户端代码,求解决思路。
Python服务端代码
import tensorflow as tf from fastapi import FastAPI import json import base64 from PIL import Image import io #from flask import request from fastapi import Request app = FastAPI() # Load the saved model cnn = tf.keras.models.load_model('modelo_cnn.h5') # Test functions to verify the connection # @app.get('/prueba0/') # def prueba0(): # return "Hello, I'm connecting..." # Test function to sum two numbers @app.get('/prueba1/{a}/{b}') def prueba1(a: int, b: int): return a + b # Test function to display a message @app.get('/prueba2/{text}') def prueba2(text: str): return "Hello, your message was... " + text ######################################################################################### # Overlap identification function @app.post('/traslape/') def traslape(request: Request): global cnn # Get data from the request body body = request.body() # Decode JSON data data = json.loads(body) # # # Open the JSON file (image) # with open(image) as f: # img = json.load(f) # # Decode the image # image = base64.b64decode(img["image"]) # # Open the image from bytes using Pillow # image = Image.open(io.BytesIO(image)) # # Concatenate images horizontally # #imagen_completa = tf.concat([imagen_i, imagen_d], axis=1) # # Apply gamma correction to the image # gamma = tf.convert_to_tensor(0.6) # gamma_corrected = tf.pow(imagen / 255.0, gamma) * 255.0 # imagen_completa # image_bw = tf.cast(gamma_corrected, tf.uint8) # # Convert the image to grayscale # grayscale_image = tf.image.rgb_to_grayscale(image_bw) # # Define new dimensions # new_height = 360 # new_width = 500 # # Resize the image # imagen_completa_resize = tf.image.resize(grayscale_image, [new_height, new_width]) # # Perform classification using the loaded model # result = cnn.predict(imagen_completa_resize) # if result[0][0] > result[0][1]: # result = False # No mask # else: # result = True # With mask return True
C#客户端代码
using System; using System.IO; using System.Net; using System.Text; namespace comunica_api { class Program { static void Main(string[] args) { // Path to the image in your local file system string imagePath = @"C:\Users\VirtualImages[00]20240418_124751_028.jpg"; try { // Read the bytes of the image from the file byte[] imageBytes = File.ReadAllBytes(imagePath); // Convert the bytes to a Base64 formatted string string base64String = Convert.ToBase64String(imageBytes); // URL of the API string url = "http://localhost:8000/traslape/"; // Data to send string json = "{\"image\": \"" + base64String + "\"}"; // Create the HTTP request var request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; // Use the POST method request.ContentType = "application/json"; // Set content type as JSON request.ContentLength = json.Length; // Convert JSON string to bytes byte[] jsonBytes = Encoding.UTF8.GetBytes(json); // Print the request content before sending it Console.WriteLine("Request:"); Console.WriteLine("URL: " + url); Console.WriteLine("Method: " + request.Method); Console.WriteLine("Headers:"); foreach (var header in request.Headers) { Console.WriteLine(header.ToString()); } Console.WriteLine("Body:"); Console.WriteLine(json); // Write bytes into the request body using StreamWriter using (Stream requestStream = request.GetRequestStream()) using (StreamWriter writer = new StreamWriter(requestStream)) { // Write JSON string into the request body writer.Write(json); } // Send the request and get the response // HERE IS THE ERROR using (var response = (HttpWebResponse)request.GetResponse()) // { // Read the response from the server using (var streamReader = new StreamReader(response.GetResponseStream())) { // Read the response as a string and display it in the console string responseText = streamReader.ReadToEnd(); Console.WriteLine("API Response:"); Console.WriteLine(responseText); } } } catch (FileNotFoundException) { Console.WriteLine("The specified image could not be found."); } catch (WebException ex) { // Handle any communication error with the API Console.WriteLine("API Communication Error:"); Console.WriteLine(ex.Message); } // Wait for the user to press Enter before exiting the program Console.ReadLine(); } } }
解决思路
1. 先定位FastAPI 500错误的具体原因
启动FastAPI服务时用uvicorn main:app --reload,发送请求后查看服务端控制台的异常栈信息,这是找到问题根源最直接的方式。
2. 规范FastAPI请求体解析方式
当前手动用Request对象解析JSON容易出错,改用Pydantic模型接收请求体,自动处理格式校验和解析:
from pydantic import BaseModel class ImageRequest(BaseModel): image: str @app.post('/traslape/') def traslape(req: ImageRequest): # 直接通过req.image获取Base64字符串 image_bytes = base64.b64decode(req.image) # 后续图像处理逻辑... return True
这种写法会在请求体格式错误时返回明确的422错误,而非模糊的500错误。
3. 修复C#端的请求构造问题
- 避免手动拼接JSON,用序列化框架生成:
// 定义对应请求结构的类 public class ImageRequest { public string image { get; set; } } // 序列化生成JSON(需引用Newtonsoft.Json或System.Text.Json) var requestData = new ImageRequest { image = base64String }; string json = JsonConvert.SerializeObject(requestData); - 修正
ContentLength赋值:当前用json.Length(字符数)错误,应使用UTF8字节数组的长度:byte[] jsonBytes = Encoding.UTF8.GetBytes(json); request.ContentLength = jsonBytes.Length; - 直接写入字节流更可靠:替换
StreamWriter写法,避免编码不一致问题:using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(jsonBytes, 0, jsonBytes.Length); }
4. 分步测试验证
先简化FastAPI接口,比如只返回Base64字符串的长度,确认C#端能正常发送并接收响应,再逐步添加图像处理和模型预测逻辑,避免一步到位排查困难。
5. 检查模型加载问题
确保modelo_cnn.h5路径正确,启动时添加异常捕获验证模型是否加载成功:
try: cnn = tf.keras.models.load_model('modelo_cnn.h5') except Exception as e: print(f"模型加载失败: {e}") raise
内容的提问来源于stack exchange,提问作者zumbide123
相关产品推荐
相关产品推荐

