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

使用Rest API在Dynamics 365 Business Central创建Item遇400错误求助

Fixing "Does not support untyped value in non-open type" Error When Creating Items via Dynamics BC API

The error you're hitting stems from how Dynamics Business Central's OData API handles related entities like baseUnitOfMeasure and itemCategory—these are "non-open types" that won’t accept full nested objects. Instead, you need to use bound navigation property references to link to existing records in BC. Here’s how to fix this:

Root Cause

When you include the full baseUnitOfMeasure or itemCategory objects in your request body, the API interprets this as an attempt to pass an untyped value (or create a new related entity) rather than linking to an existing one. For pre-existing records, you must use the @odata.bind syntax to reference them directly.

Corrected Request Body

Replace your nested objects with @odata.bind pointers to the existing BC records. Here’s the adjusted request body:

{
  "number": "1896-S",
  "displayName": "ATHENS Desk",
  "type": "Inventory",
  "blocked": false,
  "baseUnitOfMeasure@odata.bind": "/unitOfMeasures('PCS')",
  "gtin": "",
  "itemCategory@odata.bind": "/itemCategories('TABLE')",
  "inventory": 0,
  "unitPrice": 1000.8,
  "priceIncludesTax": false,
  "unitCost": 780.7,
  "taxGroupCode": "FURNITURE"
}

Note: If constructing this in C#, make sure to escape single quotes inside the OData path (use \' or wrap the path in double quotes).

Adjust Your C# Code

Update your itemBodyValues to use these @odata.bind properties instead of nested objects. Here are two common approaches:

1. Using an Anonymous Object

var itemBodyValues = new {
    number = "1896-S",
    displayName = "ATHENS Desk",
    type = "Inventory",
    blocked = false,
    baseUnitOfMeasure@odata.bind = "/unitOfMeasures('PCS')",
    gtin = "",
    itemCategory@odata.bind = "/itemCategories('TABLE')",
    inventory = 0,
    unitPrice = 1000.8,
    priceIncludesTax = false,
    unitCost = 780.7,
    taxGroupCode = "FURNITURE"
};

string requestBody = JsonConvert.SerializeObject(itemBodyValues);

2. Using a Strongly-Typed Class

If you prefer a strongly-typed model, use JsonProperty attributes to map the bind properties correctly:

public class ItemRequest {
    public string number { get; set; }
    public string displayName { get; set; }
    public string type { get; set; }
    public bool blocked { get; set; }
    public string gtin { get; set; }
    public int inventory { get; set; }
    public double unitPrice { get; set; }
    public bool priceIncludesTax { get; set; }
    public double unitCost { get; set; }
    public string taxGroupCode { get; set; }

    [JsonProperty("baseUnitOfMeasure@odata.bind")]
    public string BaseUnitOfMeasureBind { get; set; }

    [JsonProperty("itemCategory@odata.bind")]
    public string ItemCategoryBind { get; set; }
}

// Usage
var itemBodyValues = new ItemRequest {
    number = "1896-S",
    displayName = "ATHENS Desk",
    type = "Inventory",
    blocked = false,
    BaseUnitOfMeasureBind = "/unitOfMeasures('PCS')",
    ItemCategoryBind = "/itemCategories('TABLE')",
    inventory = 0,
    unitPrice = 1000.8,
    priceIncludesTax = false,
    unitCost = 780.7,
    taxGroupCode = "FURNITURE"
};

string requestBody = JsonConvert.SerializeObject(itemBodyValues);

Why This Works

The @odata.bind syntax explicitly tells the BC API to link your new item to the existing unit of measure and item category records, rather than trying to process an unstructured object or create duplicate entities. This matches how BC’s OData API handles related entities for non-open types.

内容的提问来源于stack exchange,提问作者Muhammad Murad Haider

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:32:53