microsoft-dynamicsdynamics-365dynamics-business-centraldynamics-albusinesscentral

How to export images in Business Central via Web Services?


I'm trying to get my Business Central products images from another app, so I'm considering using a web service as the docs suggest Microsoft Doc.

I'm running in Postman this request:

https://api.businesscentral.dynamics.com/v2.0/de2fx7xx-a7e0-4fb8-8f39-215792c9xx53/Sandbox_PL/ODataV4/Company('Prueba%20Global%2C%20S.L.U.')/items('PL006001')/picture

(I've modified some digits for security purposes as I can't post it publicly)

I'm getting this error:

{
    "error": {
        "code": "BadRequest_NotFound",
        "message": "The URI segment 'picture' is invalid after the segment 'items('PL006001')'."
    }
}

So I guess the endpoint is not available? Let's confirm with another request:

https://api.businesscentral.dynamics.com/v2.0/de2fx7xx-a7e0-4fb8-8f39-215792c9xx53/Sandbox_PL/ODataV4/Company('Prueba%20Global%2C%20S.L.U.')/items

Response: 404 Not found

If the web service doesn't exist, let's create a new one pointing to item table:

page 60011 "MAG Item Image API"
{
    ApplicationArea = All;
    Caption = 'Item Image API';
    PageType = List;
    SourceTable = Item;
    UsageCategory = Administration;

    layout
    {
        area(content)
        {
            repeater(General)
            {
                field(ItemNo; Rec."No.")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the number of the item.';
                }                
                field(Picture; Rec.Picture)
                {
                    Caption = 'Picture';
                    ApplicationArea = All;
                    ToolTip = 'Representation of the first picture.';
                }
            }
        }
    }
}

This is what I get as response from the web service:

"value": [
        {
            "@odata.etag": "W/\"JzE5OzE4NjEzODI5Mjk5MDMxNTIyNDIxOzAwOyc=\"",
            "ItemNo": "PL006001"
        }
    ]

So, no picture... I've created a function to export the image in Base64 format and it's working but the picture size is increased and that is a problem and not possible be accepted as a solution (because it will be creating a new problem):

procedure ConvertMediaSetToBase64(): Text
var
    TenantMedia: Record "Tenant Media";
    Base64Convert: codeunit "Base64 Convert";
    InStream: InStream;
begin
    if Rec.Picture.Count() = 0 then
        exit('')
    else
        if TenantMedia.Get(Rec.Picture.Item(1)) then begin
            TenantMedia.CalcFields(Content);
            if TenantMedia.Content.HasValue() then begin
                TenantMedia.Content.CreateInStream(InStream, TextEncoding::Windows);
                exit(Base64Convert.ToBase64(InStream));
            end;
        end;
    
    exit('');
end;

How I can export images without ending up with a bigger image than the original?


Solution

  • Web Services is an old method for exposing objects from Business Central through the SOAP or OData protocols. Basically the platform tries to generate a valid API based on e.g. a page (which is an UI element). This means that there are some limitations as to what is possible or not.

    I suggest you use the new API endpoints instead. Here you have both an API for Items and their pictures available out of the box.

    Based on your example the endpoint for a specific items picture should look like this:

    https://api.businesscentral.dynamics.com/v2.0/de2fx7xx-a7e0-4fb8-8f39-215792c9xx53/Sandbox_PL/api/v2.0/companies({{Company Id}})/items({{Item Id}})/picture/pictureContent
    

    If you want to get the pictures for all items you will need to first get the items with the picture property expanded and then get the pictures as described above:

    https://api.businesscentral.dynamics.com/v2.0/de2fx7xx-a7e0-4fb8-8f39-215792c9xx53/Sandbox_PL/api/v2.0/companies({{Company Id}})/items({{Item Id}})?expand=picture