如何在Azure Functions C#上以简单的方式获取GET查询参数?

Ton*_*ony 8 c# azure azure-functions

我试过了

    /// <summary>
    /// Request the Facebook Token
    /// </summary>
    [FunctionName("SolicitaFacebookToken")]
    [Route("SolicitaToken/?fbAppID={fbAppID}&fbCode={fbCode}&fbAppSecret={fbAppSecret}")]
    public static async Task<HttpResponseMessage> SolicitaFacebookToken(
        [HttpTrigger(AuthorizationLevel.Function, methods: new string[] { "get" } )]
        HttpRequestMessage req,
        TraceWriter log,
        string fbAppID,
        string fbCode,
        string fbAppSecret
    )
    { }
Run Code Online (Sandbox Code Playgroud)

当我访问URL时

http://localhost:7071/api/SolicitaFacebookToken/?fbAppID=ABC&fbCode=DEF&fbAppSecret=GHI
Run Code Online (Sandbox Code Playgroud)

但这会带来以下错误:

无法从Azure WebJobs SDK调用“ SolicitaFacebookToken”。是否缺少Azure WebJobs SDK属性?System.InvalidOperationException:无法从Azure WebJobs SDK调用'SolicitaFacebookToken'。是否缺少Azure WebJobs SDK属性?在Microsoft.Azure.WebJobs.JobHost.Validate(IFunctionDefinition函数,对象键)在异步Microsoft.Azure.WebJobs.JobHost.CallAsync(??)在异步Microsoft.Azure.WebJobs.Script.ScriptHost.CallAsync(String method,Dictionary异步Microsoft.Azure.WebJobs.Script.Host.FunctionRequestInvoker处的`2个参数,异步Microsoft.Azure.WebJobs.Script.WebHost.WebScriptHostManager.HandleRequestAsync(FunctionDescriptor function,HttpRequestMessage request,CancellationToken cancellingToken)处的异步参数。

如果我更改为

HttpRequestMessage req,
        string fbAppID,
        string fbCode,
        string fbAppSecret,
        TraceWriter log
Run Code Online (Sandbox Code Playgroud)

[14/04/2018 15:24:49]以下1个功能有误:

[14/04/2018 15:24:49] SolicitaFacebookToken:Microsoft.Azure.WebJobs.Host:错误索引方法'Function1.SolicitaFacebookToken'。Microsoft.Azure.WebJobs.Host:无法将参数“ fbAppID”绑定为字符串类型。确保绑定支持参数类型。如果您正在使用绑定扩展(例如ServiceBus,Timer等),请确保已在启动代码(例如config.UseServiceBus(),config.UseTimers()等)中调用了扩展的注册方法。 )。

在Azure Functions模板代码中,有

string name = req.GetQueryNameValuePairs()
                 .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                 .Value;
Run Code Online (Sandbox Code Playgroud)

我想要一种更简单的方法来获取GET查询参数。

我想要一个类似的网址

http://localhost:7071/api/SolicitaFacebookToken/?fbAppID=123&fbCode=456&fbAppSecret=789
Run Code Online (Sandbox Code Playgroud)

并轻松获取参数及其值。

怎么做?

Tob*_*ias 13

对我来说,在 get 方法中处理查询参数的最简单方法是定义一个 PoCo 对象并使用[FromQuery]属性,就像我在 .Net Web API 中使用的那样。

不幸的是,我最初使用 HTTP 触发的 Azure 函数执行此操作的方法导致了原始问题中描述的相同异常。

经过一番谷歌搜索后,我几乎失去了所有希望,因为所有引用(至少是我找到的引用)都表明这是不可能的,或者他们只是希望您使用路由配置或从请求对象中获取查询参数,或者相反使用 GET 使用 POST 请求并传递您想要作为请求正文的一部分传递的内容...

由于所有这些都不是很令人满意,我打算为我想在函数的 GET 请求中使用的 POCO 对象实现我自己的自定义 BindingProvider...

然后我仔细查看了 azure-webjobs-sdk-extensions 的来源,发现了这个:HttpDirectRequestBindingProvider

来自该课程的评论:

// support allowing binding any non-attributed HttpRequest parameter to the incoming http request. 
//    Foo([HttpTrigger] Poco x, HttpRequest y); 
Run Code Online (Sandbox Code Playgroud)

事实证明,以下内容实际上是受支持的并且按预期工作:

Tl;博士;

确保 HttpTrigger 属性应用于您的 Poco 对象参数,以允许魔术绑定启动!

public async Task<IActionResult> Foo([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
    PaginationFilter paginationFilter, HttpRequest req, ClaimsPrincipal principal, CancellationToken cancellationToken)
Run Code Online (Sandbox Code Playgroud)

我的例子中的类型PaginationFilter是这样指定的:

请注意,这只是一个示例。您可以在函数签名中使用任何类似 PoCo 的类型,只要它是 JSON 可序列化的并且具有默认构造函数即可。

public record PaginationFilter(Int32 Limit, Int32 Page)
{
    public PaginationFilter()
        : this(Constants.DefaultPageSize, 1)
    { }
}
Run Code Online (Sandbox Code Playgroud)

支持使用此签名的查询:

http://localhost:7071/api/Foo?Limit=50&Page=1
or
http://localhost:7071/api/Foo?Limit=50
or
http://localhost:7071/api/Foo?Page=1
or
http://localhost:7071/api/Foo
Run Code Online (Sandbox Code Playgroud)

另请参阅我对Azure-Functions GitHub 问题上相关问题的原始回答

回答原来的问题

因此,为了回答最初的问题,如果您创建一个传输对象,如下所示:

public class TokenSecrets
{
    public TokenSecrets() {}
    public string FbAppID {get; set;}
    public string FbCode {get; set;}
    public string FbAppSecret {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

您可以将您的函数调用调整为:

public static async Task<HttpResponseMessage> SolicitaFacebookToken(
    [HttpTrigger(AuthorizationLevel.Function, methods: new string[] { "get" } )]
    TokenSecrets secrets,
    HttpRequestMessage req,
    TraceWriter log
)
{ 
    // and access the query parameters like:
    var id = secrets.FbAppId;
    ...
}
Run Code Online (Sandbox Code Playgroud)

无需更改 API 的调用方式。


小智 12

在 v2 运行时,另一种获取查询参数的方法:

var query = System.Web.HttpUtility.ParseQueryString(req.RequestUri.Query);
string result = query.Get("result");
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。


Sea*_*ean 11

过去,当我有多个参数时,已将它们添加到路由中。所以代替这个:

[Route("SolicitaToken/?fbAppID={fbAppID}&fbCode={fbCode}&fbAppSecret={fbAppSecret}")]
Run Code Online (Sandbox Code Playgroud)

我做了这样的事情:

[Route("SolicitaToken/{fbAppID}/{fbCode}/{fbAppSecret}")]
Run Code Online (Sandbox Code Playgroud)

然后,您根本不需要访问查询字符串,并且可以直接使用函数参数。

[FunctionName("Function1")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "HttpTriggerCSharp/name/{fbAppID}/{fbCode}/{fbAppSecret}")]HttpRequestMessage req, string fbAppID, string fbCode, string fbAppSecret, TraceWriter log)
{
  log.Info("C# HTTP trigger function processed a request.");
  var msg = $"App ID: {fbAppID}, Code: {fbCode}, Secret: {fbAppSecret}";
  // Fetching the name from the path parameter in the request URL
  return req.CreateResponse(HttpStatusCode.OK, msg);
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,将查询参数放入路由中被认为是不好的做法。最佳实践是路径参数标识资源,[如此处所述](/sf/ask/2167747571/ restful-api#:~:text=8%20Answers&amp;text=Best%20practice%20for%20RESTful%20API,to%20sort%2Ffilter%20those%20resources。)。 (3认同)
  • 这有效。但我想要 SolicitaToken/?fbAppID={fbAppID}&amp;fbCode={fbCode}&amp;fbAppSecret={fbAppSecret} ... 不可能有 name=value 形式的 GET 参数吗? (2认同)

evi*_*obu 7

对于v2 / beta / .NET Core运行时,您可以特定并执行以下操作:

string fbAppID = req.Query["fbAppID"];
Run Code Online (Sandbox Code Playgroud)

或更通用的:

using System.Collections.Generic;
...
IDictionary<string, string> queryParams = req.GetQueryParameterDictionary();
// Use queryParams["fbAppID"] to read keys from the dictionary.
Run Code Online (Sandbox Code Playgroud)

对于v1功能应用程序(.NET Full Framework):

using System.Collections.Generic;
...
IDictionary<string, string> queryParams = req.GetQueryNameValuePairs()
    .ToDictionary(x => x.Key, x => x.Value);
// Use queryParams["fbAppID"] to read keys from the dictionary.
Run Code Online (Sandbox Code Playgroud)

  • 很有可能您正在使用v1运行时,请使用`req.GetQueryNameValuePairs()`,请参见上文。 (2认同)