How to retrieve bytes data from request body in Azure Function App

坚强是说给别人听的谎言 提交于 2020-01-04 05:57:16

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!