Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Flatter和php创建用户登录时解析json数据的类型错误_Json_Flutter_Dart - Fatal编程技术网

使用Flatter和php创建用户登录时解析json数据的类型错误

使用Flatter和php创建用户登录时解析json数据的类型错误,json,flutter,dart,Json,Flutter,Dart,我正在尝试在php中使用flatter和backend创建一个用户登录。但是,当登录有效时,在获取json数据时,flatter显示错误:“type'\u OneByteString'不是int类型的子类型”。但是,当错误的电子邮件或密码没有出现错误时,屏幕上会显示Snackbar,但progressIndicator会无限期地显示。我无法理解这个问题,因为在这两种情况下字符串都返回为Status。请帮帮我。我被困在这里两天了。这是我的颤振代码: Future<Login> use

我正在尝试在php中使用flatter和backend创建一个用户登录。但是,当登录有效时,在获取json数据时,flatter显示错误:“type'\u OneByteString'不是int类型的子类型”。但是,当错误的电子邮件或密码没有出现错误时,屏幕上会显示Snackbar,但progressIndicator会无限期地显示。我无法理解这个问题,因为在这两种情况下字符串都返回为Status。请帮帮我。我被困在这里两天了。这是我的颤振代码:

 Future<Login> userLogin(String email, String password) async {
 Map<String, dynamic> map = {'email': email, 'password': password};

  final http.Response response = await http.post(
  'my php page',
  headers: <String, String>{
    'Content-Type': 'application/json; charset=UTF-8',
  },
  body: jsonEncode(map),
);

 if (response.statusCode == 201 || response.statusCode == 200) {
   return Login.fromJson(json.decode(response.body));
 } else {
   throw Exception('Failed to login.');
 }
}

 class Login {
  final int usrid;
  //final String usrname;
  final String status;

  Login({this.usrid, this.status});

  factory Login.fromJson(Map<String, dynamic> json) {
  return Login(usrid: json['usrid'], status: json['type']);
 }
 }

 class TextControl extends StatefulWidget {
   TextControl({Key key}) : super(key: key);
   @override
   State<StatefulWidget> createState() {
   return _TextControl();
  }
 }

 class _TextControl extends State<TextControl> {
   final _formKey = GlobalKey<FormState>();
   final TextEditingController _controller = TextEditingController();
   final TextEditingController _controller2 = TextEditingController();

 @override
 void dispose() {
  // Clean up the controller when the widget is disposed.
  _controller.dispose();
  _controller2.dispose();
  super.dispose();
 }

Future<Login> _futureLogin;
 @override
 Widget build(BuildContext context) {
 return Form(
  key: _formKey,
  child: (_futureLogin == null)
      ? Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            TextFormField(
              controller: _controller,
              decoration: InputDecoration(hintText: 'Email'),
              keyboardType: TextInputType.emailAddress,
              validator: (value) {
                if (value.isEmpty || !value.isValidEmail()) {
                  return 'Please enter valid email.';
                }
                return null;
              },
            ),
            TextFormField(
              controller: _controller2,
              decoration: InputDecoration(hintText: 'Password'),
              obscureText: true,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter password.';
                }
                return null;
              },
            ),
            Container(
              margin: EdgeInsets.all(10.0),
              child: RaisedButton(
                color: Colors.purple[400],
                textColor: Colors.white,
                onPressed: () {
                  if (_formKey.currentState.validate()) {
                    setState(() {
                      _futureLogin =
                          userLogin(_controller.text, _controller2.text);
                    });
                  }
                },
                child: Text('Login', style: TextStyle(fontSize: 18.0)),
              ),
            ),
          ],
        )
      : FutureBuilder<Login>(
          future: _futureLogin,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              //return Text(snapshot.data.usrname);
              if (snapshot.data.status == '1') {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => TextInput()),
                );
              } else if (snapshot.data.status == '2') {
                Scaffold.of(context).showSnackBar(
                    SnackBar(content: Text('Invalid login credentials.')));
              }
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            return Center(child: CircularProgressIndicator());
          },
        ),
    );
   }
  }
