Azure Functions - 带文件的路由模板

Azure Functions - route template with file

我创建了一个接收 HTTP 请求和 returns HTTP 请求的 Azure 函数。函数:

  1. 接受 HTTP 请求
  2. 创建指向 blob 存储中某个位置的 URI,共享访问签名将在 n minutes/hours
  3. 后过期
  4. Returns 一个 302 状态代码,其位置 header 设置为将在 n minutes/hours
  5. 后过期的 URI

当我将 blob 的路径放在查询参数中时,我能够让它工作,但是当该变量在路由模板中时它失败了。

我尝试制作路由模板:storage/{containerName:alpha}/{path:alpha} 但它总是 returns 404。下面是请求构建方式的示例 cURL。

GET /api/storage/example-container-name/example.jpg?code=SSBhbSBhIHRlYXBvdCwgZG8geW91IHRoaW5rIEkgd291bGQgcHV0IGEgcGFzc3dvcmQgaGVyZT8= HTTP/1.1
Host: hostdoesnotexist.azurewebsites.net    
Cache-Control: no-cache

**注意:主机不是真实的,路径和代码也不是真实的*

我确实发现这个问题与 Azure Functions Proxy 做同样的事情有关,但这个问题不适用于 Functions。

使用此 Azure Functions HTTP and webhook bindings 示例,并滚动到 自定义 HTTP 端点 部分,我使用以下代码创建了另一个函数:

Function.json - id 从 int 变了?阿尔法

{
  "bindings": [
    {
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get"
      ],
      "route": "products/{category:alpha}/{id:alpha}",
      "authLevel": "function"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ],
  "disabled": false
}

run.csx

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, 
                                                    string category, 
                                                    string id,
                                                    TraceWriter log)
{
    if (id == null)
        return  req.CreateResponse(HttpStatusCode.OK, $"All {category} items were requested.");
    else
        return  req.CreateResponse(HttpStatusCode.OK, $"{category} item with id = {id} has been requested.");
}

因此,如果路由是 products/test/abcd,则它会响应:

200 - "test item with id = abc has been requested."

但是,如果您将其更改为 products/test/abcd.jpg,那么它会响应:

404 - 您要查找的资源已被删除、更名或暂时不可用。

这与我在创建的其他函数中看到的行为相同。

有谁知道这是否是像代理示例那样的错误,或者我的路线应该看起来不同吗?同样,我使用查询参数进行了此工作,但是当我将变量移动到路由模板中时它失败了。

已编辑 - 根据反馈添加了文件 function.json

{
  "bindings": [
    {
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get"
      ],
      "route": "products/{category:alpha}",
      "authLevel": "function"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ],
  "disabled": false
}

run.csx

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, 
                                                    string category, 
                                                    TraceWriter log)
{
    string id = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
        .Value;


    if (id == null)
        return  req.CreateResponse(HttpStatusCode.OK, $"All {category} items were requested.");
    else
        return  req.CreateResponse(HttpStatusCode.OK, $"{category} item with id = {id} has been requested.");
}

proxies.json

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "GetJustArtinAroundStorageLinkProxy": {
            "matchCondition": {
                "route": "/products/{category:alpha}/{id}",
                "methods": [
                    "GET"
                ]
            },
            "backendUri": "https://<company-name>.azurewebsites.net/api/products/{category:alpha}?id={id}"
        }
    }
}

目前,HttpTrigger 有一个限制,它不支持带有扩展的请求(有关详细信息,请参阅 this)。

如问题中所述,您可以使用代理来解决此限制,但您确实需要从路由中删除 alpha 约束。

这是一个示例代理配置,它将转发您上面的 id 作为查询字符串:

{
    "$schema": "http://json.schemastore.org/proxies",
    "proxies": {
        "Test": {
            "matchCondition": {
                "route": "products/{category}/{id}"
            },
            "backendUri": "https://<functionapp>.azurewebsites.net/api/<function>?id={id}"
        }
    }
}

您可以调整以上内容以满足您的要求,但这应该会为您提供所需的行为。