Olivier Pons
Olivier Pons

Reputation: 15778

Change a HashTable to a Dictionnary

I've already read this. But there's no example to make it work. So I tried it on my own. Here's my code:

public void AskServer(List<Kvp> kvps)
{
    WWWForm form = new WWWForm();
    Hashtable headers = form.headers;
    if (this._lastCookies != string.Empty) {
        headers.Add("Cookie", this._lastCookies);
    }
    foreach (var arg in kvps) {
        form.AddField(arg.Key, arg.Value.ToString());
    }
    form.AddField("pseudo", this._pseudo);
    form.AddField("jeton", this._dernierJeton.ToString());
    StartCoroutine(SendToServer(
        new WWW(this._URL, form.data, headers)
    )); 
}

Now, there's a warning saying that calling new WWW(this._URL, form.data, headers) is obsolete, I should use the one with the dictionnary. The declarations are like this:

    public WWW(string url, byte[] postData, Dictionary<string, string> headers);
    [Obsolete("This overload is deprecated. Use the one with Dictionary argument.")]
    public WWW(string url, byte[] postData, Hashtable headers);

So when I try to use the example in the link I've provided at the beginning of the question, I have a code like this, which doesn't work:

public static Dictionary<K, V> HashtableToDictionary<K, V>(Hashtable table)
{
    return table
      .Cast<DictionaryEntry>()
      .ToDictionary(kvp => (K)kvp.Key, kvp => (V)kvp.Value);
}

public void AskServer(List<Kvp> kvps)
{
    WWWForm form = new WWWForm();
    Dictionary<string, string> headers = StateManager.HashtableToDictionary<string, object>(form.headers);
    if (this._lastCookies != string.Empty) {
        headers.Add("Cookie", this._lastCookies);
    }
    foreach (var arg in kvps) {
        form.AddField(arg.Key, arg.Value.ToString());
    }
    form.AddField("pseudo", this._pseudo);
    form.AddField("jeton", this._dernierJeton.ToString());
    StartCoroutine(SendToServer(
        new WWW(this._URL, form.data, headers)
    )); 
}

The error is: Assets/Code/StateManager.cs(58,36): error CS0029: Cannot implicitly convert typeSystem.Collections.Generic.Dictionary' to System.Collections.Generic.Dictionary<string,string>'

What am I doing wrong? And is there a more effective way of doing this?

Upvotes: 2

Views: 3767

Answers (3)

Kasi-Laubfrosch
Kasi-Laubfrosch

Reputation: 11

For anyone who might fell over this issue (a minimal example):

    //make a short dictionary (only one Entry - remember to set also the
    //appropriate Length if you want to submit non Text Data

    Dictionary<string, string> headers = new Dictionary<string, string>();
    headers.Add( "Content-Type", "application/x-www-form-urlencoded" );

        //ADD your Form Elements wich you want to transmit
        WWWForm form = new WWWForm();
        form.AddField( "ChunkCoordinate", ChunkCoordinate );            // 0/0

        byte[] rawData = form.data;
        string url = "http://yourURL.com/addSomething.php?";

        // Post a request to an URL with our custom headers
        WWW www = new WWW(url, rawData, headers);

Upvotes: 0

will
will

Reputation: 11

It seems like the wwwform code on in unit3d's documentation needs to be updated, seeing as it still shows an example that has this exact same issue.

The problem I found with the solutions above at first is when you look at the www reference is it the www class requires a hashtable as the third argument. it seemed then that this solution would work:

Hashtable header = new Hashtable(form.headers);

The only problem with that is that using the hashtable is obsolete, so you actually have to use a dictionary. Just remember you may also need to then add

using System.Collections.Generic;

Upvotes: -1

dotnetom
dotnetom

Reputation: 24901

The issue is that you are trying to assign Dictionary<string, object> to a variable of type Dictionary<string, string>. In order to fix the issue change

Dictionary<string, string> headers = 
    StateManager.HashtableToDictionary<string, object>(form.headers);

to

Dictionary<string, object> headers = 
    StateManager.HashtableToDictionary<string, object>(form.headers);

or

Dictionary<string, string> headers = 
    StateManager.HashtableToDictionary<string, string>(form.headers);

Upvotes: 2

Related Questions