Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.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
Delphi 目标多字节代码页中不存在Unicode字符的映射_Delphi_Utf 8_Urlencode_Delphi 10.1 Berlin_Webbroker - Fatal编程技术网

Delphi 目标多字节代码页中不存在Unicode字符的映射

Delphi 目标多字节代码页中不存在Unicode字符的映射,delphi,utf-8,urlencode,delphi-10.1-berlin,webbroker,Delphi,Utf 8,Urlencode,Delphi 10.1 Berlin,Webbroker,我有一个用Delphi2007构建的soap,它可以工作 在Delphi 10.1 Berlin中进行转换后,我有很多例外情况: 目标多字节代码页中不存在Unicode字符的映射 原因似乎是,当webbroker HttpApp解析请求参数时,如果请求的查询字符串中有一些url编码的字符,则会引发此异常,例如: http://localhost/soap/soap.dll/action?param=%E0 事实上,如果我用%E0(a)调用URL.Decode()): 它引发了同样的例外: 目标

我有一个用Delphi2007构建的soap,它可以工作

在Delphi 10.1 Berlin中进行转换后,我有很多例外情况:

目标多字节代码页中不存在Unicode字符的映射

原因似乎是,当webbroker HttpApp解析请求参数时,如果请求的查询字符串中有一些url编码的字符,则会引发此异常,例如:

http://localhost/soap/soap.dll/action?param=%E0
事实上,如果我用
%E0
a
)调用
URL.Decode()
):

它引发了同样的例外:

目标多字节代码页中不存在Unicode字符的映射

在方法
TURLEncoding.DoDecode(常量输入:string):string上,问题似乎是unit
System.NetEncoding
。此方法尝试仅在UTF-8中转换url编码的字符,而不使用任何回退。字符串
%E0
是针对
的Windows-1252编码,但仅限于delphi转换UTF-8版本:
%C3%A0

一个小的(不完美、不优雅的)修复是添加一个后备:

try
  Result := TEncoding.UTF8.GetString(Bytes); // original Delphi 10.1 line
except
  on E: EEncodingError do Result := string(PChar(Bytes)); // fallback
end;
完整代码:

function TURLEncoding.DoDecode(const Input: string): string;

  function DecodeHexChar(const C: Char): Byte;
  begin
    case C of
       '0'..'9': Result := Ord(C) - Ord('0');
       'A'..'F': Result := Ord(C) - Ord('A') + 10;
       'a'..'f': Result := Ord(C) - Ord('a') + 10;
    else
      raise EConvertError.Create('');
    end;
  end;

  function DecodeHexPair(const C1, C2: Char): Byte; inline;
  begin
    Result := DecodeHexChar(C1) shl 4 + DecodeHexChar(C2)
  end;

var
  Sp, Cp: PChar;
  I: Integer;
  Bytes: TBytes;

