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 版本),因为反序列化很容易......这是如果您离开 .net 世界,那就不好了,因为通常只有.net 二进制格式化程序(相同的 clr 版本)才能理解该数据......

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

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

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

a:1:{s:1:"1";s:6:"谷歌"}

一个:大小:{键;值;[重复]}

而字符串必须表示为:

s:长度:“the_string_itself”

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

a:2:{s:2:"16";s:12:"WebSiteTitle";s:2:"14";s:9:"NewDomain"}

从那里您需要使用该 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 回答