Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

queryParameters 不支持数组 #734

Closed
MinuteReversal opened this issue Apr 9, 2020 · 3 comments
Closed

queryParameters 不支持数组 #734

MinuteReversal opened this issue Apr 9, 2020 · 3 comments

Comments

@MinuteReversal
Copy link

MinuteReversal commented Apr 9, 2020

https://github.com/flutterchina/dio#request-options
帮助文档上是说可以传入Iterable
以下为dio调用

///从标签下删除用户
Future<void> labelMgtDeleteUsersFromLabel(int labelId,List userIds) async {
   await dio.delete(labelMgtDeleteUsersFromLabelUrl,queryParameters:{'labelId':labelId,'userIds':userIds});
}

调用上面的删除用户业务

test(
  '批量删除',
  () async {
    await labelMgtDeleteUsersFromLabel(20, ['3', '5']);
  },
  timeout: Timeout.none,
);

服务器没有接收到数组参数userIds。

{"input":{"labelId":20,"userIds":[]}}

服务器要求数组的querystring的格式如下

qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'

请实现数组序列化为querystring,实现标准可以参考qs库。
qs库地址如下,详见arrayFormat。可以使用ctrl+F查找arrayFormat。
https://www.npmjs.com/package/qs

@MinuteReversal
Copy link
Author

需要替换 RequestOptions

代码如下:

import 'package:dio/dio.dart';

const serverAddress = 'http://your.server.address:prot';

///fix query string
class FixQueryStringRequestOptions extends RequestOptions {
  FixQueryStringRequestOptions({
    String method,
    int sendTimeout,
    int receiveTimeout,
    int connectTimeout,
    dynamic data,
    String path,
    Map<String, dynamic> queryParameters,
    String baseUrl,
    void Function(int, int) onReceiveProgress,
    void Function(int, int) onSendProgress,
    CancelToken cancelToken,
    Map<String, dynamic> extra,
    Map<String, dynamic> headers,
    ResponseType responseType,
    String contentType,
    ValidateStatus validateStatus,
    bool receiveDataWhenStatusError = true,
    bool followRedirects = true,
    int maxRedirects,
    RequestEncoder requestEncoder,
    ResponseDecoder responseDecoder,
  }) : super(
          method: method,
          sendTimeout: sendTimeout,
          receiveTimeout: receiveTimeout,
          connectTimeout: connectTimeout,
          data: data,
          path: path,
          queryParameters: queryParameters,
          baseUrl: baseUrl,
          onReceiveProgress: onReceiveProgress,
          onSendProgress: onSendProgress,
          cancelToken: cancelToken,
          extra: extra,
          headers: headers,
          responseType: responseType,
          contentType: contentType,
          validateStatus: validateStatus,
          receiveDataWhenStatusError: receiveDataWhenStatusError,
          followRedirects: followRedirects,
          maxRedirects: maxRedirects,
          requestEncoder: requestEncoder,
          responseDecoder: responseDecoder,
        );

  /// here is important
  ///
  ///
  @override
  Uri get uri {
    final Uri _url = Uri.parse(baseUrl + path);

    return new Uri(
      scheme: _url.scheme,
      host: _url.host,
      port: _url.port,
      path: _url.path,
      queryParameters: queryParameters, //use Uri default querystring serializer
    );
  }
}

/// convert all value to string type
///
///
_convertQueryParameters(Map<String, dynamic> parameters) {
  final Map<String, dynamic> queryParams = new Map<String, dynamic>();
  parameters.forEach((key, value) {
    if (value is List) {
      final List list = new List();
      for (final item in value) {
        list.add('$item');
      }
      queryParams[key] = list;
    } else {
      queryParams[key] = '$value';
    }
  });
  return queryParams;
}

/// global dio instance
final dio = new Dio(new BaseOptions(baseUrl: serverAddress))
  ..interceptors.add(
    InterceptorsWrapper(
      onRequest: (RequestOptions options) async {
        final fixOption = new FixQueryStringRequestOptions(
          method: options.method,
          sendTimeout: options.sendTimeout,
          receiveTimeout: options.receiveTimeout,
          connectTimeout: options.connectTimeout,
          data: options.data,
          path: options.path,
          queryParameters: _convertQueryParameters(options.queryParameters),
          baseUrl: options.baseUrl,
          onReceiveProgress: options.onReceiveProgress,
          onSendProgress: options.onSendProgress,
          cancelToken: options.cancelToken,
          extra: options.extra,
          headers: options.headers,
          responseType: options.responseType,
          contentType: options.contentType,
          validateStatus: options.validateStatus,
          receiveDataWhenStatusError: options.receiveDataWhenStatusError,
          followRedirects: options.followRedirects,
          maxRedirects: options.maxRedirects,
          requestEncoder: options.requestEncoder,
          responseDecoder: options.responseDecoder,
        );
        return fixOption; //continue
      },
      onResponse: (Response response) async {
        // Do something with response data
        return response; // continue
      },
      onError: (DioError e) async {
        // Do something with response error
        return e; //continue
      },
    ),
  );

docs
https://pub.dev/packages/dio#interceptors
https://github.com/flutterchina/dio/blob/master/dio/lib/src/options.dart

@ZhongXiaoHong
Copy link

#315 这个才是解决方案

@MinuteReversal
Copy link
Author

#315 这个才是解决方案

成功了,谢谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants