3

I am developing remote event receiver to a SharePoint Online tenant and noticed that with each deployment a new Event Receiver is added to the web. So on the app installed event I want to find all existing event receivers and delete them before adding a new one. I am attempting to use a LINQ query to get them all and then call DeleteObject but it is not liking my query.

Here is the code I am using and the error. Thanks for the help.

public class AppEventReceiver : IRemoteEventService
{
    public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
    {
        SPRemoteEventResult result = new SPRemoteEventResult();

        using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
        {
            if (clientContext != null)
            {
                clientContext.Load(clientContext.Web, ev=>ev.EventReceivers);
                clientContext.ExecuteQuery();

                // Create new List Added Event Receiver
                EventReceiverDefinitionCreationInformation listAddedEV = new EventReceiverDefinitionCreationInformation()
                {
                    EventType = EventReceiverType.ListAdded,
                    ReceiverName = "List_Events",
                    ReceiverUrl = GetServiceURL("List_Events.svc"),
                    SequenceNumber = 1000
                };

                // Add Event Receiver to Web's EventReceivers.
                EventReceiverDefinitionCollection webEvs = clientContext.Web.EventReceivers;

                List<EventReceiverDefinition> existingEvs = webEvs.Where(n => n.ReceiverName == "List_Events").ToList(); // Error is here!

                foreach (EventReceiverDefinition ev in existingEvs)
                {
                    ev.DeleteObject();
                }

                // Add event receiver to Projects List
                webEvs.Add(listAddedEV);
                clientContext.ExecuteQuery();
            }
        }

        return result;
    }

Error Message: System.NotSupportedException was unhandled by user code

StackTrace: at Microsoft.SharePoint.Client.ClientQueryable1.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at EventReceiverTestWeb.Services.AppEventReceiver.ProcessEvent(SPRemoteEventProperties properties) in c:\Users\timothyo\Documents\Visual Studio 2013\Projects\EventReceiverTest\EventReceiverTestWeb\Services\AppEventReceiver.svc.cs:line 36 at SyncInvokeProcessEvent(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

3

I faced this problem today in Client Object Model, it seems like it doesn't support comparing to strings either with == or Equals method.

.Where(n => n.ReceiverName == "List_Events") this is what is causing the issue..

You might need to Load EventReceiverDefinitionCollection webEvs object and than iterate through the collection to match the ReceiverName property

UPDATE

Can you try setting the credentials and specify the user explicitly like:

context.Credentials = new NetworkCredential("user", "password", "domain");
5
  • I have attempted to also load web.EventReceivers and iterate over them to get their ReceiverID. I then iterate those calling DeleteObject() but now get Access Denied. My assembly has full control over web and site so I am not sure why access is denied.
    – ChiliYago
    Apr 3 '14 at 19:30
  • I have updated my answer, this is another problem and should be posted as another question.. Apr 3 '14 at 19:38
  • yes the denied issue relates to attempting to delete an event receiver that was loaded by a previous F5 depoy. You are only able to delete event receivers on app unload. I am not sure if your answere will work becuase I am just foreach'ing them now and skipping LINQ mysteries.
    – ChiliYago
    Apr 4 '14 at 15:19
  • That's what I said.. foreach'ing means iterating :P Apr 4 '14 at 15:20
  • If it solved the issue, kindly mark the answer as correct to close the Question Apr 4 '14 at 16:03
0

The issue is being caused because the Sharepoint collection type doesn't support the full range of Linq expressions.

To get around this convert it from a Sharepoint collection to a generic list with another .ToList() as below.

var existingEvs = webEvs.ToList().Where(n => n.ReceiverName == "List_Events").ToList();

If this were LinqToSql this would cause all the rows to be retrieved from the server without filtering causing it to slow significantly, however as you have already loaded all the rows into client memory with the Load and ExecuteQuery the difference should be insignificant.

I believe, but am not sure, that this is only an issue with Sharepoint 2013 and the V15 DLLs, and that the V16 DLLs support a fuller range of Linq expressions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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