0

I have the following scenario on sharepoint online.

One Site collection with:

  • RootWeb
  • List Clients
  • List Projects
  • Subsite called Clients for hosting each client subsite
  • One RER to create a client subsite everytime a new item is added to the client list.
  • One RER to create a project subsite INSIDE a client site when a new item is added to the project list.

List Clients has a managed metadata field with the clientname List Project has a managed metadata field with the clientname and another one with the project.

The business logic on the project item creation is: 1. Check if there is a list item with the client name on the client list, if there is one, check the client site url and create a subsite for the project in the client subsite.

However I am getting a 403 Forbidden error.

The error is when I try to load the Web object for the specific client subite.

   ccSpecificClient.Load(ccSpecificClient.Web);
                                ccSpecificClient.ExecuteQuery();

I will paste the relevant code here:

    public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
            {
                SPRemoteEventResult result = new SPRemoteEventResult();
                try
                {              
                    switch (properties.EventType)
                    {
                        case SPRemoteEventType.AppInstalled:
                            AppEvents.HandleAppInstalled(properties);
                            result.Status = SPRemoteEventServiceStatus.Continue;
                            break;
                        case SPRemoteEventType.AppUninstalling:
                            AppEvents.HandleAppUninstalled(properties);
                            result.Status = SPRemoteEventServiceStatus.Continue;
                            break;
                        case SPRemoteEventType.AppUpgraded:
                            AppEvents.HandleAppUpgraded(properties);
                        result.Status = SPRemoteEventServiceStatus.Continue;
                        break;
                    case SPRemoteEventType.ItemAdded:
                        if(properties.ItemEventProperties.ListTitle=="Clientes")
                        {
                            return Clients.CreateClientSiteAndUpdateSiteOnList(properties);                           
                        }
                        if (properties.ItemEventProperties.ListTitle == "Proyectos")
                        {
                            return Projects.CreateProjectSiteAndUpdateSiteOnList(properties);
                        }
                        break;

                }
                return result;
            }
            catch (Exception ex)
            {
                //Log message
                result.ErrorMessage = "Capatech.Intranet:  " + ex.Message;
                result.Status = SPRemoteEventServiceStatus.CancelWithError;
                return result;
            }
        }


public static SPRemoteEventResult CreateProjectSiteAndUpdateSiteOnList(SPRemoteEventProperties properties)
        {
            SPRemoteEventResult result = new SPRemoteEventResult();
            try
            {
                using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
                {
                    if (clientContext != null)
                    {
                        //Get the item that we are trying to add to the project list
                        List projectList = clientContext.Web.Lists.GetById(properties.ItemEventProperties.ListId);
                        ListItem item = projectList.GetItemById(properties.ItemEventProperties.ListItemId);
                        clientContext.Load(item);
                        clientContext.ExecuteQuery();

                        //Get client name from that list item
                        TaxonomyFieldValue taxFieldValueClient = item["Nombre_x0020_Cliente"] as TaxonomyFieldValue;
                        string nombreCliente=  taxFieldValueClient.Label;

                        //Get the client we need from the clientList, matching the name on the project list
                        Microsoft.SharePoint.Client.List clientList = clientContext.Web.Lists.GetByTitle("Clientes");
                        clientContext.Load(clientList);
                        clientContext.ExecuteQuery();
                        string strUrlCliente=default(string);
                        if (clientList != null && clientList.ItemCount > 0)
                        {
                            Microsoft.SharePoint.Client.CamlQuery camlQuery = new CamlQuery();
                            camlQuery.ViewXml = string.Format( @"<View>  
                                    <Query> 
                                        <Where><Eq><FieldRef Name='Nombre_x0020_Cliente' /><Value Type='TaxonomyFieldType'>{0}</Value></Eq></Where> 
                                    </Query> 
                                </View>", nombreCliente);

                            ListItemCollection listItems = clientList.GetItems(camlQuery);
                            clientContext.Load(listItems);
                            clientContext.ExecuteQuery();

                            if (listItems.Count > 0)
                            {
                                foreach (ListItem listItem in listItems)
                                {
                                    if (listItem != null && listItem["Sitio_x0020_Cliente"] != null)
                                    {
                                        strUrlCliente = ((FieldUrlValue)(listItem["Sitio_x0020_Cliente"])).Url.ToString();
                                    }
                                }
                            }
                            else
                            {
                                result.Status = SPRemoteEventServiceStatus.CancelWithError;
                                //Client site has not been created yet
                                result.ErrorMessage = "Por favor cree el sitio del cliente primero.";
                                return result;
                            }
                        }
                        else
                        {
                            result.Status = SPRemoteEventServiceStatus.CancelWithError;
                            //Client site has not been created yet
                            result.ErrorMessage = "Por favor cree el sitio del cliente primero.";
                            return result;
                        }

                        // Maybe the client exists on the list, but the site has not been created yuet
                        // Check for that
                        if (!string.IsNullOrEmpty(strUrlCliente))
                        {
                            using (ClientContext ccSpecificClient = new ClientContext(strUrlCliente))
                            {
                                //Get Project name 
                                TaxonomyFieldValue taxFieldValue = item["Nombre_x0020_Proyecto"] as TaxonomyFieldValue;
                                string site_title = taxFieldValue.Label;
                                string site_url = taxFieldValue.Label;

                                ccSpecificClient.Load(ccSpecificClient.Web);
                                ccSpecificClient.ExecuteQuery();                     

                                //Create project site on specific client site
                                Web newWeb = ccSpecificClient.Web.CreateWeb(site_title, site_url, site_title, "STS#0", 1033);
                                ccSpecificClient.Load(newWeb);
                                ccSpecificClient.ExecuteQuery();

                                //Updates site on the project list
                                FieldUrlValue siteUrl = new FieldUrlValue();
                                siteUrl.Url = newWeb.Url;
                                siteUrl.Description = site_title + " Sitio";
                                item["Sitio_x0020_Proyecto"] = siteUrl;
                                item.Update();
                                clientContext.ExecuteQuery();

                                result.Status = SPRemoteEventServiceStatus.Continue;
                                return result;                               
                            }                            
                        }
                        else
                        {
                            //Client site has not been created yet
                            result.ErrorMessage = "Por favor cree el sitio del cliente primero.";
                            result.Status= SPRemoteEventServiceStatus.CancelWithError;
                            return result;
                        }
                    }
                    else
                    {
                        result.ErrorMessage = "No se pudo encontrar el contexto";
                        result.Status= SPRemoteEventServiceStatus.CancelWithError;
                        return result;
                    }
                }
            }
            catch (Exception ex)
            {
                result.ErrorMessage = ex.Message;
                result.Status= SPRemoteEventServiceStatus.CancelWithError;
                return result;
            }           
        }   
1
  • I am guessing I have to use the tokenhelper with any override to create the 2nd client context, but I am not sure if that is correct. Jan 27, 2015 at 0:13

1 Answer 1

0

The answer is to clone the client context, Bert Jensen from Office PnP program in Yammer helped me identify the problem.

the .clone method is an extension method from ClientContext and works just perfect.

Your Answer

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

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