未来用户登录(字符串电子邮件、字符串密码)异步{
Map Map={'email':email,'password':password};
final http.Response Response=wait http.post(
“我的php页面”,
标题:{
“内容类型”:“应用程序/json;字符集=UTF-8”,
},
正文:JSONECODE(map),
);
如果(response.statusCode==201 | | response.statusCode==200){
返回Login.fromJson(json.decode(response.body));
}否则{
抛出异常('登录失败');
}
}
类登录{
最后一次国际会议;
//最终字符串usrname;
最终字符串状态;
登录名({this.usrid,this.status});
factory Login.fromJson(映射json){
返回登录名(usrid:json['usrid'],状态:json['type']);
}
}
类TextControl扩展StatefulWidget{
TextControl({Key}):super(Key:Key);
@凌驾
状态createState(){
返回_TextControl();
}
}
类_TextControl扩展状态{
final _formKey=GlobalKey();
最终文本编辑控制器_控制器=文本编辑控制器();
最终文本编辑控制器_controller2=文本编辑控制器();
@凌驾
无效处置(){
//处置小部件时清理控制器。
_controller.dispose();
_控制器2.dispose();
super.dispose();
}
未来登录;
@凌驾
小部件构建(构建上下文){
报税表(
键:_formKey,
子项:(_futureLogin==null)
?立柱(
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
TextFormField(
控制器:_控制器,
装饰:输入装饰(hintText:“电子邮件”),
键盘类型:TextInputType.emailAddress,
验证器:(值){
if(value.isEmpty | |!value.isValidEmail()){
返回“请输入有效电子邮件”;
}
返回null;
},
),
TextFormField(
控制器:_控制器2,
装饰:输入装饰(hintText:“密码”),
蒙昧文字:对,
验证器:(值){
if(value.isEmpty){
返回“请输入密码”;
}
返回null;
},
),
容器(
保证金:所有边缘套(10.0),
孩子:升起按钮(
颜色:颜色。紫色[400],
textColor:Colors.white,
已按下:(){
if(_formKey.currentState.validate()){
设置状态(){
_未来登录=
用户登录(_controller.text,_controller2.text);
});
}
},
子项:文本('Login',样式:TextStyle(fontSize:18.0)),
),
),
],
)
:未来建设者(
未来:_futureLogin,
生成器:(上下文,快照){
if(snapshot.hasData){
//返回文本(snapshot.data.usrname);
如果(snapshot.data.status==“1”){
导航器。推(
上下文
MaterialPage路由(生成器:(上下文)=>TextInput()),
);
}else if(snapshot.data.status==“2”){
Scaffold.of(上下文).showSnackBar(
SnackBar(内容:文本(“无效的登录凭据”);
}
}else if(snapshot.hasrerror){
返回文本(“${snapshot.error}”);
}
返回中心(子项:CircularProgressIndicator());
},
),
);
}
}

我返回字符串“1”表示有效登录,返回字符串“2”表示无效登录。那么,为什么只有在有效登录时才会发生错误呢?对于无效登录,将显示消息“无效凭据”,但ProgressIndicator不会停止。如何停止此操作并显示登录屏幕?请帮我解决这两个问题。提前感谢。

当登录有效时,json['usrid']返回用户id,这是int,对于无效登录,json['usrid']返回0,这也是int。这是因为我使用了final int-usrid;类内登录。
CircularProgressIndicator
不会消失,因为当
snapshot.data.status='2'
时不会返回任何内容,因此它默认再次返回指示符。至于成功登录的错误,我怀疑
json['usrId']的返回值
实际上不是您认为的int,而是字符串。打印响应JSON字符串以确保您实际从服务器接收到的内容。您不能返回null,因为生成器函数必须返回某些内容。如果您不想返回任何内容,那么builder函数是该代码的错误位置。我认为
\u OneByteString
\u Smi
是JSON解析器的内部类型,分别表示(简而言之)字符串值和整数值。这告诉我的是,您的PHP后端可能有一个bug,在不成功登录时为用户ID返回一个
int
,在成功登录时为用户ID返回一个
String
。为了让颤振端正常工作,您需要追踪并修复该bug。