C# Azure:无法从Azure函数HttpTrigger读取Blob文本(400-错误请求错误)

C# Azure:无法从Azure函数HttpTrigger读取Blob文本(400-错误请求错误),c#,azure,http-post,azure-functions,C#,Azure,Http Post,Azure Functions,我在Azure(blob)存储中读取blob中存储的文本时遇到问题。 blob只包含一行文本(字符串)。blob通过Azure函数HttpTrigger(C#)填充文本,该函数通过POST接收文本并将文本保存到具有用户指定名称的blob。保存blob时,名称将转换为所有小写 然后,用户可以访问一个简单的HTML网页,并在表单中输入blob的名称。当用户单击HTML表单上的“提交”时,将针对不同的Azure函数API执行POST。此函数访问blob并从中读取文本。每当我在Azure函数中或使用Po

我在Azure(blob)存储中读取blob中存储的文本时遇到问题。

blob只包含一行文本(字符串)。blob通过Azure函数HttpTrigger(C#)填充文本,该函数通过POST接收文本并将文本保存到具有用户指定名称的blob。保存blob时,名称将转换为所有小写

然后,用户可以访问一个简单的HTML网页,并在表单中输入blob的名称。当用户单击HTML表单上的“提交”时,将针对不同的Azure函数API执行POST。此函数访问blob并从中读取文本。每当我在Azure函数中或使用Postman测试函数时,它都能正常工作(我会返回blob文本)

当我尝试使用网页与API交互时,当Azure函数从blob读取时,我会收到一个“400-Bad请求”。详情如下:

来自邮差的API正常工作日志:

#r "Microsoft.WindowsAzure.Storage"
using System;
using System.IO;
using System.Net;
using System.Text;
using Microsoft.Azure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, Binder binder)
{
    log.Info("C# HTTP trigger function processed a request.");

    // Get text passed in POST
    string postData = await req.Content.ReadAsStringAsync();
    log.Info("Data from POST: " + postData);

    // Format blobName string to remove unwanted text
    // Help from http://stackoverflow.com/questions/9505400/extract-part-of-a-string-between-point-a-and-b
    int startPos = postData.LastIndexOf("blobName=") + "blobName=".Length;
    int length = postData.IndexOf("submit=") - startPos;
    string blobName = postData.Substring(startPos, length);
    blobName = blobName.ToLower();      // Name of blob must be all lower-case

    log.Info("Blob name is: " + blobName);

    // START BLOB READING
    log.Info("Accessing Azure Storage account.");
    string containerAndBlob = "usertext-container/blob-" + blobName;

    var attributes = new Attribute[]
    {
         new StorageAccountAttribute("[StorageAccountName]"),
         new BlobAttribute(containerAndBlob)
    };

    try
    {
        userBlobText = await binder.BindAsync<string>(attributes);
    }
    catch (StorageException ex)
    {
        var requestInformation = ex.RequestInformation;
        var extendedInformation = requestInformation.ExtendedErrorInformation;

        if (extendedInformation == null)
        {
            log.Info("No Extended Error Information!");
            log.Info(requestInformation.HttpStatusMessage);
        }
        else
        {
            log.Info(requestInformation.HttpStatusMessage);

            var errorMessage = string.Format("({0}) {1}", extendedInformation.ErrorCode, extendedInformation.ErrorMessage);

            var errorDetails = extendedInformation.AdditionalDetails.Aggregate("", (s, pair) =>
            {
                return s + string.Format("{0}={1},", pair.Key, pair.Value);
            });

            log.Info(errorMessage + ": Error Details: " + errorDetails);
        }
    }

    log.Info("Text in Blob: " + userBlobText.ToString());
    // END BLOB READING

    return userBlobText == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass blob name in the request body.")
        : req.CreateResponse(HttpStatusCode.OK, "Your blob stored the text: " + userBlobText.ToString());
}
2017-04-11T20:19:14.340功能启动(Id=ea82f5c6-4345-40cc-90a5-1cb1cad78b7b)

2017-04-11T20:19:14.340 C#HTTP触发器函数处理了一个请求

2017-04-11T20:19:14.340来自POST的数据:blobName=TestBlob1submit=SubmitButtonText

2017-04-11T20:19:14.340 Blob名称为:testblob1

2017-04-11T20:19:14.340访问Azure存储帐户

2017-04-11T20:19:14.402 Blob文本:你好,世界测试

2017-04-11T20:19:14.402功能完成(成功,Id=ea82f5c6-4345-40cc-90a5-1cb1cad78b7b)

API未通过HTML表单工作的日志:

