Pergunta

I've build a SharePoint that should modify some information when the user create data.

The addin has some pages (asp.mvc) that lists the lists in the host web. The user select one of the list, then the code registers dynamically the event receiver.

The event receiver itself handles both ItemAdding and ItemUpdating event and should change some of the item's field dynamically.

I was able to register the RER, I can even step into the receiver when debugging with Visual Studio, and I can actually see the SPRemoteEventResult.ChangedProperties correctly populated. However, even though I've no error, the actual date does not reflect my changed.

I suspect this is due to the fact I dynamically register RER, which leeds to authentication troubles.

Here's how I register my RER (from a POST action in my ASP.net MVC app) :

    [SharePointContextFilter]
    [HttpPost]
    public ActionResult Enable(Guid listId)
    {
        var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
        using (var clientContext = spContext.CreateAppOnlyClientContextForSPHost())
        {
            if (listId != Guid.Empty)
            {
                var serviceUrlRoot = $"{Request.Url.Scheme}://{Request.Url.Authority}" + Url.Content("~/Services");

                var list = clientContext.Web.Lists.GetById(listId);
                clientContext.Load(list, lst => lst.Title, lst => lst.EventReceivers);

                clientContext.ExecuteQuery();
                var receiver = new EventReceiverDefinitionCreationInformation
                {
                    EventType = EventReceiverType.ItemAdding
                };

                //Get WCF URL where this message was handled
                receiver.ReceiverUrl = serviceUrlRoot + "/Services/myreceiver.svc";

                receiver.ReceiverName = "some name";
                receiver.Synchronization = EventReceiverSynchronization.Synchronous;

                //Add the new event receiver to a list in the host web
                list.EventReceivers.Add(receiver);
                clientContext.ExecuteQuery();

            }
        }
        return RedirectToAction("Lists", new { SPHostUrl = spContext.SPHostUrl.ToString() });
    }

I guess this code is OK since the RER are actually triggering.

Here's how I handle the adding event :

    public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
    {
        var result = new SPRemoteEventResult();
        var webUrl = properties.ItemEventProperties.WebUrl;

        var webUri = new Uri(webUrl);
        var realm = TokenHelper.GetRealmFromTargetUrl(webUri);
        var accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, webUri.Authority, realm).AccessToken;

        using (var ctx = TokenHelper.GetClientContextWithAccessToken(webUrl, accessToken))
        {
             result.ChangedItemProperties.Add("MyField", "My dynamic value");

        }

        return result;
    }

This code does not throw any error when executing. But the list item does not have it's MyField changed.

As you can see, both registering the RER and handling it's event is done using App Only context. I tries various other combination, but I never succeed in making everything work as expected.

What's the correct way to dynamically register RER on list in the host web, on user's action ?

What's the correct way to handle adding and updating event when the RER was registered dynamically ?

Foi útil?

Solução 2

I wasn't good in my diagnostic. Actually, the RER didn't worked not because of a permission issue, but because of a wrong type in some fields (user field to be precise). I don't get what's the proper way of updating user field, but that's another question.

Outras dicas

The ChangedItemProperties is just a dictionary object in memory. Changing it is not going to change the source item on SharePoint.

To change the item in SharePoint you need to grab a ClientContext on the site and run the appropriate CSOM code.

If this is the same list that triggered the event receiver you then need to handle triggering the event receiver again or it'll loop forever.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top