Console application triggering event receiver
-
08-10-2020 - |
Question
I have console application collecting data from SQL and either creates or updates the item in a SP list.
I have added an event receiver to that list, this triggers if an item has been updated and finds a correlating item in another list and make changes to it.
The problem is that the even receiver is triggered, but not fully executed; it seems it is not able to get the list to modify. The event receiver works fine if I change an item manually.
It's a very simple event receiver, here is the code:
public override void ItemUpdated(SPItemEventProperties properties)
{
try
{
base.ItemUpdated(properties);
this.EventFiringEnabled = false;
SPSecurity.RunWithElevatedPrivileges(delegate(){
SPUserToken token = properties.ListItem.Web.Site.SystemAccount.UserToken;
using(SPSite site = new SPSite(properties.SiteId, token)){
using(SPWeb web = site.OpenWeb(properties.Web.ID)){
try
{
SPListItem listItem = web.Lists[properties.ListId].GetItemById(properties.ListItem.ID);
string contactlisturl = web.ServerRelativeUrl + "/lists/Contacts";
SPList contactlist = web.GetList(contactlisturl);
SPListItemCollection contactItems = contactlist.GetItems();
foreach(SPListItem item in contactItems){
log.logToTextfile("Entered foreach");
string id = "";
string email = "";
try
{
id = "" + GetFieldValueRegular(item, "ID");
email = "" + GetFieldValueRegular(item, "EMail");
}catch(Exception ex){
log.logToTextfile(ex.ToString());
}
if(email.Trim() == listItem["Email"].ToString().Trim()){
log.logToTextfile("The contact exsist");
if (listItem["Unsubscribed"].ToString() == "True")
{
item["UNSUBSCRIBED"] = true;
}
else
{
item["UNSUBSCRIBED"] = false;
}
}
item.Update();
}
}catch(Exception ex){
log.logToTextfile(ex.ToString());
}
}
}
});
}
catch (Exception ex)
{
log.logToTextfile(ex.ToString());
}
}
As I have mentioned the event receiver works fine if I do any changes to an item manually, but when triggered from the console application it seems unable to get the list and items:
string contactlisturl = web.ServerRelativeUrl + "/lists/Contacts";
SPList contactlist = web.GetList(contactlisturl);
SPListItemCollection contactItems = contactlist.GetItems();
and it does not enter the foreach. The value of the item triggering the event receiver is listed in my log, so it's not Null. I am not getting any exceptions either.
Anyone have a clue why this happends? and what I may do wrong?
Solution
I managed to solve this by adding SequenceNumber and Synchronization in the Elements.xml file of the event receiver:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers ListUrl="Lists/members">
<Receiver>
<Name>MembersItemUpdated</Name>
<Type>ItemUpdated</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>Members.Members</Class>
<SequenceNumber>10001</SequenceNumber>
<Synchronization>Synchronous</Synchronization>
</Receiver>
</Receivers>
</Elements>
When adding xml tags to the Element.xml an update of the wsp is not sufficient. You either have to reinstall the wsp or update the event receiver with powershell. I went with the powershell version like so:
Add-PSSnapin Microsoft.SharePoint.PowerShell
$web = Get-SPWeb "site url"
$a = $web.Lists.TryGetList("List name").Eventreceivers
Since I only had one event receiver in this list I could get the first from the array like so:
$a = $a[0] (or assign it to a new variable)
$a.Synchronization = "Synchronous"
$a.SequenceNumber = 10001
$a.Update()