tags:

views:

312

answers:

5

I've got a hashtable that I want to update from a second hashtable. For any of the keys that match I want to copy the value over. The problem I have is when I enumerate the hashtable keys and try to cast each to a string I receive an exception about casting a Guid to a String. Well it's the string I want. When you use the index operator with something like hashtable["FirstName"] then I expect FirstName to be the key. It might use Guids underneath I guess but I need to get out the string for the key, the key value.

private void UpdateSharePointFromInfoPath(Hashtable infopathFields)
{
    // Go through all the fields on the infopath form
    // Invalid Cast Exception Here
    foreach (String fieldName in infopathFields.Keys)
    {
        // If the same field is on sharepoint    
        if (workflowProperties.Item.Fields.ContainsField(fieldName))
        {
            // Update the sharepoint field with the new value from infopath
            workflowProperties.Item[fieldName] = infopathFields[fieldName];
        }
    }
    // Commit the changes
    workflowProperties.Item.Update();
}

EDIT I don't create either of these hashtables. The keys have strings somewhere because I can put the field name in like the following and get the value of the field out. I'm trying to make a shorthand way of doing the following for every field:

workflowProperties.Item["FirstName"] = infopathFields["FirstName"];
workflowProperties.Item["LastName"] = infopathFields["LastName"];
workflowProperties.Item["Address"] = infopathFields["Address"];
workflowProperties.Item["DOB"] = infopathFields["DOB"];
ect...

EDIT It's been said that the hashtable uses Guids, but it also obviously has a string inside else I wouldn't be able to do infopathFields["FirstName"]. It's the value on the string I pass in there that I want.

A: 

What creates the Hashtable? the key is actually an object so it sounds like whatever populated it has no implicit cast to a string

Pharabus
A: 

If the type of the values of infopathFields is a Guid then the types of the values of workflowProperties will have to be Guids. I can't see from the snippet what workflowProperties is defined as.

To convert a Guid to a string use Guid.ToString()

jbloomer
I was just about to post something along these lines. Almost definitely your Hashtable is using GUID as the key value
Crowe T. Robot
A: 

The objects stored in the hashtable are Guid objects, so to get a string you need to call ToString() on the object you get from the key enumerator. I would also recommend using the generic Dictionary<K,V> class instead of Hashtable, as that would catch problems like this at compile time rather than runtime.

thecoop
I don't create the hashtables. An infopath form outputs the hashtable when it is submitted and sharepoint exposes it's own hashtable for each item on a list so you can access the fields.
Dan Revell
+1  A: 

The standard version of the Hashtable can have different type keys, so most of your keys may be strings, but some of your keys may be GUIDs. I'm willing to bet that is the case and is causing your issue. The following little console app demonstrates the problem.

    static void Main(string[] args)
    {
        System.Collections.Hashtable htable = new System.Collections.Hashtable();
        htable.Add("MyName", "WindyCityEagle");
        htable.Add("MyAddress", "Here");
        htable.Add(new Guid(), "That Was My Guid");

        int loopCount = 0;
        foreach (string s in htable.Keys)
        {
            Console.WriteLine(loopCount++.ToString());
            Console.WriteLine(htable[s]);
        }
    }

You'll get the exact same exception that you're reporting here.

My suggestion to fix the problem would be to go with the following

private void UpdateSharePointFromInfoPath(Hashtable infopathFields)
{
    // Go through all the fields on the infopath form
    // Invalid Cast Exception Here
    foreach (object key in infopathFields.Keys)
    {

        string wfpKey = key.ToString();
        // If the same field is on sharepoint    
        if (workflowProperties.Item.Fields.ContainsField(wfpKey))
        {
            // Update the sharepoint field with the new value from infopath
            workflowProperties.Item[wfpKey] = infopathFields[key];
        }
    }
    // Commit the changes
    workflowProperties.Item.Update();
}
Jonathan Beerhalter
If the object coming out from .Keys is a Guid then casting it to a string will just give me the Guid in string format.
Dan Revell
I don't think so, you can't cast a Guid to a String. Try writing the following two lines of code, they won't compile. Guid g = new Guid(); string s = (string)g;
Jonathan Beerhalter
+2  A: 

Every item is a Key/Value pair of format DictionaryEntry

foreach (DictionaryEntry de in infopathFields)
        {        
            string fieldName = de.Key as string;         
                if (workflowProperties.Item.Fields.ContainsField(fieldName))        
                {           
                    workflowProperties.Item[fieldName] = infopathFields[fieldName];        
                }    
        }    

        workflowProperties.Item.Update();
harryovers
Just what I'm after. Wish some of the other attempts would have actually read the question before answering. Cheers
Dan Revell
very common problem on here
harryovers
Just an FYI, this will ignore the GUIDs, which, according to your question you didn't want to do. The line string fieldName = de.Key as string; will have the fieldName as null when the key is of type Guid. Then the if statement returns false and the Guid is ignored. Therefore I don't think this solution is correct.
Jonathan Beerhalter