Universal http SendRequest() method. Multipart form data.

 procedure SendRequest(contentToSend: Variant; RequestMethod: enum "Http Request Type"; requestUri: Text; ContentType: Text; HttpTimeout: integer; var ResponseValue: Codeunit "Temp Blob"; DictionaryContentHeaders: Codeunit "Dictionary Wrapper"; DictionaryDefaultHeaders: Codeunit "Dictionary Wrapper")

var Client: HttpClient; Request: HttpRequestMessage; Response: HttpResponseMessage; ContentHeaders: HttpHeaders; Content: HttpContent; ErrorBodyContent: Text; TextContent: Text; InStreamContent: InStream; InStreamRepsonse: InStream; OutStreamResponse: OutStream; i: Integer; KeyVariant: Variant; ValueVariant: Variant; HasContent: Boolean; begin case true of contentToSend.IsText(): begin TextContent := contentToSend; if TextContent <> '' then begin Content.WriteFrom(TextContent); HasContent := true; end; end; contentToSend.IsInStream(): begin InStreamContent := contentToSend; Content.WriteFrom(InStreamContent); HasContent := true; end; else Error(UnsupportedContentToSendErr); end; if HasContent then Request.Content := Content; if ContentType <> '' then begin ContentHeaders.Clear(); Request.Content.GetHeaders(ContentHeaders); if ContentHeaders.Contains(ContentTypeKeyLbl) then ContentHeaders.Remove(ContentTypeKeyLbl); ContentHeaders.Add(ContentTypeKeyLbl, ContentType); end; for i := 0 to DictionaryContentHeaders.Count() do if DictionaryContentHeaders.TryGetKeyValue(i, KeyVariant, ValueVariant) then ContentHeaders.Add(Format(KeyVariant), Format(ValueVariant)); Request.SetRequestUri(requestUri); Request.Method := Format(RequestMethod); for i := 0 to DictionaryDefaultHeaders.Count() do if DictionaryDefaultHeaders.TryGetKeyValue(i, KeyVariant, ValueVariant) then Client.DefaultRequestHeaders.Add(Format(KeyVariant), Format(ValueVariant)); if HttpTimeout <> 0 then Client.Timeout(HttpTimeout); Client.Send(Request, Response); ResponseValue.CreateInStream(InStreamRepsonse); ResponseValue.CreateOutStream(OutStreamResponse); Response.Content().ReadAs(InStreamRepsonse); if not Response.IsSuccessStatusCode() then begin Response.Content().ReadAs(ErrorBodyContent); Error(RequestErr, Response.HttpStatusCode(), ErrorBodyContent); end; CopyStream(OutStreamResponse, InStreamRepsonse); //Save data to TempBlob end; var RequestErr: Label 'Request failed with HTTP Code:: %1 Request Body:: %2', Comment = '%1 = HttpCode, %2 = RequestBody'; UnsupportedContentToSendErr: Label 'Unsuportted content to sned.'; ContentTypeKeyLbl: Label 'Content-Type', Locked = true;

First of all, I want to note that Microsoft has recently updated the documentation for HTTP data types. I recommend you take a look at this and that. I want to focus on multipart form data and how we can work with it in Business Central. Let's delve into what multipart content-type is: https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html Also, check about multipart/form-data: https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4 In summary, multipart/form-data is used to send one or multiple files in a request, or to send a single file in parts. I will provide an example of sending multiple files using multipart/form-data content type in Business Central:

var APIMgt: Codeunit "FOD API Mgt"; ResponseData: Codeunit "Temp Blob"; FileInStream: InStream; FormData: TextBuilder; Boundary: Text; TextBuffer: Text; begin Boundary := Format(CreateGuid(), 0, 3); FormData.AppendLine(StrSubstNo('--%1', Boundary)); FormData.AppendLine('Content-Disposition: form-data; name=foo1;'); FormData.AppendLine('Content-Type: text/plain'); FormData.AppendLine(''); FormData.AppendLine('bar1'); FormData.AppendLine(StrSubstNo('--%1', Boundary)); FormData.AppendLine('Content-Disposition: form-data; name=foo2;'); FormData.AppendLine('Content-Type: text/plain'); FormData.AppendLine(''); FormData.AppendLine('bar2'); FormData.AppendLine(StrSubstNo('--%1--', Boundary)); FormData.AppendLine(''); APIMgt.SendRequest(FormData.ToText(), Enum::"Http Request Type"::POST, 'https://postman-echo.com/post', StrSubstNo('multipart/form-data; boundary=%1', Boundary), ResponseData);

No comments:

Post a Comment