base64编码和序列化数组WHMCS

时间:2013-05-15 22:54:56

标签: c# base64 whmcs

我使用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; }
}

我做错了什么吗?因为当我尝试发出请求时它不起作用而不是在我想添加的地方添加这个字段。

2 个答案:

答案 0 :(得分:1)

你做错了什么:

您正在使用二进制格式化程序来序列化...

这将生成一个字节序列,另一个二进制格式化程序可以理解它反序列化......只要你不离开.net世界(和clr版本)这很好,因为反序列化很容易。如果你离开.net世界,这是不好的,因为通常只有 .net二进制格式化程序(相同的clr版本)会理解这些数据......

php的serialize()不会给出.net的binaryformatter相同的结果,因此反序列化将失败

这里的另一个问题是没有指定php的serialize()的输出字符串如何被编码成字节...有很多方法可以做到这一点,每一个都产生另一系列的字节......你需要知道编码首先......可能是ascii,但这只是猜测...

在c#中实现你自己的serialize()版本,你的函数必须返回以下内容,给出php示例中的输入:

一个:1:{S:1: “1”; S:6: “谷歌”}

一个:尺寸:{密钥;值;重复]}

而字符串必须表示为:

S:长度: “the_string_itself”

因此,假设WebSiteTitle和NewDomain是litteral-strings,你的示例应该在serialize()之后看起来像这样

一个:2:{S:2: “16”; S:12: “WebSiteTitle”; S:2: “14”; S:9: “NEWDOMAIN”}

从那里你需要使用该API期望的任何编码将其编码为字节,然后将该字节流编码为base64字符串

答案 1 :(得分: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对其结果进行编码。