使用http触发功能将输入绑定到表存储

时间:2019-06-05 17:43:39

标签: c# .net azure azure-functions azure-table-storage

是否可以(输入)绑定到通过HTTP触发的函数中的表存储?

我正尝试在具有以下属性的常规http触发函数内部向表存储添加输入绑定:

    [Table("MyTable", "MyPartition", "{httpTrigger}")] MyPoco poco

但是我执行它时却返回以下错误:

  

[6/5/2019 5:36:38 PM]发生未处理的主机错误。 [6/5/2019   5:36:38 PM] Microsoft.Azure.WebJobs.Host:   无法从Azure调用'tableStorageInputBindingHttpTriggered'   WebJobs SDK。是否缺少Azure WebJobs SDK属性?。

另外,在启动时,我得到了这个异常:

  

[2019/6/5下午6:17:17] tableStorageInputBindingHttpTriggered:Microsoft.Azure.WebJobs.Host:错误索引方法“ tableStorageInputBindingHttpTriggered”。 Microsoft.Azure.WebJobs.Host:无法解析绑定参数“ httpTrigger”。绑定表达式必须映射到触发器提供的值或触发器绑定到的值的属性,或者必须是系统绑定表达式(例如sys.randguid,sys.utcnow等)。

这是全部功能:

public class MyPoco
{
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public string Directory { get; set; }
}

public static class tableStorageInputBindingHttpTriggered
{
    [FunctionName("tableStorageInputBindingHttpTriggered")]
    public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    [Table("MyTable", "MyPartition", "{httpTrigger}")] MyPoco poco,
        ILogger log)
    {


        string name = req.Query["name"];

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;

        return name != null
            ? (ActionResult)new OkObjectResult($"PK={poco.PartitionKey}, RK={poco.RowKey}, Text={poco.Directory}")
            : new BadRequestObjectResult("");
    }
}

我在做什么错?如何在http触发的azure函数中绑定到表存储?

2 个答案:

答案 0 :(得分:2)

似乎您正在尝试从Azure Table Storage中读取HTTP Trigger Function。请参见下面的代码段:

您的POCO类别:

  public class MyPoco
    {

        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
        public string Directory { get; set; }

    }

表存储类:

 public class TableStorageClass
    {
        public TableStorageClass()
        {

        }
        public TableStorageClass(DynamicTableEntity entity)
        {
            PartitionKey = entity.PartitionKey;
            RowKey = entity.RowKey;

        }

        public string PartitionKey { get; set; }
        public string RowKey { get; set; }


    }

Azure HTTP触发功能V2:

public static class FunctionReadFromTableStorage
    {
        [FunctionName("FunctionReadFromTableStorage")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            //Read Request Body
            var content = await new StreamReader(req.Body).ReadToEndAsync();

            //Extract Request Body and Parse To Class
            MyPoco objMyPoco = JsonConvert.DeserializeObject<MyPoco>(content);

            // Validate param because PartitionKey and RowKey is required to read from Table storage In this case , so I am checking here.
            dynamic validationMessage;

            if (string.IsNullOrEmpty(objMyPoco.PartitionKey))
            {
                validationMessage = new OkObjectResult("PartitionKey is required!");
                return (IActionResult)validationMessage;
            }
            if (string.IsNullOrEmpty(objMyPoco.RowKey))
            {
                validationMessage = new OkObjectResult("RowKey is required!");
                return (IActionResult)validationMessage;
            }


            // Table Storage operation  with credentials
            var client = new CloudTableClient(new Uri("https://YourStorageURL.table.core.windows.net/"),
                      new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials("YourStorageName", "xtaguZokAWbfYG4QDkBjT+YourStorageKey+T/kId/Ng+cl3TfYHtg=="));
            var table = client.GetTableReference("YourTableName");

            //Query filter
            var query = new TableQuery()
            {
                FilterString = string.Format("PartitionKey eq '{0}' and RowKey eq '{1}'", objMyPoco.PartitionKey, objMyPoco.RowKey)
            };


            //Request for storage query with query filter
            var continuationToken = new TableContinuationToken();
            var storageTableQueryResults = new List<TableStorageClass>();
            foreach (var entity in table.ExecuteQuerySegmentedAsync(query, continuationToken).GetAwaiter().GetResult().Results)
            {
                var request = new TableStorageClass(entity);
                storageTableQueryResults.Add(request);
            }

            //As we have to return IAction Type So converting to IAction Class Using OkObjectResult We Even Can Use OkResult
            var result = new OkObjectResult(storageTableQueryResults);
            return (IActionResult)result;
        }
    }

记住点:

  1. 在执行Azure Portal的情况下,只需摆脱FunctionReadFromTableStorage
  2. 您需要以下参考资料才能执行上述代码
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.Collections.Generic;

邮递员请求模式:

函数调用示例:

{
   "PartitionKey": "Your Param According to Table Storage Design" ,
   "RowKey": "Your Param According to Table Storage Design",
   "Directory": "Your Param According to Table Storage Design"
}

查看屏幕截图:

enter image description here

邮递员回复:

响应取决于我自己的表格设计

[
    {
        "partitionKey": "Microsoft SharePoint Server",
        "rowKey": "2016"
    }
]

请参见下面的屏幕截图:

enter image description here

  

注意:我喜欢以简单易懂的方式编写代码。我只是为您的情况尝试过。如果它解决了您的问题,我的努力将是   那么成功。这是到目前为止我所知道的最简单的方法   azure table storage

如果您还有任何问题,请随时分享。谢谢,祝您编程愉快!

答案 1 :(得分:1)

这通过绑定到CloudTable

将请求主体插入到表存储中
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Table;

namespace AzureFunctionsSandbox
{
    public class MyPoco : TableEntity
    {
        public string Body { get; set; }
    }

    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            [Table("Sandbox", "StorageConnectionString")] CloudTable table,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            var poco = new MyPoco { PartitionKey = "HttpTrigger", RowKey = Guid.NewGuid().ToString(), Body = requestBody };

            var insertOperation = TableOperation.Insert(poco);

            await table.ExecuteAsync(insertOperation);

            return new OkObjectResult($"PK={poco.PartitionKey}, RK={poco.RowKey}, Text={poco.Body}");
        }
    }
}

注意MyPoco继承自TableEntity,您可以创建TableOperation.Insert(poco),因为.Insert()需要ITableEntity。 / p>

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",

    "StorageConnectionString": "UseDevelopmentStorage=true"
  }
}