tags:

views:

7944

answers:

7

I officially think I'm going mad. I'm trying something very simple - accessing my SharePoint list's items and their properties.

However, SPListItem.Properties count is zero for all normal lists. Everything works as expected for document and pages libraries. So, if the list items are based on document type, all is good. If they are based on item, properties are not returned.

I've tried in two environments, with new sites created from OOTB publishing templates, with new lists which are based on OOTB content types etc. Always the same thing.

Right amount of SPListItems is always returned. Title and Name are fine. It's just that the .Properties hashtable is totally empty.

In desperation, I wrote a web part that outputs the following (ugly!) diagnostics.

    foreach (SPList list in SPContext.Current.Web.Lists)
    {
        foreach (SPListItem item in list.Items)
        {
            Label label = new Label();
            label.Text = "Name: " + item.Name + "Property count: " + item.Properties.Count;
            this.Controls.Add(label);
        }
    }

The only observation is that it works exactly as I described earlier. I just share the code to show that this is the most basic operation imaginable.

Here is sample output - I've added the line breaks for readability ;-)

Name: Test Property count: 0
Name: default.aspx Property count: 21

Obviously item "Test" is an item based list item and default.aspx is a page.

Has anyone ever encountered anything like this? Any ideas?

Joyce

+1  A: 

Are you trying to get the field Values? Sadly, they are not strongly typed:

string ModifiedBy = (string)item["Author"];

To get the proper names of the fields (they have to be the internal names), go to the List and then List Settings. You will find the List of Columns there. Click on any Column Name to go to the Edit Page, and then look at the URL in the Address Bar of your Browser. At the very end, there should be a parameter "Field=Editor" or similar - that's your internal field name.

If you wonder why a field like "Test Field" looks strange, that is because Sharepoint encodes certain characters. A Space would be encoded to x0020 hence the Internal Name for "Test Field" is "Test_x0020_Field".

In order to get the proper field type to cast to:

string FieldType = item["Author"].GetType().FullName;

(The Intermediate Window in Visual Studio is tremendously helpful for this!)

Michael Stum
Thanks for your ideas, Michael. Sadly, my problem is that the SPListItem.Properties hashtable is completely empty. There is nothing there if the item is not based on document. I've verified this by looking with Visual Studio debugger.
For what do you need the .Properties HashTable? If you want to access any of the fields, you don't need it at all. It's only for Metadata, and Simple List Items usually do not have Metadata.
Michael Stum
If I look at e.g. a Page type item, I see in the Properties hashtable the following: Key (my field name) and Value (the value of the field). Then I access the value like in your example: item["fieldname"]. When I try to access field value that is not in the Properties table, I get an exception.
Have you checked if the field is accessed properly? i.e. when you open the List in your Browser and select Settings => List Settings, is the desired column listed there? If yes, are you accessing it using the correct internal name?
Michael Stum
A: 

Do you run SPListItem.Update() or .SystemUpdate() after setting the properties?

JMD
No...but I'm not trying to set anything. I'd like to read the properties, but unfortunately the hashtable is totally empty. There is not one single property to access.
A: 

item["FieldName"] is the canonical way to get a value of a metadata column in a SharePoint list. If you need to get the list of available fields for a SharePoint list, check the parent SPList object's Fields property which is a collection of the fields in this list. Each of those field objects will have a property called InternalName and that is what you should use to access its value when you are working with an instance of SPListItem.

Mark Mascolino
A: 

If you want to get an object out of a SPField of a SPListItem you've got to do like this:

SPField field = ((SPList)list).Fields.GetField("FieldName"); 
object fieldValue = field.GetFieldValue(((SPListItem)item)[field.Title].ToString());
+1  A: 

First of all - thank you all for taking the time to help me out. As I wrote yesterday, I figured I was going mad when I couldn't do this very simple thing that has always worked before.

All those who said the properties had nothing to do with the problem were of course right. Once I couldn't access the data, I started debugging, saw the differences in Properties and got carried away with that "problem".

In the end my issue was a combination of three things: 1) being too tired, 2) trying to access a field that was empty ---- that will throw Exception even when the internal name is correct, and 3) having one wrong internal name in my code.

All is good now and thanks. Below is the ultimate version of my supremely ugly debugging code.

Joyce

    Panel panel = new Panel();
    panel.ID = "Panel1";
    this.Controls.Add(panel);

    foreach (SPList list in SPContext.Current.Web.Lists)
    {
        foreach (SPListItem item in list.Items)
        {
            Label label = new Label();
            label.Text = "<br/>Name: " + item.Name ;
            panel.Controls.Add(label);

            foreach (SPField field in item.Fields)
            {
                Label l1 = new Label();
                l1.Text = "<br/>&nbsp;&nbsp;&nbsp;&nbsp;Field name (internal): " + field.InternalName;
                panel.Controls.Add(l1);
                try
                {
                    Label l2 = new Label();
                    l2.Text = "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Field value: " + item[field.InternalName].ToString();
                    panel.Controls.Add(l2);
                }
                catch (Exception e)
                {
                    Label l3 = new Label();
                    l3.Text = "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception (value could not be read)";
                    panel.Controls.Add(l3);
                }
            }
        }
    }
A: 

Hi,

I have a similar problem. I have a SPList that has Publishing Image Field which stores the Url of the images. How do I check the type of the publishing Image and if true display that image to the image control?

I did //Get the list SPList HomepageImage = currentWeb.Lists["Homepage Images"];

                    //Get the list items
                    SPListItemCollection collListItems = HomepageImage.Items;


                    //Select one of the list items randomly 
                    Random random = new Random();
                    int i = random.Next() % collListItems.Count;
                    string sUrl="";

                    foreach (SPListItem Listitem in collListItems)
                    {

                        if (Listitem["Title"].ToString().CompareTo(i.ToString())==0)
                        {        


                            sUrl=Listitem["ImageAbstractHD"].ToString();


                            break;
                        }

                        //string fieldType = spField.TypeAsString;

                            testImage.ImageUrl = sUrl;

                    }
A: 

I am building a custom webpart which retrives 5 records from annoucement list. I need to pick the list items randomley. Any idea!

Abhi