0

I have a custom list that has a GUID column which refers to the UniqueId of a document in a document library. Every time I upload a document, it should add an entry in this list and populate the column with this document GUID column.

List 1: Document Library, its items UniqueId is stored in the DocumentId column of the second list.
List 2: A custom list with a column called DocumentId where it's value is the document's UniqueId (GUID).

I have used an item receiver to do this, the code is shown below (working). This side works fine, the issue is when I want to do the opposite.

 public override void ItemDeleting(SPItemEventProperties properties)
    {
        using (SPWeb web = properties.OpenWeb())
        {
            SPListItem documentItem = properties.ListItem;
            string listUrl = SPUtility.ConcatUrls(web.ServerRelativeUrl, "Lists/PortalLinks");
            // Get the PortalLinks list
            SPList portalLinksList = web.GetList(listUrl);
            // Gets the matching items by CAML
            SPQuery linkQuery = new SPQuery();
            linkQuery.Query = string.Format("<Where><Eq><FieldRef Name='DocumentItemId' /><Value Type='Guid'>{0}</Value></Eq></Where>", documentItem.UniqueId);
            SPListItemCollection linkItemsMatchingGuid = portalLinksList.GetItems(linkQuery);

            //add the main text to the stringbuilder
            batchString.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
            foreach (SPListItem item in linkItemsMatchingGuid)
            {
                batchString.Append("<Method>");
                batchString.Append("<SetList Scope=\"Request\">" + Convert.ToString(item.ParentList.ID) + "</SetList>");
                batchString.Append("<SetVar Name=\"ID\">" + Convert.ToString(item.ID) + "</SetVar>");
                batchString.Append("<SetVar Name=\"Cmd\">Delete</SetVar>");
                batchString.Append("</Method>");
            }
            batchString.Append("</Batch>");
            web.ProcessBatchData(batchString.ToString());
        }
        base.ItemDeleting(properties);
    }

If I delete the link item associated with a document, I also want to delete this document. So I went and added an ItemDeleting event receiver to this linked list but for some reason I can't seem to get this side to work.

Here is the ItemDeleting code to 'try' and delete the referencing document. (Not working)

 public override void ItemDeleting(SPItemEventProperties properties)
    {
        using (SPWeb web = properties.OpenWeb())
        {
            // Get the matching list item beign deleted.
            SPListItem linkItem = properties.ListItem;
            Guid parentId = new Guid(linkItem["DocumentItemId"].ToString());
            // Get the list of documents.
            string documentLibraryUrl = SPUtility.ConcatUrls(web.ServerRelativeUrl, "/Documents");
            SPList documentLibrary = web.GetList(documentLibraryUrl);
            SPListItemCollection documents = documentLibrary.Items;

            StringBuilder batchString = new StringBuilder();
            batchString.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
            foreach (SPListItem item in documents)
            {
                if (item.UniqueId == parentId)
                {
                    batchString.Append("<Method>");
                    batchString.Append("<SetList Scope=\"Request\">" + Convert.ToString(item.ParentList.ID) + "</SetList>");
                    batchString.Append("<SetVar Name=\"ID\">" + Convert.ToString(item.ID) + "</SetVar>");
                    batchString.Append("<SetVar Name=\"Cmd\">Delete</SetVar>");
                    batchString.Append("</Method>");
                }
            }
            batchString.Append("</Batch>");
            web.ProcessBatchData(batchString.ToString());
        }
        base.ItemDeleting(properties);
    }

I have tried the following before with no luck either:

Looping through the list and deleting the item one by one (I read its not very efficient so I switched to batch delete).

Result

Deleting the document removes the link in the list.

Deleting the link, however does NOT remove the referring document but I want it to.

Please let me know if there is a better way to do this.

Thanks.

1
  • Can you confirm that event is firing? If you look at "Elements.xml" which has event receivers defined, it should have receiver defined for your custom list or generic list. You can try to remove the "ListTemplateId" or "ListUrl" for the "Receivers" node of Elements.xml. Commented Aug 19, 2013 at 13:07

2 Answers 2

1

HandleEventFiring handleEventFiring = new HandleEventFiring();

                    handleEventFiring.DisableHandleEventFiring();
                    try
                    {
                        var parentDoc = documentLibrary.GetItemByUniqueId(parentId);
                        parentDoc.Delete();    
                     }
                    finally
                    {
                        handleEventFiring.EnableHandleEventFiring();
                    }

to disallow multiple firing of the delete event.

2
  • Will give this a shot Vishal. Commented Aug 19, 2013 at 15:01
  • Hi Vishal, this seem to have solve my issue for now. Thank you very much. I'll dig into the code a bit more though, as I'm a bit concerned about disabling events being fired. I've tried testing for multiple cases it seems to work fine at the moment. Commented Aug 19, 2013 at 15:20
0

Have you tried the obvious instead of looping through all document and building a batch update to delete a single document by it's unique id?

Something like this (after the line SPList documentLibrary = web.GetList(documentLibraryUrl);:

var parentDoc = documentLibrary.GetItemByUniqueId(parentId);
parentDoc.Delete();
1
  • I have done that before Per, unfortunately it seems like I am getting a circular delete issue cause both list has an ItemDeleting event receiver on them. So by calling that delete, it triggers the other ItemDeleting method from the document library which in turns calls the ItemDeleting again. i.e possibly an infinite loop until the SPException was thrown saying 'File does not exists, it may have been deleted by someone'. Commented Aug 19, 2013 at 11:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.