Exemplo n.º 1
0
        /// <summary>
        /// Clones a ClientContext object while "taking over" the security context of the existing ClientContext instance
        /// </summary>
        /// <param name="clientContext">ClientContext to be cloned</param>
        /// <param name="siteUrl">Site url to be used for cloned ClientContext</param>
        /// <returns>A ClientContext object created for the passed site url</returns>
        public static ClientContext Clone(this ClientRuntimeContext clientContext, Uri siteUrl)
        {
            if (siteUrl == null)
            {
                throw new ArgumentException(CoreResources.ClientContextExtensions_Clone_Url_of_the_site_is_required_, "siteUrl");
            }

            ClientContext clonedClientContext = new ClientContext(siteUrl);

            clonedClientContext.AuthenticationMode = clientContext.AuthenticationMode;

            // In case of using networkcredentials in on premises or SharePointOnlineCredentials in Office 365
            if (clientContext.Credentials != null)
            {
                clonedClientContext.Credentials = clientContext.Credentials;
            }
            else
            {
                //Take over the form digest handling setting
                clonedClientContext.FormDigestHandlingEnabled = (clientContext as ClientContext).FormDigestHandlingEnabled;

                // In case of app only or SAML
                clonedClientContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
                {
                    // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                    // the new delegate method
                    MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                    object[]   parametersArray = new object[] { webRequestEventArgs };
                    methodInfo.Invoke(clientContext, parametersArray);
                };
            }

            return(clonedClientContext);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Clones a ClientContext object while "taking over" the security context of the existing ClientContext instance
        /// </summary>
        /// <param name="clientContext">ClientContext to be cloned</param>
        /// <param name="siteUrl">Site URL to be used for cloned ClientContext</param>
        /// <param name="accessTokens">Dictionary of access tokens for sites URLs</param>
        /// <returns>A ClientContext object created for the passed site URL</returns>
        public static ClientContext Clone(this ClientRuntimeContext clientContext, Uri siteUrl, Dictionary <String, String> accessTokens = null)
        {
            if (siteUrl == null)
            {
                throw new ArgumentException(CoreResources.ClientContextExtensions_Clone_Url_of_the_site_is_required_, nameof(siteUrl));
            }

            ClientContext clonedClientContext = new ClientContext(siteUrl);

            clonedClientContext.AuthenticationMode = clientContext.AuthenticationMode;
            clonedClientContext.ClientTag          = clientContext.ClientTag;
#if !ONPREMISES
            clonedClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;
#elif SP2016
            clonedClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;
#endif


            // In case of using networkcredentials in on premises or SharePointOnlineCredentials in Office 365
            if (clientContext.Credentials != null)
            {
                clonedClientContext.Credentials = clientContext.Credentials;
            }
            else
            {
                //Take over the form digest handling setting
                clonedClientContext.FormDigestHandlingEnabled = (clientContext as ClientContext).FormDigestHandlingEnabled;

                var originalUri = new Uri(clientContext.Url);
                // If the cloned host is not the same as the original one
                // and if there is a custom Access Token for it in the input arguments
                if (originalUri.Host != siteUrl.Host &&
                    accessTokens != null && accessTokens.Count > 0 &&
                    accessTokens.ContainsKey(siteUrl.Authority))
                {
                    // Let's apply that specific Access Token
                    clonedClientContext.ExecutingWebRequest += (sender, args) =>
                    {
                        args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accessTokens[siteUrl.Authority];
                    };
                }
                else
                {
                    // In case of app only or SAML
                    clonedClientContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
                    {
                        // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                        // the new delegate method
                        MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                        object[]   parametersArray = new object[] { webRequestEventArgs };
                        methodInfo.Invoke(clientContext, parametersArray);
                    };
                }
            }

            return(clonedClientContext);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Clones a ClientContext object while "taking over" the security context of the existing ClientContext instance
        /// </summary>
        /// <param name="clientContext">ClientContext to be cloned</param>
        /// <param name="siteUrl">Site url to be used for cloned ClientContext</param>
        /// <returns>A ClientContext object created for the passed site url</returns>
        public static ClientContext Clone(this ClientRuntimeContext clientContext, Uri siteUrl)
        {
            if (siteUrl == null)
            {
                throw new ArgumentException("siteUrl");
            }

            ClientContext clonedClientContext = new ClientContext(siteUrl)
            {
                AuthenticationMode = clientContext.AuthenticationMode,
                ClientTag          = clientContext.ClientTag,
                //DisableReturnValueCache = clientContext.DisableReturnValueCache
            };

//#if !ONPREMISES
//#elif SP2016
//            //clonedClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;
//#endif


            // In case of using networkcredentials in on premises or SharePointOnlineCredentials in Office 365
            if (clientContext.Credentials != null)
            {
                clonedClientContext.Credentials = clientContext.Credentials;
            }
            else
            {
                //Take over the form digest handling setting
                clonedClientContext.FormDigestHandlingEnabled = (clientContext as ClientContext).FormDigestHandlingEnabled;

                // In case of app only or SAML
                clonedClientContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
                {
                    // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                    // the new delegate method
                    MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                    object[]   parametersArray = { webRequestEventArgs };
                    methodInfo.Invoke(clientContext, parametersArray);
                };
            }

            return(clonedClientContext);
        }
        protected virtual bool DetectSharePointOnlineContext(ClientRuntimeContext context)
        {
#if NET35
            return(false);
#endif

#if !NET35
            // checking based on the current assembly version
            // using hash to avoid performance degradation

            if (!Context2SharePointOnlineHash.ContainsKey(context))
            {
                Context2SharePointOnlineHash.Add(context, false);

                try
                {
                    // by assembly version
                    var version = AssemblyVersionService.GetAssemblyFileVersion(context.GetType().Assembly);

                    // 16.1.0.0 for SharePoint Online
                    // 16.0.0.0 for SharePoint 2016, we should be safe
                    // Major.Minor.Build.Revision
                    // currrent assembly? at least 16 (O365 / SharePoint 2016)
                    Context2SharePointOnlineHash[context] = version.Major == 16;

                    // if we talk to SharePoint 2016 from old, SP2013 CSOM
                    // SP2016 CSOM - taxonomy group cannot be found after provision #1103
                    // https://github.com/SubPointSolutions/spmeta2/issues/1103
                    if (context.ServerLibraryVersion.Major == 16)
                    {
                        Context2SharePointOnlineHash[context] = version.Major == 16;
                    }
                }
                catch (Exception e)
                {
                    // fallback
                    Context2SharePointOnlineHash[context] = context.Credentials is SharePointOnlineCredentials;
                }
            }

            return(Context2SharePointOnlineHash[context]);
#endif
        }
        /// <summary>
        /// Clones a ClientContext object while "taking over" the security context of the existing ClientContext instance
        /// </summary>
        /// <param name="clientContext">ClientContext to be cloned</param>
        /// <param name="siteUrl">Site URL to be used for cloned ClientContext</param>
        /// <param name="accessTokens">Dictionary of access tokens for sites URLs</param>
        /// <returns>A ClientContext object created for the passed site URL</returns>
        public static ClientContext Clone(this ClientRuntimeContext clientContext, Uri siteUrl, Dictionary <String, String> accessTokens = null)
        {
            if (siteUrl == null)
            {
                throw new ArgumentException(CoreResources.ClientContextExtensions_Clone_Url_of_the_site_is_required_, nameof(siteUrl));
            }

            ClientContext clonedClientContext = new ClientContext(siteUrl);

            clonedClientContext.AuthenticationMode = clientContext.AuthenticationMode;
            clonedClientContext.ClientTag          = clientContext.ClientTag;
#if !ONPREMISES || SP2016 || SP2019
            clonedClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;
#endif


            // In case of using networkcredentials in on premises or SharePointOnlineCredentials in Office 365
            if (clientContext.Credentials != null)
            {
                clonedClientContext.Credentials = clientContext.Credentials;
            }
            else
            {
                // Check if we do have context settings
                var contextSettings = clientContext.GetContextSettings();

                if (contextSettings != null) // We do have more information about this client context, so let's use it to do a more intelligent clone
                {
                    string newSiteUrl = siteUrl.ToString();

                    // A diffent host = different audience ==> new access token is needed
                    if (contextSettings.UsesDifferentAudience(newSiteUrl))
                    {
                        // We need to create a new context using a new authentication manager as the token expiration is handled in there
                        OfficeDevPnP.Core.AuthenticationManager authManager = new OfficeDevPnP.Core.AuthenticationManager();

                        ClientContext newClientContext = null;
                        if (contextSettings.Type == ClientContextType.SharePointACSAppOnly)
                        {
                            newClientContext = authManager.GetAppOnlyAuthenticatedContext(newSiteUrl, TokenHelper.GetRealmFromTargetUrl(new Uri(newSiteUrl)), contextSettings.ClientId, contextSettings.ClientSecret, contextSettings.AcsHostUrl, contextSettings.GlobalEndPointPrefix);
                        }
#if !ONPREMISES && !NETSTANDARD2_0
                        else if (contextSettings.Type == ClientContextType.AzureADCredentials)
                        {
                            newClientContext = authManager.GetAzureADCredentialsContext(newSiteUrl, contextSettings.UserName, contextSettings.Password);
                        }
                        else if (contextSettings.Type == ClientContextType.AzureADCertificate)
                        {
                            newClientContext = authManager.GetAzureADAppOnlyAuthenticatedContext(newSiteUrl, contextSettings.ClientId, contextSettings.Tenant, contextSettings.Certificate, contextSettings.Environment);
                        }
#endif

                        if (newClientContext != null)
                        {
                            //Take over the form digest handling setting
                            newClientContext.FormDigestHandlingEnabled = (clientContext as ClientContext).FormDigestHandlingEnabled;
                            newClientContext.ClientTag = clientContext.ClientTag;
#if !ONPREMISES || SP2016 || SP2019
                            newClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;
#endif
                            return(newClientContext);
                        }
                        else
                        {
                            throw new Exception($"Cloning for context setting type {contextSettings.Type} was not yet implemented");
                        }
                    }
                    else
                    {
                        // Take over the context settings, this is needed if we later on want to clone this context to a different audience
                        contextSettings.SiteUrl = newSiteUrl;
                        clonedClientContext.AddContextSettings(contextSettings);

                        clonedClientContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
                        {
                            // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                            // the new delegate method
                            MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                            object[]   parametersArray = new object[] { webRequestEventArgs };
                            methodInfo.Invoke(clientContext, parametersArray);
                        };
                    }
                }
                else // Fallback the default cloning logic if there were not context settings available
                {
                    //Take over the form digest handling setting
                    clonedClientContext.FormDigestHandlingEnabled = (clientContext as ClientContext).FormDigestHandlingEnabled;

                    var originalUri = new Uri(clientContext.Url);
                    // If the cloned host is not the same as the original one
                    // and if there is an active PnPProvisioningContext
                    if (originalUri.Host != siteUrl.Host &&
                        PnPProvisioningContext.Current != null)
                    {
                        // Let's apply that specific Access Token
                        clonedClientContext.ExecutingWebRequest += (sender, args) =>
                        {
                            // We get a fresh new Access Token for every request, to avoid using an expired one
                            var accessToken = PnPProvisioningContext.Current.AcquireToken(siteUrl.Authority, null);
                            args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accessToken;
                        };
                    }
                    // Else if the cloned host is not the same as the original one
                    // and if there is a custom Access Token for it in the input arguments
                    else if (originalUri.Host != siteUrl.Host &&
                             accessTokens != null && accessTokens.Count > 0 &&
                             accessTokens.ContainsKey(siteUrl.Authority))
                    {
                        // Let's apply that specific Access Token
                        clonedClientContext.ExecutingWebRequest += (sender, args) =>
                        {
                            args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accessTokens[siteUrl.Authority];
                        };
                    }
                    // Else if the cloned host is not the same as the original one
                    // and if the client context is a PnPClientContext with custom access tokens in its property bag
                    else if (originalUri.Host != siteUrl.Host &&
                             accessTokens == null && clientContext is PnPClientContext &&
                             ((PnPClientContext)clientContext).PropertyBag.ContainsKey("AccessTokens") &&
                             ((Dictionary <string, string>)((PnPClientContext)clientContext).PropertyBag["AccessTokens"]).ContainsKey(siteUrl.Authority))
                    {
                        // Let's apply that specific Access Token
                        clonedClientContext.ExecutingWebRequest += (sender, args) =>
                        {
                            args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + ((Dictionary <string, string>)((PnPClientContext)clientContext).PropertyBag["AccessTokens"])[siteUrl.Authority];
                        };
                    }
                    else
                    {
                        // In case of app only or SAML
                        clonedClientContext.ExecutingWebRequest += (sender, webRequestEventArgs) =>
                        {
                            // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                            // the new delegate method
                            MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                            object[]   parametersArray = new object[] { webRequestEventArgs };
                            methodInfo.Invoke(clientContext, parametersArray);
                        };
                    }
                }
            }

            return(clonedClientContext);
        }
        /// <summary>
        /// Clones a ClientContext object while "taking over" the security context of the existing ClientContext instance
        /// </summary>
        /// <param name="clientContext">ClientContext to be cloned</param>
        /// <param name="targetContext">CientContext stub to be used for cloning</param>
        /// <param name="siteUrl">Site URL to be used for cloned ClientContext</param>
        /// <param name="accessTokens">Dictionary of access tokens for sites URLs</param>
        /// <returns>A ClientContext object created for the passed site URL</returns>
        internal static ClientContext Clone(this ClientRuntimeContext clientContext, ClientContext targetContext, Uri siteUrl, Dictionary <string, string> accessTokens = null)
        {
            if (siteUrl == null)
            {
                throw new ArgumentException(CoreResources.ClientContextExtensions_Clone_Url_of_the_site_is_required_, nameof(siteUrl));
            }

            ClientContext clonedClientContext = targetContext;

            clonedClientContext.ClientTag = clientContext.ClientTag;
            clonedClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;


            // Check if we do have context settings
            var contextSettings = clientContext.GetContextSettings();

            if (contextSettings != null) // We do have more information about this client context, so let's use it to do a more intelligent clone
            {
                string newSiteUrl = siteUrl.ToString();

                // A diffent host = different audience ==> new access token is needed
                if (contextSettings.UsesDifferentAudience(newSiteUrl))
                {
                    var           authManager      = contextSettings.AuthenticationManager;
                    ClientContext newClientContext = null;
                    if (contextSettings.Type == ClientContextType.SharePointACSAppOnly)
                    {
                        newClientContext = authManager.GetACSAppOnlyContext(newSiteUrl, contextSettings.ClientId, contextSettings.ClientSecret, contextSettings.Environment);
                    }
                    else
                    {
                        newClientContext = authManager.GetContextAsync(newSiteUrl).GetAwaiter().GetResult();
                    }
                    if (newClientContext != null)
                    {
                        //Take over the form digest handling setting
                        newClientContext.ClientTag = clientContext.ClientTag;
                        newClientContext.DisableReturnValueCache = clientContext.DisableReturnValueCache;
                        return(newClientContext);
                    }
                    else
                    {
                        throw new Exception($"Cloning for context setting type {contextSettings.Type} was not yet implemented");
                    }
                }
                else
                {
                    // Take over the context settings, this is needed if we later on want to clone this context to a different audience
                    contextSettings.SiteUrl = newSiteUrl;
                    clonedClientContext.AddContextSettings(contextSettings);

                    clonedClientContext.ExecutingWebRequest += delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
                    {
                        // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                        // the new delegate method
                        MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                        object[]   parametersArray = new object[] { webRequestEventArgs };
                        methodInfo.Invoke(clientContext, parametersArray);
                    };
                }
            }
            else // Fallback the default cloning logic if there were not context settings available
            {
                //Take over the form digest handling setting

                var originalUri = new Uri(clientContext.Url);
                // If the cloned host is not the same as the original one
                // and if there is an active PnPProvisioningContext
                if (originalUri.Host != siteUrl.Host &&
                    PnPProvisioningContext.Current != null)
                {
                    // Let's apply that specific Access Token
                    clonedClientContext.ExecutingWebRequest += (sender, args) =>
                    {
                        // We get a fresh new Access Token for every request, to avoid using an expired one
                        var accessToken = PnPProvisioningContext.Current.AcquireToken(siteUrl.Authority, null);
                        args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accessToken;
                    };
                }
                // Else if the cloned host is not the same as the original one
                // and if there is a custom Access Token for it in the input arguments
                else if (originalUri.Host != siteUrl.Host &&
                         accessTokens != null && accessTokens.Count > 0 &&
                         accessTokens.ContainsKey(siteUrl.Authority))
                {
                    // Let's apply that specific Access Token
                    clonedClientContext.ExecutingWebRequest += (sender, args) =>
                    {
                        args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accessTokens[siteUrl.Authority];
                    };
                }
                // Else if the cloned host is not the same as the original one
                // and if the client context is a PnPClientContext with custom access tokens in its property bag
                else if (originalUri.Host != siteUrl.Host &&
                         accessTokens == null && clientContext is PnPClientContext &&
                         ((PnPClientContext)clientContext).PropertyBag.ContainsKey("AccessTokens") &&
                         ((Dictionary <string, string>)((PnPClientContext)clientContext).PropertyBag["AccessTokens"]).ContainsKey(siteUrl.Authority))
                {
                    // Let's apply that specific Access Token
                    clonedClientContext.ExecutingWebRequest += (sender, args) =>
                    {
                        args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + ((Dictionary <string, string>)((PnPClientContext)clientContext).PropertyBag["AccessTokens"])[siteUrl.Authority];
                    };
                }
                else
                {
                    // In case of app only or SAML
                    clonedClientContext.ExecutingWebRequest += (sender, webRequestEventArgs) =>
                    {
                        // Call the ExecutingWebRequest delegate method from the original ClientContext object, but pass along the webRequestEventArgs of
                        // the new delegate method
                        MethodInfo methodInfo      = clientContext.GetType().GetMethod("OnExecutingWebRequest", BindingFlags.Instance | BindingFlags.NonPublic);
                        object[]   parametersArray = new object[] { webRequestEventArgs };
                        methodInfo.Invoke(clientContext, parametersArray);
                    };
                }
            }

            return(clonedClientContext);
        }
Exemplo n.º 7
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            this.ModelHost = modelHost;

            if (!(modelHost is SiteModelHost ||
                  modelHost is WebModelHost ||
                  modelHost is ListModelHost))
            {
                throw new ArgumentException("modelHost needs to be SiteModelHost/WebModelHost/ListModelHost instance.");
            }

            CurrentHostClientContext = (modelHost as CSOMModelHostBase).HostClientContext;
            CurrentModelHost         = modelHost.WithAssertAndCast <CSOMModelHostBase>("modelHost", value => value.RequireNotNull());

            HostSite = ExtractSiteFromHost(modelHost);
            HostWeb  = ExtractWebFromHost(modelHost);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Casting field model definition");
            var fieldModel = model.WithAssertAndCast <FieldDefinition>("model", value => value.RequireNotNull());

            Field currentField           = null;
            ClientRuntimeContext context = null;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = null,
                ObjectType       = GetTargetFieldType(fieldModel),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            if (modelHost is ListModelHost)
            {
                var listHost = modelHost as ListModelHost;
                context = listHost.HostList.Context;

                currentField = DeployListField(modelHost as ListModelHost, fieldModel);
            }
            else if (modelHost is WebModelHost)
            {
                var webHost = modelHost as WebModelHost;
                context = webHost.HostWeb.Context;

                currentField = DeployWebField(webHost as WebModelHost, fieldModel);
            }

            else if (modelHost is SiteModelHost)
            {
                var siteHost = modelHost as SiteModelHost;
                context = siteHost.HostSite.Context;

                currentField = DeploySiteField(siteHost as SiteModelHost, fieldModel);
            }
            else
            {
                throw new ArgumentException("modelHost needs to be SiteModelHost/WebModelHost/ListModelHost instance.");
            }

            object typedField = null;

            // emulate context.CastTo<>() call for typed field type
            if (GetTargetFieldType(fieldModel) != currentField.GetType())
            {
                var targetFieldType = GetTargetFieldType(fieldModel);

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Calling context.CastTo() to field type: [{0}]", targetFieldType);

                var method  = context.GetType().GetMethod("CastTo");
                var generic = method.MakeGenericMethod(targetFieldType);

                typedField = generic.Invoke(context, new object[] { currentField });
            }

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = typedField ?? currentField,
                ObjectType       = GetTargetFieldType(fieldModel),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });

            if (fieldModel.PushChangesToLists.HasValue)
            {
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall,
                                     string.Format("UpdateAndPushChanges({0})", fieldModel.PushChangesToLists));

                currentField.UpdateAndPushChanges(fieldModel.PushChangesToLists.Value);
            }
            else
            {
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "UpdateAndPushChanges(true)");
                // Why does SSOM handler distinguish between list and web/site fields and csom doesn't?
                currentField.UpdateAndPushChanges(true);
            }

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()");
            context.ExecuteQueryWithTrace();

            CurrentHostClientContext = null;
        }