#r "Microsoft.WindowsAzure.Storage"
using System;
using System.IO;
using System.Net;
using System.Text;
using Microsoft.Azure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, Binder binder)
{
    log.Info("C# HTTP trigger function processed a request.");

    // Get text passed in POST
    string postData = await req.Content.ReadAsStringAsync();
    log.Info("Data from POST: " + postData);

    // Format blobName string to remove unwanted text
    // Help from http://stackoverflow.com/questions/9505400/extract-part-of-a-string-between-point-a-and-b
    int startPos = postData.LastIndexOf("blobName=") + "blobName=".Length;
    int length = postData.IndexOf("submit=") - startPos;
    string blobName = postData.Substring(startPos, length);
    blobName = blobName.ToLower();      // Name of blob must be all lower-case

    log.Info("Blob name is: " + blobName);

    // START BLOB READING
    log.Info("Accessing Azure Storage account.");
    string containerAndBlob = "usertext-container/blob-" + blobName;

    var attributes = new Attribute[]
    {
         new StorageAccountAttribute("[StorageAccountName]"),
         new BlobAttribute(containerAndBlob)
    };

    try
    {
        userBlobText = await binder.BindAsync<string>(attributes);
    }
    catch (StorageException ex)
    {
        var requestInformation = ex.RequestInformation;
        var extendedInformation = requestInformation.ExtendedErrorInformation;

        if (extendedInformation == null)
        {
            log.Info("No Extended Error Information!");
            log.Info(requestInformation.HttpStatusMessage);
        }
        else
        {
            log.Info(requestInformation.HttpStatusMessage);

            var errorMessage = string.Format("({0}) {1}", extendedInformation.ErrorCode, extendedInformation.ErrorMessage);

            var errorDetails = extendedInformation.AdditionalDetails.Aggregate("", (s, pair) =>
            {
                return s + string.Format("{0}={1},", pair.Key, pair.Value);
            });

            log.Info(errorMessage + ": Error Details: " + errorDetails);
        }
    }

    log.Info("Text in Blob: " + userBlobText.ToString());
    // END BLOB READING

    return userBlobText == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass blob name in the request body.")
        : req.CreateResponse(HttpStatusCode.OK, "Your blob stored the text: " + userBlobText.ToString());
}
2017-04-11T20:19:52.594功能启动(Id=1b1a39b6-0ab8-4673-bbf0-ae0006f7f7cf)

2017-04-11T20:19:52.594 C#HTTP触发器函数处理了一个请求

2017-04-11T20:19:52.594来自POST的数据:blobName=TestBlob1

提交=检索Blob文本

2017-04-11T20:19:52.594 Blob名称为:testblob1

2017-04-11T20:19:52.594访问Azure存储帐户

2017-04-11T20:19:52.626功能完成(故障,Id=1b1a39b6-0ab8-4673-bbf0-AE0006F7CF)

2017-04-11T20:19:52.672执行函数时出现异常:Functions.Austin-SteelThread-HttpTrigger-displayblotext。Microsoft.WindowsAzure.Storage:远程服务器返回错误:(400)请求错误。

这里是有问题的Azure函数:

