You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

查询Durable Entity状态时Http函数崩溃如何返回JSON

问题背景

我是Azure Functions与Durable Entities的初学者,计划实现以下功能:

  • 创建一个持久实体,其包含名为systemList的状态
  • 创建队列触发器函数消费队列内的消息,并将消息存储到前述创建的实体状态中
  • 创建Http触发器函数获取实体的当前状态

我在实现第三步时遇到问题:本地运行发送Http查询请求时程序直接停止运行,但把返回行从直接返回stateResponse.EntityState改成拼接空字符串后程序可以正常返回字符串,但我需要返回标准JSON格式响应。


问题相关代码

HttpTriggerFunction.cs

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using System.Net.Http;
using System.Net;
using Newtonsoft.Json.Linq;

namespace **.Function
{
    public static class HttpTriggerQueryEntity
    {
        [FunctionName("QueryEntity")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function)] HttpRequestMessage req,
            [DurableClient] IDurableEntityClient client)
        {
            var entityId = new EntityId(nameof(ProcessingListEntity), "processing_message_total");
            EntityStateResponse<JObject> stateResponse = await client.ReadEntityStateAsync<JObject>(entityId);
           
            //await client.SignalEntityAsync(entityId, "Empty");

            return req.CreateResponse(HttpStatusCode.OK,stateResponse.EntityState);
        }
    }
}

blockData.cs

#nullable enable
using System;

namespace **.Function
{
    public class BlockData
    {
        public string? id { get; set; }
        public string? SessionId { get; set; }
        public string? MachineId { get; set; }
        public DateTime? Start { get; set; }
        public DateTime? End { get; set; }
        public string? Activity {get; set;}
        public string? BlobId { get; set; }
    }
}

Entity.cs

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using System.Collections.Generic;
namespace **.Function
{
    [JsonObject(MemberSerialization.OptIn)]
    public class ProcessingListEntity
    {
        public ProcessingListEntity(){
            systemList = new Dictionary<string, BlockData>();
        }

        [JsonProperty("systemList")]
        public Dictionary<string, BlockData> systemList {get; set;}

        public void Add(BlockData blockData) {

            if (!this.systemList.ContainsKey(blockData.MachineId)) {
                this.systemList.Add(blockData.MachineId, blockData);
                return;
            }
            else {
                this.systemList[blockData.MachineId].Start = blockData.Start;
                this.systemList[blockData.MachineId].End = blockData.End;
            }
            
        }

        public void Empty() => this.systemList = new Dictionary<string, BlockData>();

        public Dictionary<string, BlockData> Get() => this.systemList;

        [FunctionName(nameof(ProcessingListEntity))]
        public static Task Run([EntityTrigger] IDurableEntityContext ctx)
            => ctx.DispatchAsync<ProcessingListEntity>();
    }
}

问题复现

直接运行时,使用如下返回代码会导致程序崩溃停止:

return req.CreateResponse(HttpStatusCode.OK,stateResponse.EntityState);

将代码修改为如下内容后程序可正常运行,但返回的是普通字符串,不符合JSON返回要求:

return req.CreateResponse(HttpStatusCode.OK,stateResponse.EntityState + "");

修复方案

问题核心是读取实体状态时使用了错误的泛型类型,且返回时未明确指定JSON序列化格式,按以下步骤修改即可:

  1. 不要用JObject作为ReadEntityStateAsync的泛型参数,直接使用定义的实体强类型ProcessingListEntity读取状态,避免跨序列化器类型不匹配导致的崩溃
  2. 返回响应时明确指定application/json媒体类型,确保返回标准JSON格式
  3. 增加实体存在性判断,避免实体未初始化时触发空引用异常

修改后的HttpTriggerFunction.cs代码如下:

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using System.Net.Http;
using System.Net;
using System.Net.Http.Formatting;

namespace **.Function
{
    public static class HttpTriggerQueryEntity
    {
        [FunctionName("QueryEntity")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function)] HttpRequestMessage req,
            [DurableClient] IDurableEntityClient client)
        {
            var entityId = new EntityId(nameof(ProcessingListEntity), "processing_message_total");
            // 使用强类型读取实体状态
            EntityStateResponse<ProcessingListEntity> stateResponse = await client.ReadEntityStateAsync<ProcessingListEntity>(entityId);
            
            // 实体不存在时返回404
            if (!stateResponse.EntityExists)
            {
                return req.CreateResponse(HttpStatusCode.NotFound, new { error = "Entity not found" }, JsonMediaTypeFormatter.DefaultMediaType);
            }

            // 明确指定返回JSON格式
            return req.CreateResponse(HttpStatusCode.OK, stateResponse.EntityState, JsonMediaTypeFormatter.DefaultMediaType);
        }
    }
}

补充说明:之前拼接空字符串能正常运行,是因为JObject拼接字符串时会隐式调用ToString()输出JSON字符串,但Azure Functions默认序列化器处理JObject类型时会出现序列化配置不匹配、循环引用等问题,直接导致宿主进程崩溃,使用强类型读取+明确指定JSON媒体类型可以完全规避这个问题。


内容的提问来源于stack exchange,提问作者superDu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:31:00