Azure EventGrid使用OkObjectResult验证失败问题排查
Azure Event Grid 订阅验证返回结果异常问题解决
问题描述
尝试实现Azure Event Grid的订阅同步握手验证,代码逻辑参考官方示例,但返回结果不符合预期:
实现代码
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData OriginalRequest) { Log.LogInformation("HTTP Request Received"); BinaryData RawEvents = BinaryData.FromStream(OriginalRequest.Body); EventGridEvent[] EventGridEvents = EventGridEvent.ParseMany(RawEvents); foreach (EventGridEvent Event in EventGridEvents) { if (Event.TryGetSystemEventData(out object EventData)) { if (EventData is SubscriptionValidationEventData ValidationEventData) { var ResponseData = new { ValidationResponse = ValidationEventData.ValidationCode }; Log.LogInformation("Validation Complete"); return new OkObjectResult(ResponseData); } else { RelayEvent(OriginalRequest); } } } return new OkObjectResult(string.Empty); }
预期返回
{ "ValidationResponse": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6" }
实际返回
{ "Value": { "ValidationResponse": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6" }, "Formatters": [], "ContentTypes": [], "DeclaredType": null, "StatusCode": 200 }
异步代码改造后问题依然存在。
原因分析
问题核心在于Azure Functions的运行时模型差异:
- In-Process模型:框架会自动识别并解析
IActionResult类型,将其封装的内容作为HTTP响应体返回,这也是官方示例默认的运行环境。 - Isolated Worker模型:该模型中
IActionResult会被当作普通CLR对象处理,直接序列化对象的所有属性,而非解析它代表的HTTP响应内容。你的函数使用了Isolated模型,因此返回结果与示例不符。
解决方法
方案1:适配Isolated模型,改用HttpResponseData返回
在Isolated Worker模型中,直接构建HttpResponseData对象来返回响应:
public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req) { Log.LogInformation("HTTP Request Received"); BinaryData rawEvents = BinaryData.FromStream(req.Body); EventGridEvent[] eventGridEvents = EventGridEvent.ParseMany(rawEvents); foreach (EventGridEvent evt in eventGridEvents) { if (evt.TryGetSystemEventData(out object eventData)) { if (eventData is SubscriptionValidationEventData validationData) { var responseData = new { ValidationResponse = validationData.ValidationCode }; var response = req.CreateResponse(HttpStatusCode.OK); response.WriteAsJsonAsync(responseData).Wait(); Log.LogInformation("Validation Complete"); return response; } else { RelayEvent(req); } } } var emptyResponse = req.CreateResponse(HttpStatusCode.OK); emptyResponse.WriteStringAsync(string.Empty).Wait(); return emptyResponse; }
方案2:切换到In-Process模型
如果希望继续使用IActionResult,可以将项目切换为In-Process模型:
- 修改项目文件(.csproj)的
TargetFramework为.NET 6或更低版本 - 设置
<AzureFunctionsVersion>为v4 - 移除Isolated相关NuGet包,添加
Microsoft.NET.Sdk.Functions包
内容的提问来源于stack exchange,提问作者Jonathon Anderson
相关产品推荐
相关产品推荐

