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

Business Central中Postman提交Blob(JSON子类型)数据报错求助

Business Central API Blob(JSON)字段流未关闭错误排查与解决方案

问题概述

在Business Central中创建了包含Blob(JSON子类型)字段的表sch_schedulerconfiguration,通过Postman向其API端点提交数据时,收到错误:"Read called with an open stream or text reader..."。

  • 请求地址:https://api.businesscentral.dynamics.com/v2.0/{TenantID}/Sandbox/api/CJAPI/CJG/v1.0/companies({CompanyID})/sch_schedulerconfiguration
  • 请求体包含sch_bookingform、sch_hoverdetails、sch_popupdetails等Blob字段的JSON字符串

现有实现

  • 表中Blob字段配置了OnValidate触发器,用于检查值是否存在
  • Codeunit SchedulerConfigurationHandler包含WriteJSONToBlob和ReadJSONFromBlob方法,处理流的读写操作
  • API Page schedulerconfiguration将该表暴露为API端点

1. 错误原因排查

错误核心是流资源未正确释放,常见触发场景:

  • 自定义流处理方法(WriteJSONToBlob/ReadJSONFromBlob)中,打开的InStream/OutStream未调用Close()方法,也未用with语句自动回收资源,导致流长期处于打开状态,与API的后续读取操作冲突
  • OnValidate触发器中直接操作流但未关闭,导致API处理时流被占用
  • API Page中Blob字段的类型映射错误,未正确适配JSON子类型的序列化逻辑,引发流生命周期管理异常

2. API处理Blob(JSON)字段的正确方式

  • 优先使用Business Central原生的**Blob(JSON子类型)**支持:该类型可直接存储JSON数据,API会自动完成序列化/反序列化,无需手动处理流
  • 若必须自定义流操作,需保证流操作的原子性:打开流→完成读写→立即关闭,禁止跨操作保持流打开
  • API Page中需明确Blob字段的DataType=Blob、SubType=JSON,确保API识别其JSON属性

3. 现有实现修改方案

方案1:移除自定义流处理,使用原生Blob(JSON)支持(推荐)

此方案最简洁,利用BC原生能力避免流管理问题:

  1. 表字段配置:保持Blob类型,SubType设为JSON
  2. 修改OnValidate触发器:直接检查Blob大小,无需操作流
    trigger OnValidate()
    begin
        if Rec."sch_bookingform".Size = 0 then
            Error('Booking form JSON cannot be empty');
    end;
    
  3. API Page字段定义:
    field(sch_bookingform; Rec."sch_bookingform")
    {
        Caption = 'Booking Form';
        DataType = Blob;
        SubType = JSON;
    }
    
  4. Postman请求体格式:直接提交JSON对象(无需转成字符串)
    {
        "sch_bookingform": {
            "field1": "value1",
            "field2": "value2"
        },
        "sch_hoverdetails": {"key": "value"},
        "sch_popupdetails": {"key": "value"}
    }
    

方案2:保留自定义流处理,修复流生命周期

若需保留原有流处理逻辑,需强制保证流的关闭:

  1. 修改流处理方法:
    procedure WriteJSONToBlob(var BlobField: Blob; JSONText: Text)
    var
        OutStream: OutStream;
    begin
        BlobField.CreateOutStream(OutStream);
        OutStream.WriteText(JSONText);
        OutStream.Close(); // 必须显式关闭流
    end;
    
    procedure ReadJSONFromBlob(var BlobField: Blob): Text
    var
        InStream: InStream;
        JSONText: Text;
    begin
        BlobField.CreateInStream(InStream);
        InStream.ReadText(JSONText);
        InStream.Close(); // 必须显式关闭流
        exit(JSONText);
    end;
    
  2. API Page添加计算字段:暴露字符串格式的JSON供API调用,避免直接操作Blob流
    field(sch_bookingform_text; GetBookingFormJSON())
    {
        Caption = 'Booking Form JSON';
        DataType = Text;
        Editable = true;
    }
    
    local procedure GetBookingFormJSON(): Text
    var
        SchedulerConfigHandler: Codeunit SchedulerConfigurationHandler;
    begin
        exit(SchedulerConfigHandler.ReadJSONFromBlob(Rec."sch_bookingform"));
    end;
    
    trigger OnModify()
    var
        SchedulerConfigHandler: Codeunit SchedulerConfigurationHandler;
    begin
        if Rec."sch_bookingform_text" <> '' then
            SchedulerConfigHandler.WriteJSONToBlob(Rec."sch_bookingform", Rec."sch_bookingform_text");
    end;
    
  3. Postman请求体格式:提交转义后的JSON字符串
    {
        "sch_bookingform_text": "{\"field1\":\"value1\",\"field2\":\"value2\"}",
        "sch_hoverdetails_text": "{\"key\":\"value\"}",
        "sch_popupdetails_text": "{\"key\":\"value\"}"
    }
    

验证步骤

  1. 用Postman发送POST请求,确认错误消失
  2. 调用GET API验证Blob字段的JSON数据正确返回
  3. 查看Business Central表中数据存储正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:03:26