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

Flutter中如何通过POST方法发送多类型必填参数数据

Flutter POST API 多类型参数提交失败问题

问题描述

在Flutter中调用POST API提交数据时遇到问题,需发送包含list、string、int、datetime等多种数据类型的必填参数(服务器要求所有字段不可为null)。仅发送字符串参数时能正常运行,但多类型参数提交时出现错误,至今未找到解决办法。

错误截图

请求失败截图:
请求更新数据失败

API文档截图:
POST API 定义

相关代码

sendBiodata 方法代码

Future<UserBiodata> sendBiodata(
    String? stAgama,
    // List<Agama>? agama,
    String? stKwn,
    // List<Kwn>? kwn,
    String? tempat,
    String? tglLahir,
    String? nik,
    String? nisn,
    String? npwp,
    String? jalan,
    String? stProv,
    // List<Province>? province,
    String? stKab,
    // List<Province>? kab,
    String? stKec,
    // List<Province>? kec,
    String? desa,
    String? dusun,
    String? rt,
    String? rw,
    String? kodePos,
    dynamic telp,
    String? email,
    String kps,
    String? stTrans,
    // List<Trans>? trans,
    String? stJn,
    // List<Jn>? jn,
    String? ipk,
    // int? smt,
    String? namaAyah,
    String? nikAyah,
    String? tglLahirAyah,
    String? stPendidikanAyah,
    // List<PendidikanAyah>? pendidikanAyah,
    String? pekerjaanAyah,
    String? penghasilanAyah,
    String? namaIbu,
    String? nikIbu,
    String? tglLahirIbu,
    String? stPendidikanIbu,
    // List<PendidikanIbu>? pendidikanIbu,
    String? pekerjaanIbu,
    String? penghasilanIbu,
    String? namaWali,
    String? nikWali,
    String? tglLahirWali,
    String? stPendidikanWali,
    // List<PendidikanWali>? pendidikanWali,
    String? pekerjaanWali,
    String? penghasilanWali,
  ) async {
    String url = Constant.baseURL;
    String token = await UtilSharedPreferences.getToken();
    final response = await http.post(
      Uri.parse(
        '$url/auth/mhs_siakad/biodata/update',
      ),
      headers: <String, String>{
        'Authorization': 'Bearer $token',
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode<String, dynamic>({
        "st_agama": stAgama,
        // 'agama': agama,
        'st_kwn': stKwn,
        // 'kwn': kwn,
        "tempat": tempat,
        "tgl_lahir": tglLahir,
        "nik": nik,
        "nisn": nisn,
        "npwp": npwp,
        "jalan": jalan,
        "st_prov": stProv,
        // 'province': province,
        "st_kab": stKab,
        // 'kab': kab,
        "st_kec": stKec,
        // 'kec': kec,
        "desa": desa,
        "dusun": dusun,
        "rt": rt,
        "rw": rw,
        "kode_pos": kodePos,
        "telp": telp,
        "email": email,
        "kps": kps,
        "st_trans": stTrans,
        // 'trans': trans,
        "st_jn": stJn,
        // "jn": jn,
        "ipk": ipk,
        // "smt": smt,
        "nama_ayah": namaAyah,
        "nik_ayah": nikAyah,
        "tgl_lahir_ayah": tglLahirAyah,
        "st_pendidikan_ayah": stPendidikanAyah,
        // "pendidikan_ayah": pendidikanAyah,
        "pekerjaan_ayah": pekerjaanAyah,
        "penghasilan_ayah": penghasilanAyah,
        "nama_ibu": namaIbu,
        "nik_ibu": nikIbu,
        "tgl_lahir_ibu": tglLahirIbu,
        "st_pendidikan_ibu": stPendidikanIbu,
        // "pendidikan_ibu": pendidikanIbu,
        "pekerjaan_ibu": pekerjaanIbu,
        "penghasilan_ibu": penghasilanIbu,
        "nama_wali": namaWali,
        "nik_wali": nikWali,
        "tgl_lahir_wali": tglLahirWali,
        "st_pendidikan_wali": stPendidikanWali,
        // "pendidikan_wali": pendidikanWali,
        "pekerjaan_wali": pekerjaanWali,
        "penghasilan_wali": penghasilanWali,
      }),
    );

    print(response.statusCode);
    print(response.body);

    if (response.statusCode == 201) {
      return UserBiodata.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed update data!');
    }
  }

提交按钮代码

Center(
          child: ElevatedButton(
            onPressed: () {
              setState(() {
                _futureBiodata = BiodataProvider().sendBiodata(
                  _controllerAgama.text,
                  // _controller2.text as List<Agama>?,
                  _controllerKwn.text,
                  // _controller4.text as List<Kwn>?,
                  _controllerTmtLahir.text,
                  _controllerTglLahir.text,
                  _controllerNik.text,
                  _controllerNisn.text,
                  _controllerNpwp.text,
                  _controllerAlamat.text,
                  _controllerProv.text,
                  // _controller12.text as List<Province>?,
                  _controllerKab.text,
                  // _controller14.text as List<Province>?,
                  _controllerKec.text,
                  // _controller16.text as List<Province>?,
                  _controllerKel.text,
                  _controllerDusun.text,
                  _controllerRt.text,
                  _controllerRw.text,
                  _controllerKdPos.text,
                  _controllerNoHp.text,
                  _controllerEmail.text,
                  _controllerKps.text,
                  _controllerNoKps.text,
                  // _controller26.text as List<Trans>?,
                  _controllerTrans.text,
                  // _controller28.text as List<Jn>?,
                  _controllerJnsTinggal.text,
                  // _controller30.text as int?,
                  _controllerNmAyah.text,
                  _controllerNikAyah.text,
                  _controllerTglLhrAyah.text,
                  _controllerPendidikanAyah.text,
                  // _controller35.text as List<PendidikanAyah>?,
                  _controllerPekerjaanAyah.text,
                  _controllerPenghasilanAyah.text,
                  _controllerNmIbu.text,
                  _controllerNikIbu.text,
                  _controllerTglLhrIbu.text,
                  _controllerPekerjaanIbu.text,
                  // _controller42.text as List<PendidikanIbu>?,
                  _controllerPekerjaanIbu.text,
                  _controllerPenghasilanIbu.text,
                  _controllerNmWali.text,
                  _controllerNikWali.text,
                  _controllerTglLhrWali.text,
                  _controllerPendidikanWali.text,
                  // _controller49.text as List<PendidikanWali>?,
                  _controllerPekerjaanWali.text,
                  _controllerPekerjaanWali.text,
                );
              });
            },
            child: const Text('Update Data'),
          ),
        ),

解决方案

1. 强制参数非空

服务器要求所有字段不可为null,当前代码中大部分参数为String?类型,存在提交null值的风险:

  • 将必填参数的类型从String?改为String,强制调用方传入非空值
  • 提交前对所有文本控制器做非空校验,比如if(_controllerAgama.text.isEmpty) return;,避免空字符串提交

2. 修正数据类型匹配

  • telp字段:若服务器要求int类型,需将控制器的字符串转换为整数:int.parse(_controllerNoHp.text),注意捕获转换异常
  • ipk字段:若服务器要求数字类型(float/double),执行double.parse(_controllerIpk.text)转换
  • 日期字段:确保tgl_lahir等字段格式与服务器要求一致(如yyyy-MM-dd),若控制器格式不符,先通过DateFormat类转换

3. 修复按钮参数顺序错误

查看按钮调用sendBiodata的代码,存在参数重复传入的问题:

_controllerPekerjaanIbu.text,
// _controller42.text as List<PendidikanIbu>?,
_controllerPekerjaanIbu.text, // 此处应为_controllerPendidikanIbu.text

参数顺序必须与方法定义完全一致,否则会导致字段值错位,触发服务器校验失败

4. 处理List类型参数

若需要提交注释掉的List参数(如agama、province):

  • 确认服务器期望的List结构:是ID数组还是对象数组
  • 若为ID数组,拆分控制器文本并转换:_controllerAgama.text.split(',').map(int.parse).toList()
  • 若为对象数组,将选中的选项转换为对应实体类的JSON格式后传入

5. 调试优化

在jsonEncode前打印请求体,检查是否存在null值或类型不匹配:

final requestBody = {
  // 所有字段
};
print('Request Body: $requestBody');
body: jsonEncode(requestBody),

查看response.body的具体错误信息,服务器通常会返回字段校验失败的详情,根据提示针对性修正


内容的提问来源于stack exchange,提问作者Meikisihka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:25:02