views:

519

answers:

1

Using the following block of code, the listItem.Update fails with a NullReferenceException:

        SPWeb web = null;
        SPList list = null;
        SPListItem listItem = null;
        try
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(this.SiteUrl))
                {
                    web = site.OpenWeb();
                    list = web.Lists[this.ListName];
                    listItem = list.Items.Add();
                    listItem["Background"] = "foo";

                }
            }
            );
            listItem.Update();
        }
        catch
        {
        }
        finally
        {
            web.Dispose();
        }

If I move the listItem.Update() method inside of the anonymous delegate, I get "Operation is not valid due to the current state of the object."

Yes, I've combed through SO and have tried many permutations without success.

Any ideas?

Update: After the first comment, I tried to remove the anonymous delegate from the code to see if it fared any better:

    // store the selected item to pass between methods
    public T SelectedItem { get; set; }   

    // set the selected item and call the delegate method
    public virtual void Save(T item)
    {
        SelectedItem = item;
        try
        {
            SPSecurity.RunWithElevatedPrivileges(SaveSelectedItem);
        }
        catch
        {
        }
    }

    public virtual void SaveSelectedItem()
    {
        if (SelectedItem != null)
        {

            using (SPSite site = new SPSite(this.SiteUrl))
            {
                using(SPWeb web = site.OpenWeb())
                {                    
                    SPList list = web.Lists[this.ListName];
                    SPListItem listItem = list.Items.Add();
                    //UpdateListItem(listItem, SelectedItem);
                    listItem["Background"] = "foo";
                    listItem.Update();
                }
            }      
        }
    }

And this still fails "Operation is not valid due to the current state of the object." In both code samples, it looks like site.Impersonating is false. I am using Windows Auth, and Impersonation in the web.config. This is running from the ASP.Net Development server.

A: 

I found an example from this site (blackninjasoftware). I create a reference to the site, grab its SystemAccount token and then create another reference to the site, using the admin token. It seemed a little hackish to me at first - but hey - I have a deadline.

Final working method body now looks like:

            SPListItem new_item = null;
            SPSite initialSite = new SPSite(this.SiteUrl);
            using (var site = new SPSite(this.SiteUrl, initialSite.SystemAccount.UserToken))
            {
                // This code runs under the security context of the SHAREPOINT\system
                // for all objects accessed through the "site" reference. Note that it's a 
                // different reference than SPContext.Current.Site. 
                using (var elevatedWeb = site.OpenWeb())
                {
                    elevatedWeb.AllowUnsafeUpdates = true;
                    SPList list = elevatedWeb.Lists[this.ListName];
                    new_item = list.Items.Add();
                    UpdateListItem(new_item, item);
                    if (new_item != null)
                    {
                        new_item.Update();
                    }
                }
            }
            initialSite.Dispose();
RJBrady