4

文字列パラメータ「CompanyName」を受け入れるサーバーメソッド「CustomerLookup」があります。ユーザーは任意の文字を入力でき、CustomerLookupメソッドは条件に部分的に一致する顧客のリストを返します。私のRESTURLは次のようなもので、最後の単語「t」はメソッドのパラメーターです。

http://localhost/datasnap/rest/TSales_SM/CustomerLookup/t

私の期待する結果は、ユーザーが「t」を入力した場合、メソッドは「t」に部分的に一致するすべての顧客の会社名を返すことです。しかし、T&YがTrueに変換され、N&Fがfalseに変換されるなどの特定の文字を見つけました。変換コードはdelphiユニット->DataSnap.DSServiceに実装されています

procedure TDSRESTService.BuildParamArray(const Params: TStringList; var ParamArray: TJSONArray);
  var
    I: Integer;
    S: String;
    LValue: Double;
  begin
    ParamArray := TJSONArray.Create;
    for I := 0 to Params.Count - 1 do
    begin
      S := Params[I];
      if (AnsiIndexText(S,TrueBoolStrs) > -1) then
         ParamArray.AddElement(TJSONTrue.Create)
      else if AnsiIndexText(S,FalseBoolStrs) > -1 then
         ParamArray.AddElement(TJSONFalse.Create)
      else if AnsiCompareStr(S,NULL) = 0 then
         ParamArray.AddElement(TJSONNull.Create)
      else
         if TDBXPlatform.TryJsonToFloat(S, LValue) then
           ParamArray.AddElement(TJSONNumber.Create(S))
         else
           ParamArray.AddElement(TJSONString.Create(S));
    end;
  end;

システムがT、F、Y、Nをtrueとfalseに変換するのを防ぐ方法を誰かに教えてもらえますか

ありがとう。

4

3 に答える 3

3

あなたのコードのどこかに次のようなものが定義されているに違いないと思います。

SetLength(TrueBoolStrs, 4);
TrueBoolStrs[0] := 'True';
TrueBoolStrs[1] := 'T';
TrueBoolStrs[2] := 'Yes';
TrueBoolStrs[3] := 'Y';

SetLength(FalseBoolStrs, 4);
FalseBoolStrs[0] := 'False';
FalseBoolStrs[1] := 'F';
FalseBoolStrs[2] := 'No';
FalseBoolStrs[3] := 'N';

回避策は、TDSRestService.BuildParamArrayに次のパッチを適用することです。

procedure TDSRESTService.BuildParamArrayPatch(const Params: TStringList;
  var ParamArray: TJSONArray);
const NULL = 'null';
var
  I: Integer;
  S: String;
  LValue: Double;
begin
  ParamArray := TJSONArray.Create;
  for I := 0 to Params.Count - 1 do
  begin
    S := Params[I];
    if SameText(S, 'true') then
      ParamArray.AddElement(TJSONTrue.Create)
    else if SameText(S, 'false') then
      ParamArray.AddElement(TJSONFalse.Create)
    else if AnsiCompareStr(S, NULL) = 0 then
      ParamArray.AddElement(TJSONNull.Create)
    else if TDBXPlatform.TryJsonToFloat(S, LValue) then
      ParamArray.AddElement(TJSONNumber.Create(S))
    else
      ParamArray.AddElement(TJSONString.Create(S));
  end;
end;
于 2012-09-14T08:13:31.117 に答える
2

示されているコードがまさにそれを行うため、それらはtrueとfalseに変換されています。を呼び出しAnsiIndexText(S,TrueBoolStrs)TrueBoolStrs配列には文字列が含まれているTため、オブジェクトを照合TJSONTrueして配列に挿入します。それを望まない場合は、この関数を呼び出さないようにする必要があります。

より限定的な検索を実行できます。TrueBoolStrs配列内のすべての値をチェックする代わりに、ブール値として扱いたい特定の値をチェックするだけです。TrueBoolStrs事前に内容を変更することで、機能を変更せずに行うことができます。(これはSysUtilsユニットのグローバル変数です。)ただし、誰かが数字を含む会社名の顧客を検索しようとすると、同様の問題が発生することがわかります。引数が。に変換されますTJSONNumber

プログラムを作成してパラメータを定義するのはあなたです。したがって、特定のフィールド名に特定の型が必要であることがわかっている場合は、誤って推測できるときに型を推測しようとする関数を使用しないでください。関数のパラメーターが文字列であることは既にご存知のとおり、CustomerLookupパラメーターを直接変換するTJSONStringか、JSONをまったく使用せずに元の文字列を使用してください。

Datasnapがこの関数を完全に制御外で呼び出している場合は、JSON変換されたパラメーターリストではなく、元のパラメーターリストにアクセスする方法を見つけようとする可能性があります。後者は信頼性が低いためです。

JSON変換されたバージョンが必要であるが、元のパラメーターリストにもアクセスできる場合は、上記に基づくカスタム作成の変換関数に、何らかの形式の予想される型情報を含めることもできます。次に、関数は期待される型を使用して推測をガイドできます。ブール値を持つはずのパラメーターを読み取る場合にのみ、ブール文字列を検索します。

于 2012-09-13T13:33:10.843 に答える
1

私はここで同じかもしれない同様の問題を抱えていました。私のServermethodでは、すべて文字列として読み込むいくつかのパラメーターを期待していました。

TServerMethods1.InsertMember(userid, Pw, MemberName, PhoneNumber: string): TJsonArray;

しばらくすると、電話番号が正しく転送されず、先頭の「0」が途切れるという苦情が寄せられました。したがって、プロセスのどこかで、パラメータを適切と思われるタイプに評価しようとします。したがって、電話番号「08979」の場合、それは番号であると見なされ、InsertMember関数は電話番号として「8979」を受け取りました。あなたの場合も同じだったと思います!解決策は、文字列型ではなく、パラメータでJSonTypeを使用することでした。そこで、インターフェイスを次のように変更しました。

TServerMethods1.InsertMember(juserid, jPw, jMemberName, jPhoneNumber: TJSONString): TJsonArray;

しかし、現在、パラメーターはjsonobjectsであり、誰かがパラメーターを空白のままにした場合に備えて、特別な処理が必要です。このために、私はローカル変数を使用しました。受信したすべてのパラメーターについて、次のチェックを行い、ローカル変数にコピーしました。

割り当てられていない場合(jPhoneNumber)、PhoneNumber:='' else PhoneNumber:= UpperCase(StringReplace(jPhoneNumber.ToString、'"'、''、[rfReplaceAll]));

その後、それはすべてうまくいきました。あなたの場合、彼は電話番号から数字を作ろうとしたので、tとfをブール値に変換すると思います!それ以来、私は常にTJSonobjectsを使用しています。

于 2013-06-18T05:03:35.577 に答える