我正在使用Delphi XE3.我有一个JSON流,其中一个对象可以为null.也就是说,我可以收到:
"user":null
Run Code Online (Sandbox Code Playgroud)
要么
"user":{"userName":"Pep","email":"pep@stackoverflow.com"}
Run Code Online (Sandbox Code Playgroud)
我想区分这两种情况,我尝试使用这段代码:
var
jUserObject: TJSONObject;
jUserObject := TJSONObject(Get('user').JsonValue);
if (jUserObject.Null)
then begin
FUser := nil;
end else begin
FUser := TUser.Create;
with FUser, jUserObject do begin
FEmail := TJSONString(Get('email').JsonValue).Value;
FUserName := TJSONString(Get('userName').JsonValue).Value;
end;
end;
Run Code Online (Sandbox Code Playgroud)
如果我把一个断点排成一行if (jUserObject.Null) then begin并且我将鼠标放在jUserObject.Null它上面说jUserObject.Null = True是否"user":null,它说jUserObject.Null = False是否"user":{"userName":"Pep","email":"pep@stackoverflow.com"}
但是,如果我使用调试器进入该行,jUserObject.Null将调用以下XE3库代码:
function TJSONAncestor.IsNull: Boolean;
begin
Result := False;
end;
Run Code Online (Sandbox Code Playgroud)
所以,我总是得到False我if就算一句,"user":null.
我想我总是有一个解决方法,即捕获在执行"user":null和Get('email').JsonValue执行时引发的异常,以便区分值是否为null,但这看起来并不那么优雅.
如何判断JSON对象在JSON流中是否具有空值?
Get()返回一个TJSONPair.如果有"user":null,TJSONPair.JsonValue属性将返回一个TJSONNull对象,而不是一个TJSONObject对象.你的代码没有考虑到这种可能性.它假设JsonValue始终是a TJSONObject并且不验证类型转换.
有两种方法可以解决这个问题.
TJSONPair有自己的Null属性,指定它JsonValue是否为空值:
var
JUser: TJSONPair;
jUserObject: TJSONObject;
jUser := Get('user');
if jUser.Null then begin
FUser := nil;
end else begin
// use the 'as' operator for type validation in
// case the value is something other than an object...
jUserObject := jUser.JsonValue as TJSONObject;
...
end;
Run Code Online (Sandbox Code Playgroud)使用is运算符在测试JsonValue之前测试类的类型:
var
JUser: TJSONPair;
jUserObject: TJSONObject;
jUser := Get('user');
if jUser.JsonValue is TJSONNull then begin
FUser := nil;
end
else if jUser.JsonValue is TJSONObject then begin
jUserObject := TJSONObject(jUser.JsonValue);
...
end else begin
// the value is something other than an object...
end;
Run Code Online (Sandbox Code Playgroud)