问题
In Python, I converted an image into bytes. Then, I pass the bytes to an Azure HTTP Trigger function app endpoint URL (Azure Portal) like this, just like usual when calling Azure cognitive services.
image_path = r"C:\Users\User\Desktop\bicycle.jpg"
image_data = open(image_path, "rb").read()
print(len(image_data)) # print length to compare later
url = "https://xxxx.azurewebsites.net/api/HTTPTrigger1........."
headers = {'Content-Type': 'application/octet-stream'}
response = requests.post(url, headers=headers,
data=image_data)
However, I have no idea on how to retrieve the bytes data in the function app on Azure Portal. I tried the following (C#) but it did not work. It seems like ReadToEndAsync()
is not meant to read bytes data from request body? Or is it because of HttpRequest
?
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
byte[] imageBytes = Encoding.ASCII.GetBytes(requestBody);
log.LogInformation(imageBytes.Length.ToString());
// the length logged is totally not the same with len(image_data) in Python
//ignore the following lines (not related)
return name != null
? (ActionResult)new OkObjectResult("OK")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
Any idea about this? I do know a workaround using base64 string but I'm just really curious about how Azure cognitive services do it!
Thanks in advance.
回答1:
Do not use ReadToEndAsync()
, instead, use MemoryStream()
. ReadToEndAsync()
is used to read string buffer which can mess up the incoming bytes data. Use CopyToAsync()
and then convert the memory stream into bytes array to preserve the incoming bytes data.
public static async Task<HttpResponseMessage> Run(HttpRequest req, ILogger log)
{
//string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
MemoryStream ms = new MemoryStream();
await req.Body.CopyToAsync(ms);
byte[] imageBytes = ms.ToArray();
log.LogInformation(imageBytes.Length.ToString());
// ignore below (not related)
string finalString = "Upload succeeded";
Returner returnerObj = new Returner();
returnerObj.returnString = finalString;
var jsonToReturn = JsonConvert.SerializeObject(returnerObj);
return new HttpResponseMessage(HttpStatusCode.OK) {
Content = new StringContent(jsonToReturn, Encoding.UTF8, "application/json")
};
}
public class Returner
{
public string returnString { get; set; }
}
Reference/Inspired by: https://weblog.west-wind.com/posts/2017/sep/14/accepting-raw-request-body-content-in-aspnet-core-api-controllers
来源:https://stackoverflow.com/questions/54944607/how-to-retrieve-bytes-data-from-request-body-in-azure-function-app