Exemplo n.º 8
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            if (!(modelHost is SiteModelHost || modelHost is ListModelHost))
            {
                throw new ArgumentException("modelHost needs to be SiteModelHost/ListModelHost instance.");
            }

            CurrentSiteModelHost = modelHost as SiteModelHost;

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Casting field model definition");
            var fieldModel = model.WithAssertAndCast <FieldDefinition>("model", value => value.RequireNotNull());

            Field currentField           = null;
            ClientRuntimeContext context = null;

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = null,
                ObjectType       = GetTargetFieldType(fieldModel),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });
            InvokeOnModelEvent <FieldDefinition, Field>(currentField, ModelEventType.OnUpdating);

            if (modelHost is SiteModelHost)
            {
                var siteHost = modelHost as SiteModelHost;
                context = siteHost.HostSite.Context;

                currentField = DeploySiteField(siteHost as SiteModelHost, fieldModel);
            }
            else if (modelHost is ListModelHost)
            {
                var listHost = modelHost as ListModelHost;
                context = listHost.HostList.Context;

                currentField = DeployListField(modelHost as ListModelHost, fieldModel);
            }

            object typedField = null;

            // emulate context.CastTo<>() call for typed field type
            if (GetTargetFieldType(fieldModel) != currentField.GetType())
            {
                var targetFieldType = GetTargetFieldType(fieldModel);

                TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Calling context.CastTo() to field type: [{0}]", targetFieldType);

                var method  = context.GetType().GetMethod("CastTo");
                var generic = method.MakeGenericMethod(targetFieldType);

                typedField = generic.Invoke(context, new object[] { currentField });
            }

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioned,
                Object           = typedField ?? currentField,
                ObjectType       = GetTargetFieldType(fieldModel),
                ObjectDefinition = model,
                ModelHost        = modelHost
            });
            InvokeOnModelEvent <FieldDefinition, Field>(currentField, ModelEventType.OnUpdated);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "UpdateAndPushChanges(true)");
            currentField.UpdateAndPushChanges(true);

            TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()");
            context.ExecuteQueryWithTrace();
        }