0

I am pretty much going crazy trying to get a SharePoint List Event Receiver to work. I have created an EventReceiver Project in VS and can debug it however, the break points don't work. Basically its the same issue lots of people have had but none of their solutions seem to work. I posted this before and I think my event receiver code should work but I can't seem to get it working on the list itself. (my code is pasted below)

Basically all I need is for the Event Receiver to rename a document that is uploaded. Consider this scenario, if a document is uploaded called Client A Document and is the first document it should be called Client A Document 1. If the next document uploaded is called Client A Document, it should be renamed to Client A Document 2 and so on. Now if another document is uploaded, named Client B Document, it should just be Client B Document 1 since there are no others with the same name. Now I think my code below accomplishes this behaviour (code was written thanks to Robert Christs help!) but I don't know how to test it.

Do I upload a document or create a new one? I have tried both and nothing works, anyone have any ideas how to accomplish this? I'm starting to lose my mind with this requirement.

public override void ItemAdding(SPItemEventProperties properties)
{
   base.ItemAdding(properties);

   SPListItem item = properties.ListItem;

   if (item == null || item["Name"] == null) //item["Name"] == null)
       return; //or better yet, log 

   string oldFileName = item["Name"].ToString();

   int positionOfPeriod = oldFileName.LastIndexOf(".");
   string tempFileName = oldFileName.Substring(0, positionOfPeriod);

   SPQuery query = BuildArbitraryQuery(properties.List, "Name", tempFileName, true);
   int count = properties.List.GetItems(query).Count;
   String fileName, fileExtension;

   if (positionOfPeriod == -1)
   {
       fileName = oldFileName;
       fileExtension = "";
   }
   else
   {
       fileName = oldFileName.Substring(0, positionOfPeriod);
       fileExtension = oldFileName.Substring(positionOfPeriod);
   }

   string newFileName = fileName + "-xx" + count.ToString() + fileExtension;

   item["Name"] = newFileName;

   Console.WriteLine("New File Name: " + newFileName);

   try
   {
       properties.Web.AllowUnsafeUpdates = true;
       EventFiringEnabled = false;

       item.Update();
   }
   finally
   {
       properties.Web.AllowUnsafeUpdates = false;
       EventFiringEnabled = true;
   }
}
/// <summary> 
/// Builds an arbitrary SPQuery which filters by a single column value. 
/// </summary> 
/// <param name="list">The list you will run the query against.</param> 
/// <param name="columnDisplayName">The Display Name of the column you want to filter.</param> 
/// <param name="value">The value to filter against.</param> 
/// <returns>A new SPQuery object ready to run against the list.</returns> 
public static SPQuery BuildArbitraryQuery(SPList list, string columnDocumentName, string value, bool deepSearch)
{
   if (list == null)
       throw new ArgumentNullException("You cannot pass a null list to Helper.BuildArbitraryQuery.");

   if (!list.Fields.ContainsField(columnDocumentName))
       throw new ArgumentException("The SharePoint List \"" + list.Title + "\" does not contain the Field \"" + columnDocumentName + "\".");

   string internalName = list.Fields[columnDocumentName].InternalName;
   SPQuery query = new SPQuery();
   query.Query = "<Where><Eq><FieldRef Name=\"" + internalName + "\"/><Value Type=\"Text\">" + value + "</Value></Eq></Where>";

   if (deepSearch)
       query.ViewAttributes += "Scope='RecursiveAll'";

   return query;
}

EDIT:-------------------------------------------------- Ok so I did a little test started with the same project type (event receiver) and created a very simple ItemAdded method to change the name of a list item to the current date. Now this works on a custom list but I can't seem to get this working with a document library.

So from this little test I know that I can register an event recevier to a custom list (sandboxed solution) using F5 and debugging it, but what is different about document libraries? And is my code that I pasted not ok for what I am trying to do on a document library?

