Azure Functions - 带文件的路由模板
Azure Functions - route template with file
我创建了一个接收 HTTP 请求和 returns HTTP 请求的 Azure 函数。函数:
- 接受 HTTP 请求
- 创建指向 blob 存储中某个位置的 URI,共享访问签名将在 n minutes/hours
后过期
- Returns 一个 302 状态代码,其位置 header 设置为将在 n minutes/hours
后过期的 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}"
}
}
}
您可以调整以上内容以满足您的要求,但这应该会为您提供所需的行为。
我创建了一个接收 HTTP 请求和 returns HTTP 请求的 Azure 函数。函数:
- 接受 HTTP 请求
- 创建指向 blob 存储中某个位置的 URI,共享访问签名将在 n minutes/hours 后过期
- Returns 一个 302 状态代码,其位置 header 设置为将在 n minutes/hours 后过期的 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}"
}
}
}
您可以调整以上内容以满足您的要求,但这应该会为您提供所需的行为。