Question

Ceci est une question pour un gourou WSS / SharePoint.

Envisagez le scénario suivant: je dispose d’un service Web ASP.Net qui relie notre système CRM d’entreprise à un intranet basé sur WSS. Ce que j'essaie de faire est de fournir une nouvelle collection de sites WSS chaque fois qu'un nouveau client est ajouté au système CRM. Pour que cela fonctionne, je dois ajouter par programme le chemin d'accès géré à la nouvelle collection de sites. Je sais que cela est possible via le modèle objet, mais lorsque je l'essaie dans mon propre service Web, cela échoue. Exemple de code extrait ci-dessous:


Dim _ClientSiteUrl As String = "http://myintranet/clients/sampleclient"

        Using _RootWeb As SPSite = New SPSite("http://myintranet")

            Dim _ManagedPaths As SPPrefixCollection = _RootWeb.WebApplication.Prefixes

            If Not (_ManagedPaths.Contains(_ClientSiteUrl)) Then

                _ManagedPaths.Add(_ClientSiteUrl, SPPrefixType.ExplicitInclusion)

            End If

        End Using

Ce code échoue avec une exception NullReferenceException sur SPUtility.ValidateFormDigest (). La recherche a suggéré que cela pouvait être dû à des privilèges insuffisants. J'ai essayé d'exécuter le code dans un bloc de privilèges élevés à l'aide de SPSecurity.RunWithElevatedPrivileges (AddressOf AddManagedPath), où AddManagedPath est une procédure Sub contenant l'exemple de code ci-dessus.

Cela échoue alors avec une exception InvalidOperationException. & "L'opération n'est pas valide en raison de l'état actuel de l'objet. &";

Où vais-je mal?

Une solution de contournement que j'ai réussi à faire est d'appeler STSADM.EXE via Process.Start (), en fournissant les paramètres requis, et cela fonctionne.

Mettre à jour: lors du développement du service Web, je l'exécute à l'aide du serveur Web intégré Visual Studio 2005 - dans quel contexte de sécurité s'exécutera-t-il? Puis-je changer le contexte de sécurité en mettant des entrées dans web.config?

Mise à jour: je pense que le problème est certainement lié à la non exécution du service Web dans le contexte de sécurité SharePoint approprié. J'ai décidé d'utiliser la solution de contournement que j'ai suggérée et de masquer STSADM. Toutefois, pour ce faire, l'identité du pool d'applications sous laquelle le service Web s'exécute doit être un membre des administrateurs SharePoint.

Était-ce utile?

La solution

Mettre à jour Je pense que vous avez prouvé que le problème n’est pas lié au code.

SPSecurity.RunWithElevatedPrivileges: normalement, le code de l'application Web SharePoint s'exécute avec les privilèges de l'utilisateur qui effectue l'action. RunWithElevatedPrivileges exécute le code dans le contexte du compte de pools d'applications Web SharePoint (je pense). La description de MSDN pourrait entrer dans le détaille un peu plus.

Le problème avec l'appel peut provenir du fait que le service Web n'exécute pas le code dans un processus SharePoint. Expliquez donc pourquoi il ne peut pas élever (alerte de devinette).

Essayez de changer d'utilisateur de votre pool d'applications de services Web et voyez si cela vous donne du plaisir.

Il est probable qu'il s'agisse d'un problème d'autorisations. Essayez peut-être:

Dim clientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using SPSite = new SPSite(clientSiteUrl) 
    webApp As SPWebApplication = SPWebApplication.Lookup(new Uri(clientSiteUrl));
    If Not (webApp.Prefixes.Contains(clientSiteUrl)) Then
        webApp.Prefixes.Add(clientSiteUrl, SPPrefixType.ExplicitInclusion)
    End If
End Using

Ce n'est pas un code exact.

Autres conseils

Le code ci-dessus n'étant pas le code exact, voici le code de travail exact pour une fonctionnalité tronquée d'application Web dans l'événement Feature Activated:

Lors de l'activation de la fonctionnalité sur la page des fonctionnalités de l'application Web Mange, l'activation de cette fonctionnalité créera un nouveau chemin géré Explicit dans l'application Web spécifiée (je souhaite remplacer le codage en dur, éventuellement par Properties.Feature.Parent ou quelque chose de similaire.)

using (SPSite site = new SPSite("http://dev-moss07-eric/PathHere")) {
    SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
    if (webApp.Prefixes.Contains("PathHere"))
    {
        //
    }
    else
    {
        webApp.Prefixes.Add("PathHere", SPPrefixType.ExplicitInclusion);
    }
}

Le code peut probablement être amélioré, mais c’est ma tentative de convertir le code ci-dessus.

Si vous souhaitez créer un chemin d'accès géré (explicite) et une collection de sites sur ce chemin, procédez comme suit:

using (SPSite site = new SPSite("http://dev-moss07-eric")) {
                SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
                if (webApp.Prefixes.Contains("ManagedPathHere"))
                {
                    //
                }
                else
                {
                    webApp.Prefixes.Add("ManagedPathHere", SPPrefixType.ExplicitInclusion);
                }
                using (SPWeb web = site.OpenWeb())
                {
                    SPWebApplication webApplication = web.Site.WebApplication;
                    try
                    {
                        webApplication.Sites.Add("ManagedPathHere","Site Title Here","This site is used for hosting styling assets.", 1033, "STS#1", "6scdev\\eric.schrader", "Eric Schrader", "eric.schrader@6sc.com");
                    }
                    catch (Exception ex)
                    {
                        //ex.ToString;
                    }
                }
            }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top