This is the code I used for the small test but it doesnt work on document libraries, even if I create a new project type for document libraries rather than custom lists (this is in ItemAdded)

       SPListItem currentItem = properties.ListItem;
       currentItem["Title"] = DateTime.Now.ToString();
       currentItem.Update();
Tudor Hofnar
  • 267
  • 2
  • 9
  • 20
  • Have you registered your event receiver? Are your sure your event receiver is not called? have you tried to put breakpoint at the very beginning of event receiver? – petro.sidlovskyy Sep 07 '12 at 19:06
  • The earliest location I can put the EventReceiver is in the first line of ItemAdding...so I put it there but my code will not break, please see my comment below to user735768's post for more details. – Tudor Hofnar Sep 07 '12 at 19:14

2 Answers2

1

Here is what you should do:

  1. Restart IIS "to unload the DLLs if they are used"
  2. Put your DLL and its pdb file in the GAC folder that is appropriate for this DLL
  3. open SharePoint web site such that an new w3wp process is started.
  4. Attached your VS project to the w3wp make sure you choose managed code in the attach to process dialog.
  5. Try to upload a file 6- you should be able to catch break point now.

You can make Shell Script that can be called in post-build event to automate all this steps.

Mahmoud Fayez
  • 3,398
  • 2
  • 19
  • 36
  • I'm not sure where you mean to put the pdb file, the GAC throws an error if I try putting the pdb there so I just put the DLL in the GAC. I've opened sharepoint and attached to a process just like you said, but still no break points, even when I upload a file. Any other ideas? – Tudor Hofnar Sep 07 '12 at 21:15
  • Please take a look @ this link http://timrayburn.net/blog/how-to-put-pdbs-in-the-gac/ – Mahmoud Fayez Sep 08 '12 at 07:41
  • 1
    I copy dbp to C:\Windows\Microsoft.NET\assembly\GAC_MSIL\dll name folder\ after run gacutil.exe -if to install dll to GAC. after that I run iisreset. do from step 3 to step 5. – Phan Đức Bình Dec 02 '16 at 08:37
0

How exactly you were trying to debug ? You need to attach to the appropriate w3wp.exe process and add an item, if the breakpoints doesn't work it's usually because the version of the last deployed dll is newer than your code in visual studio(even the slightest change can cause this difference like new line etc)

liranco
  • 33
  • 7
  • Ok so to debug I attached to the w3wp process and I found the right one for my application pool. I placed a breakpoint at the first line in ItemAdding and hit F5. Now the breakpoint turns hollow (not the red as it usually is) and it says the symbols have not been loaded, I tried loading symbols using the Modules window but it still will not load them, where should I browse for them? – Tudor Hofnar Sep 07 '12 at 19:12
  • I tried recreating the project twice and I still can't get this to work, I used the EventReceiver project and I checked in the /bin folder of the project both the dll and pdb files have the same name and time on them, what else should I check? – Tudor Hofnar Sep 07 '12 at 19:13
  • no need to hit F5, it should catch anything that comes up from your code in sharepoint. Anyway if the breakpoint is hollow, usually it due to differences between the last deployed dll and your current code in visual studio(just redeploy to make sure). Another option is what petro suggested check his comment – liranco Sep 07 '12 at 19:15
  • How can I fix that? I tried cleaning and rebuilding the project but that didn't do it. Did I do something wrong when I first built the project? – Tudor Hofnar Sep 07 '12 at 19:16
  • 1
    How are you deploying the event receiver and registering it ? – liranco Sep 07 '12 at 19:19
  • I am just right clicking the solution and selecting Deploy. The EventReceiver project has a feature within it, so I think its getting stapled? I am adding this EventReceiver to the entire site not just a specific library. What I did before is to register it using a console application but that also did not work, I couldn't get the breakpoints issue figure out there either. For that project I followed the MSDN instructions http://msdn.microsoft.com/en-us/library/gg749858.aspx – Tudor Hofnar Sep 07 '12 at 19:22
  • Which one is the proper/preferred method? Or is there a better one than the two? – Tudor Hofnar Sep 07 '12 at 19:23