2

WHMCS API を使用します。APIを使用してリクエストを作成しようとしています.そのAPIには、配列をシリアル化し、base64_encodeにする必要があります。彼らはphpで例を挙げ、それをC#コードに変換しようとしましたが、うまくいきません。

PHPコード:

     $values["customfields"] = base64_encode(serialize(array("1"=>"Google")));

このための私のC#コード:

     CustomFields[] cf = new CustomFields[2];
                    CustomFields cf0 = new CustomFields();
                    cf0.number = "16";
                    cf0.value = WebSiteTitle;
                    CustomFields cf1 = new CustomFields();
                    cf1.number = "14";
                    cf1.value = NewDomain;
                    cf[0] = cf0;
                    cf[1] = cf1;
                    byte[] bytecf = ObjectToByteArray2(cf);
                    String CString = Convert.ToBase64String(bytecf);

                    form.Add("customfields", CString);


       private static byte[] ObjectToByteArray2(Object obj)
    {
        if (obj == null)
            return null;
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }


       [Serializable]
public class CustomFields
{
    public string number { get; set; }
    public string value { get; set; }
}

私は何か間違ったことをしましたか?リクエストを作成しようとすると機能せず、追加したい場所にこのフィールドを追加しないためです。

4

2 に答える 2

1

あなたは何か間違ったことをしました:

バイナリフォーマッタを使用してシリアル化しています...

これは、逆シリアル化する別のバイナリ フォーマッタによって理解されるバイト シーケンスを生成します ... 逆シリアル化は簡単なので、.net の世界 (および clr バージョン) を離れない限り、これは適切です ... これは通常、(同じ clr バージョンの) .net バイナリ フォーマッタだけがそのデータを理解するため、.net の世界を離れると悪いことになります ...

php の serialize() は .net の binaryformatter と同じ結果を返さないため、逆シリアル化は失敗します。

ここでのもう 1 つの問題は、php の serialize() の出力文字列がバイトにエンコードされる方法が指定されていないことです...それを行うには多数の方法があり、それぞれが別の一連のバイトになります...最初にエンコーディングを知る必要があります...おそらくASCIIですが、それは単なる推測です...

C# で独自のバージョンの serialize() を実装するには、php の例のような入力が与えられた場合、関数は次を返す必要があります。

a:1:{s:1:"1";s:6:"グーグル"}

a:size:{キー;値;[繰り返し]}

文字列は次のように表す必要があります。

s:length:"文字列そのもの"

したがって、WebSiteTitle と NewDomain がリテラル文字列であると仮定すると、serialize() 後に例は次のようになります。

a:2:{s:2:"16";s:12:"WebSiteTitle";s:2:"14";s:9:"新しいドメイン"}

そこから、その API で期待されるエンコードを使用してバイトにエンコードし、そのバイトストリームを base64 文字列にエンコードする必要があります。

于 2013-05-15T23:28:41.457 に答える
1

.Net の BinaryFormatter はプラットフォームに大きく依存します。CLR の異なるバージョン間で使用することはできません。プログラミング言語間で問題はありません。PHP シリアライズ関数は、配列に対して呼び出されると、C# で再現できるほど単純な出力を実際に生成します。たとえば、次のようになります。

$array["a"] = "Foo";
$array["b"] = "Bar";
print serialize($array);

結果:

a:2:{s:1:"a";s:3:"Foo";s:1:"b";s:3:"Bar";}

試す

 public static string phpStringArray(Dictionary<string, string> arr)
 {
     StringBuilder sb = new StringBuilder("a:")
         .Append(arr.Count).Append(":{");

     foreach (string key in arr.Keys)
     {
         sb.AppendFormat("s:{0}:\"{1}\";s:{2}:\"{3}\";",
             key.Length, key, arr[key].Length, arr[key]);
     }

     return sb.Append('}').ToString();
 }

それで

Console.WriteLine(
         phpStringArray(
             new Dictionary<string, string> { { "a", "Foo" }, { "b", "Bar" } })
         );

その結果を Base64 エンコードするだけです。

于 2013-05-15T23:29:26.707 に答える