【发布时间】:2015-11-11 12:18:38
【问题描述】:
我有一个 JSONArray 作为参数传递给我的服务器。我有一个由“生成数据快照客户端类”过程生成的方法,当它到达第一个“SetJsonValue”行时,它给了我一个访问冲突,这个错误来来去去,没有明显的原因。我在 LAN 中使用了一个 Rest 服务器(也将它与 http 一起使用,但尚未对其进行测试)。有时它可以通过重新启动我的计算机/编译器来解决,但有时它会持续更长时间。
方法如下:
if FExecutaInsertCommand = nil then
begin
FExecutaInsertCommand := FConnection.CreateCommand;
FExecutaInsertCommand.RequestType := 'POST';
FExecutaInsertCommand.Text := 'TServerMethods."ExecutaInsert"';
FExecutaInsertCommand.Prepare(TServerMethods_ExecutaInsert);
end;
FExecutaInsertCommand.Parameters[0].Value.SetWideString(database);
FExecutaInsertCommand.Parameters[1].Value.SetWideString(Tabela);
FExecutaInsertCommand.Parameters[2].Value.SetJSONValue(aValores, FInstanceOwner);
FExecutaInsertCommand.Parameters[3].Value.SetJSONValue(aTipos, FInstanceOwner);
FExecutaInsertCommand.Parameters[4].Value.SetInt32(usuario);
FExecutaInsertCommand.Execute(ARequestFilter);
Result := FExecutaInsertCommand.Parameters[5].Value.GetInt32;
从这里调用方法:
result := DMClient.ServerMethodsClient.ExecutaInsert(banco, Tabela, GeraJSONArray(Registro), GeraJSONArray(GetStrings(Registro.DataType)), CodigoUsuarioLogado);
JSONArray 的生成方式如下:
function GeraJSONArray(Valores: TVariantArray) : TJSONArray;
var
i : Integer;
begin
result := TJSONArray.Create;
for i := 0 to Length(Valores.Values) - 1 do
result.Adiciona(Valores.Values[i], Valores.DataType[i]);
end;
function GeraJSONArray(Valores: TArray<String>) : TJSONArray;
var
i : Integer;
begin
result := TJSONArray.Create;
for i := 0 to Length(Valores) - 1 do
result.AddElement(TJSONString.Create(Valores[i]));
end;
JsonArray.Adiciona:
procedure TJSONArrayHelper.Adiciona(valor: variant; DataType: TFieldType);
var
JSONValue : TJSONValue;
begin
if not (VarIsEmpty(valor)) and not (VarIsNull(valor)) then
begin
case DataType of
TFieldType.ftString,
TFieldType.ftMemo,
TFieldType.ftFmtMemo,
TFieldType.ftFixedChar,
TFieldType.ftWideString : JSONValue := TJSONString.Create(valor);
//-----------------------------------------------//
TFieldType.ftSmallint,
TFieldType.ftInteger,
TFieldType.ftWord,
TFieldType.ftFloat,
TFieldType.ftCurrency,
TFieldType.ftAutoInc,
TFieldType.ftLargeint,
TFieldType.ftSingle,
TFieldType.ftBCD : JSONValue := TJSONNumber.Create(valor);
//-----------------------------------------------//
TFieldType.ftDateTime : JSONValue := TJSONString.Create(DateTimeParaString(valor));
end;
end
else
begin
JSONValue := TJSONNull.Create;
end;
if JSONValue <> nil then
AddElement(JSONValue);
end;
参数2产生错误,但参数3没有,我认为Adiciona程序有问题
【问题讨论】:
-
请将其缩减为minimal reproducible example。使用 FastMM 帮助自己使缺陷更可重复。
-
我认为最好在 Destroy 中添加一个测试:
if FMembers[I] is TJSONAncestor。可能有一个意想不到的不同类型,甚至某些元素是 Nil。 -
@Christian,显示的
Destroy方法是Delphi 提供的一种;修改它并非易事。此外,几乎不值得修改代码以在调试器中轻松检查而无需额外代码。该修复将首先防止无效项目进入数组,一旦它们在那里就不会跳过它们。此外,该元素不为空; Ricardo 之前对这个问题的尝试表明访问冲突的正常外观非零地址。 -
Ricardo,您的第一个
GeraJSONArray函数调用TJSONArray.Adiciona,这不是该类型的标准方法。请确保在 David 请求的示例中包含该方法。 -
Adiciona 检查数据类型,创建一个 JSONObject 来保存它并调用 self.Add
标签: arrays json rest delphi datasnap