Domanda

I use WHMCS API. I am trying to use their API to make request.That api need that array need to be serialize and in base64_encode. They give example with php and I try to convert it into C# code but it not work.

PHP CODE :

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

My C# Code for this :

     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; }
}

Did I do something wrong? Because when I try to make request it not work and not adding this field where I want to add.

È stato utile?

Soluzione

The BinaryFormatter in .Net is highly platform dependent, it can't be used across different versions of the CLR never mind between programming languages. The PHP serialize function, when called on an array will actually produce output that should be simple enough to reproduce in C#, e.g.:

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

Result:

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

Try

 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();
 }

Then

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

Just need to Base64 Encode the result of that.

Altri suggerimenti

You did something wrong:

you are using the binary formatter to serialize ...

this wil generate a byte sequence that will be understood by another binary formatter to deserialize ... this is good as long as you don't leave the .net world (and the clr version) since deserialization would be easy ... this is bad if you leave the .net world, since usually only the .net binary formatter (of the same clr version) will understand that data ...

php's serialize() won't give the same result as .net's binaryformatter, therefore the deserialization will fail

another problem here is that it's not specified how the output String of php's serialize() is encoded into bytes ... there are numerous ways to do that, each one resulting in another series of bytes ... you need to know the encoding first ... probably ascii but that's just a guess ...

to implement your own version of serialize() in c# your function has to return the following, given the input like in the php example:

a:1:{s:1:"1";s:6:"Google"}

a:size:{key;value;[repeat]}

while strings have to be represented as:

s:length:"the_string_itself"

therefore your example should look like this after serialize() assuming WebSiteTitle and NewDomain are litteral-strings

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

from there you will need to encode that to bytes with whatever encoding is expected by that API, and then encode that bytestream into a base64 string

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top