postFilesWithRequestAs<T> method

Future<T> postFilesWithRequestAs<T>(
  1. String requestUri,
  2. dynamic request,
  3. List<UploadFile> files, {
  4. T? responseAs,
  5. RequestFilter? requestFilter,
  6. ResponseFilter? responseFilter,
})

Posts files with a request DTO using multipart/form-data

requestUri The request URI request The request DTO files List of file upload entries. Each entry should be a Map with:

  • 'fieldName': String (optional, defaults to 'upload')
  • 'fileName': String
  • 'stream': List
  • 'contentType': String (optional, defaults to 'application/octet-stream') responseAs Optional type to deserialize response as

Implementation

Future<T> postFilesWithRequestAs<T>(
    String requestUri,
    dynamic request,
    List<UploadFile> files, {
      T? responseAs,
      RequestFilter? requestFilter,
      ResponseFilter? responseFilter,
    }) async {
  var uri = createUri(toAbsoluteUrl(requestUri))!;
  var req = await client.postUrl(uri);

  // Set up multipart request
  var boundary = _generateBoundary();
  req.headers.set(HttpHeaders.contentTypeHeader,
      'multipart/form-data; boundary=$boundary');

  if (bearerToken != null) {
    req.headers.add(HttpHeaders.authorizationHeader, 'Bearer $bearerToken');
  }

  // Add other headers
  headers.forEach((key, val) {
    if (key != HttpHeaders.contentTypeHeader) {
      req.headers.add(key, val);
    }
  });

  // Create multipart output stream
  var output = BytesBuilder();

  // Convert request to map and add each field as a separate multipart field
  var requestMap = toMap(request);
  if (requestMap != null && requestMap.isNotEmpty) {
    for (var entry in requestMap.entries) {
      if (entry.value != null) {
        // Convert value to JSON string and remove quotes for simple values
        var valueJson = json.encode(entry.value);
        var value = (entry.value is String || entry.value is num || entry.value is bool) && valueJson.contains('"')
            ? valueJson.substring(1, valueJson.length - 1)  // Remove quotes for simple types
            : valueJson;  // Keep full JSON for complex types

        _writeMultipartField(
            output,
            boundary,
            entry.key,
            utf8.encode(value),
            'text/plain; charset=utf-8'
        );
      }
    }
  }

  // Add each file
  for (var file in files) {
    var fieldName = file.fieldName ?? 'upload';
    var fileName = file.fileName!;
    var contentType = file.contentType ?? 'application/octet-stream';
    var fileData = file.contents ?? Uint8List(0);

    _writeMultipartFile(output, boundary, fieldName, fileName, fileData, contentType);
  }

  // Write final boundary
  output.add(utf8.encode('--$boundary--\r\n'));

  // Set content length and write body
  var body = output.takeBytes();
  req.contentLength = body.length;
  req.add(body);

  // Apply request filters
  if (requestFilter != null) requestFilter(req);
  if (this.requestFilter != null) this.requestFilter!(req);
  if (globalRequestFilter != null) globalRequestFilter!(req);

  // Send request and handle response
  try {
    var res = await req.close();
    var response = await createResponse<T>(
        res,
        SendContext(
            method: 'POST',
            request: request,
            responseAs: responseAs,
            responseFilter: responseFilter));
    return response!;
  } on Exception catch (e) {
    return await handleError(null, e);
  }
}