#r "Microsoft.WindowsAzure.Storage"
using System;
using System.IO;
using System.Net;
using System.Text;
using Microsoft.Azure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, Binder binder)
{
    log.Info("C# HTTP trigger function processed a request.");

    // Get text passed in POST
    string postData = await req.Content.ReadAsStringAsync();
    log.Info("Data from POST: " + postData);

    // Format blobName string to remove unwanted text
    // Help from http://stackoverflow.com/questions/9505400/extract-part-of-a-string-between-point-a-and-b
    int startPos = postData.LastIndexOf("blobName=") + "blobName=".Length;
    int length = postData.IndexOf("submit=") - startPos;
    string blobName = postData.Substring(startPos, length);
    blobName = blobName.ToLower();      // Name of blob must be all lower-case

    log.Info("Blob name is: " + blobName);

    // START BLOB READING
    log.Info("Accessing Azure Storage account.");
    string containerAndBlob = "usertext-container/blob-" + blobName;

    var attributes = new Attribute[]
    {
         new StorageAccountAttribute("[StorageAccountName]"),
         new BlobAttribute(containerAndBlob)
    };

    try
    {
        userBlobText = await binder.BindAsync<string>(attributes);
    }
    catch (StorageException ex)
    {
        var requestInformation = ex.RequestInformation;
        var extendedInformation = requestInformation.ExtendedErrorInformation;

        if (extendedInformation == null)
        {
            log.Info("No Extended Error Information!");
            log.Info(requestInformation.HttpStatusMessage);
        }
        else
        {
            log.Info(requestInformation.HttpStatusMessage);

            var errorMessage = string.Format("({0}) {1}", extendedInformation.ErrorCode, extendedInformation.ErrorMessage);

            var errorDetails = extendedInformation.AdditionalDetails.Aggregate("", (s, pair) =>
            {
                return s + string.Format("{0}={1},", pair.Key, pair.Value);
            });

            log.Info(errorMessage + ": Error Details: " + errorDetails);
        }
    }

    log.Info("Text in Blob: " + userBlobText.ToString());
    // END BLOB READING

    return userBlobText == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass blob name in the request body.")
        : req.CreateResponse(HttpStatusCode.OK, "Your blob stored the text: " + userBlobText.ToString());
}
#r“Microsoft.WindowsAzure.Storage”
使用制度;
使用System.IO;
Net系统;
使用系统文本;
使用Microsoft.Azure;
使用Microsoft.WindowsAzure.Storage;
使用Microsoft.WindowsAzure.Storage.Blob;
公共静态异步任务运行(HttpRequestMessage请求、TraceWriter日志、活页夹)
{
Info(“C#HTTP触发器函数处理了一个请求。”);
//获取在POST中传递的文本
字符串postData=wait req.Content.ReadAsStringAsync();
log.Info(“来自POST的数据:+postData”);
//格式化blobName字符串以删除不需要的文本
//帮助http://stackoverflow.com/questions/9505400/extract-part-of-a-string-between-point-a-and-b
int startPos=postData.LastIndexOf(“blobName=”)+“blobName=”.Length;
int length=postData.IndexOf(“submit=”)-startPos;
string blobName=postData.Substring(startPos,length);
blobName=blobName.ToLower();//blob的名称必须全部小写
log.Info(“Blob名称为:”+blobName);
//开始读BLOB
log.Info(“访问Azure存储帐户”);
string containerAndBlob=“usertext container/blob-”+blobName;
变量属性=新属性[]
{
新的StorageAccountAttribute(“[StorageAccountName]”),
新BlobatAttribute(containerAndBlob)
};
尝试
{
userBlobText=await binder.BindAsync(属性);
}
捕获(StorageException-ex)
{
var requestInformation=ex.requestInformation;
var extendedInformation=requestInformation.ExtendedErrorInformation;
if(extendedInformation==null)
{
log.Info(“无扩展错误信息!”);
log.Info(requestInformation.HttpStatusMessage);
}
其他的
{
log.Info(requestInformation.HttpStatusMessage);
var errorMessage=string.Format(“({0}){1}”,extendedInformation.ErrorCode,extendedInformation.errorMessage);
var errorDetails=extendedInformation.AdditionalDetails.Aggregate(“,(s,pair)=>
{
返回s+string.Format(“{0}={1},”,pair.Key,pair.Value);
});
日志信息(errorMessage+”:错误详细信息:“+errorDetails”);
}
}
log.Info(“Blob中的文本:+userBlobText.ToString());
//结束斑点读数
返回userBlobText==null
?req.CreateResponse(HttpStatusCode.BadRequest,“请在请求正文中传递blob名称”)
:req.CreateResponse(HttpStatusCode.OK,“您的blob存储了文本:“+userBlobText.ToString()”);
}

如何解决此问题,使函数读取blob文本,而web浏览器显示blob文本(现在我只得到一个空字符串)?提前感谢。

您应该利用绑定引擎,而不是手动连接到Blob存储。将
binder
参数添加到函数中,然后使用它检索文件:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, 
    TraceWriter log, Binder binder)
{
    // Do await, not .Result
    string postData = await req.Content.ReadAsStringAsync();

    // ... get your HTTP parameters here

    var attributes = new Attribute[]
    {
         new StorageAccountAttribute(accountName),
         new BlobAttribute(blobName) // blobName should have "container/blob" format
    };

    var userBlobText = await binder.BindAsync<string>(attributes);
    // do whatever you want with this blob...
}
公共静态异步任务运行(HttpRequestMessage req,
TraceWriter日志、活页夹(活页夹)
{
//不要等待,不要等待结果
字符串postData=wait req.Content.ReadAsStringAsync();
//…在此处获取您的HTTP参数
变量属性=新属性[]
{
新的StorageAccountAttribute(accountName),
新建BlobAttribute(blobName)//blobName应具有“container/blob”格式
};
var userBlobText=await binder.BindAsync(属性);
//你想怎么处理这个东西就怎么处理。。。
}

您实际上应该将异常强制转换为StorageException。这个