begin
  SetLength(Bytes, Length(Input) * 4);
  I := 0;
  Sp := PChar(Input);
  Cp := Sp;
  try
    while Sp^ <> #0 do
    begin
      case Sp^ of
        '+':
          Bytes[I] := Byte(' ');
        '%':
          begin
            Inc(Sp);
            // Look for an escaped % (%%)
            if (Sp)^ = '%' then
              Bytes[I] := Byte('%')
            else
            begin
              // Get an encoded byte, may is a single byte (%<hex>)
              // or part of multi byte (%<hex>%<hex>...) character
              Cp := Sp;
              Inc(Sp);
              if ((Cp^ = #0) or (Sp^ = #0)) then
                raise EHTTPException.CreateFmt(sErrorDecodingURLText, [Cp - PChar(Input)]);
              Bytes[I] := DecodeHexPair(Cp^, Sp^)
            end;
          end;
      else
        // Accept single and multi byte characters
        if Ord(Sp^) < 128 then
          Bytes[I] := Byte(Sp^)
        else
          I := I + TEncoding.UTF8.GetBytes([Sp^], 0, 1, Bytes, I) - 1

      end;
      Inc(I);
      Inc(Sp);
    end;
  except
    on E: EConvertError do
      raise EConvertError.CreateFmt(sInvalidURLEncodedChar, [Char('%') + Cp^ + Sp^, Cp - PChar(Input)])
  end;
  SetLength(Bytes, I);

  // ------> MY FIX <------
  try
     Result := TEncoding.UTF8.GetString(Bytes); // Original line
  except
     on E: EEncodingError do Result := string(PChar(Bytes));
  end;
  // END FIX
end;
函数TURLEncoding.DoDecode(常量输入:字符串):字符串;
函数DecodeHexChar(const C:Char):字节;
开始
案例C
'0'..'9':结果:=Ord(C)-Ord('0');
‘A’…‘F’:结果:=Ord(C)-Ord(‘A’)+10;
‘a’…‘f’:结果:=Ord(C)-Ord(‘a’)+10;
其他的
引发EConvertError。创建(“”);
结束;
结束;
函数DecodeHexPair(常量C1,C2:Char):字节;内联;
开始
结果:=解码字符(C1)shl 4+解码字符(C2)
结束;
变量
Sp,Cp:PChar;
I:整数;
字节:TBytes;
开始
设置长度(字节,长度(输入)*4);
I:=0;
Sp:=PChar(输入);
Cp:=Sp;
尝试
而Sp ^#0可以
开始
个案
'+':
字节[I]:=字节(“”);
'%':
开始
公司(Sp),;
//查找转义的%(%)
如果(Sp)^=“%”,则
字节[I]:=字节(“%”)
其他的
开始
//获取编码字节,可能是单个字节(%)
//或多字节(%%…)字符的一部分
Cp:=Sp;
公司(Sp),;
如果((Cp^=#0)或(Sp^=#0)),则
提高EHTTPException.CreateFmt(sErrorDecodingURLText[Cp-PChar(输入)];
字节[I]:=DecodeHexPair(Cp^,Sp^)
结束;
结束;
其他的
//接受单字节和多字节字符
如果作战需求文件(Sp^)小于128,则
字节[I]:=字节(Sp^)
其他的
I:=I+TEncoding.UTF8.GetBytes([Sp^],0,1,Bytes,I)-1
结束;
公司(一);
公司(Sp),;
结束;
除了
关于E:EConvertError-do
raise EConvertError.CreateFmt(sInvalidURLEncodedChar,[Char('%')+Cp^+Sp^,Cp-PChar(输入)])
结束;
设置长度(字节,I);
//------>我的补丁尝试使用WEB.ReqMulti

当表单中有多字节字符时,当我使用WebBroker从网页处理POST方法时,我也有同样的例外

在我在WebBroker的项目中添加了use WEB.ReqMulti之后,这个异常就消失了。

我在东京(10.2.1)IDE中尝试关闭IDE时遇到了“目标多字节代码页中不存在Unicode字符的映射”异常。
修复方法:从项目目录中删除文件。$$$。

仅供参考,没有Delphi XE 10.1-它只是Delphi 10.1。更新了你的标签。
function TURLEncoding.DoDecode(const Input: string): string;

  function DecodeHexChar(const C: Char): Byte;
  begin
    case C of
       '0'..'9': Result := Ord(C) - Ord('0');
       'A'..'F': Result := Ord(C) - Ord('A') + 10;
       'a'..'f': Result := Ord(C) - Ord('a') + 10;
    else
      raise EConvertError.Create('');
    end;
  end;

  function DecodeHexPair(const C1, C2: Char): Byte; inline;
  begin
    Result := DecodeHexChar(C1) shl 4 + DecodeHexChar(C2)
  end;

var
  Sp, Cp: PChar;
  I: Integer;
  Bytes: TBytes;

begin
  SetLength(Bytes, Length(Input) * 4);
  I := 0;
  Sp := PChar(Input);
  Cp := Sp;
  try
    while Sp^ <> #0 do
    begin
      case Sp^ of
        '+':
          Bytes[I] := Byte(' ');
        '%':
          begin
            Inc(Sp);
            // Look for an escaped % (%%)
            if (Sp)^ = '%' then
              Bytes[I] := Byte('%')
            else
            begin
              // Get an encoded byte, may is a single byte (%<hex>)
              // or part of multi byte (%<hex>%<hex>...) character
              Cp := Sp;
              Inc(Sp);
              if ((Cp^ = #0) or (Sp^ = #0)) then
                raise EHTTPException.CreateFmt(sErrorDecodingURLText, [Cp - PChar(Input)]);
              Bytes[I] := DecodeHexPair(Cp^, Sp^)
            end;
          end;
      else
        // Accept single and multi byte characters
        if Ord(Sp^) < 128 then
          Bytes[I] := Byte(Sp^)
        else
          I := I + TEncoding.UTF8.GetBytes([Sp^], 0, 1, Bytes, I) - 1

      end;
      Inc(I);
      Inc(Sp);
    end;
  except
    on E: EConvertError do
      raise EConvertError.CreateFmt(sInvalidURLEncodedChar, [Char('%') + Cp^ + Sp^, Cp - PChar(Input)])
  end;
  SetLength(Bytes, I);

  // ------> MY FIX <------
  try
     Result := TEncoding.UTF8.GetString(Bytes); // Original line
  except
     on E: EEncodingError do Result := string(PChar(Bytes));
  end;
  // END FIX
end;