Como criar um caminho gerenciado através do modelo de objeto do SharePoint
-
20-08-2019 - |
Pergunta
Esta é uma pergunta para um guru WSS/SharePoint.
Considere este cenário: tenho um serviço da web ASP.NET que vincula nosso sistema corporativo de CRM e intranet baseado em WSS. O que estou tentando fazer é provisionar uma nova coleção de sites WSS sempre que um novo cliente é adicionado ao sistema CRM. Para fazer isso funcionar, preciso adicionar programaticamente o caminho gerenciado à nova coleção de sites. Sei que isso é possível através do modelo de objeto, mas quando eu o tento no meu próprio serviço da web, ele falha. Extrato de código de exemplo abaixo:
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
Este código falha com uma NullReferenceException no Sputility.ValidateFormDigest (). Pesquisas sugeriram que isso pode ser devido a privilégios insuficientes, tentei executar o código dentro de um bloco de privilégios elevados usando o SpSecurity.RunwithelevatedPrivileges (endereço do addManagedPath), onde o AddManagedPath é um sub -procedimento que contém a amostra de código acima.
Isso falha com um invalidoperationException, "a operação não é válida devido ao estado atual do objeto".
Onde eu estou errando?
Uma solução alternativa que consegui fazer é chamar para StsadM.EXE via process.start (), fornecendo os parâmetros necessários e isso funciona.
Atualizar: Enquanto desenvolve o serviço da web, estou executando -o usando o servidor web do Visual Studio 2005 interno - em qual contexto de segurança isso estará em execução? Posso mudar o contexto de segurança colocando entradas no web.config?
Atualizar: Eu acho que o problema é definitivamente a ver com não executar o serviço da web no contexto de segurança do SharePoint correto. Decidi ir com a solução alternativa que sugeri e desembolsar para o STSADM, embora, para fazer isso, a identidade do pool de aplicativos em que o serviço da web executa deve ser um membro dos administradores do SharePoint.
Solução
AtualizarEu acho que você provou que o problema não está no código.
SpSecurity.RunWithelevatedPrivileges: Normalmente, o código no aplicativo da Web do SharePoint é executado com os privilégios do usuário tomar a ação. O RunwithelevatedPrivileges executa o código no contexto da conta do SharePoint Web Application Pools (eu acho) a descrição em Msdn poderia entrar nos detalhes um pouco mais.
O problema com a chamada pode ser que o serviço da Web não esteja realmente executando o código em um processo do SharePoint, portanto, explicando por que ele não pode elevar (Wild Guess Alert).
Faça uma rachadura em alterar o usuário do seu pool de aplicativos de serviços da Web e veja se isso dá alguma alegria.
É provável que seja um problema de permissões. Talvez tente:
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
Este não é um código exato.
Outras dicas
Como o código acima não é o código exato, aqui está o código de trabalho exato para um recurso de aplicativo da Web no evento ativado pelo recurso:
Na ativação do recurso na página Recursos de aplicativos da Web da mange, o recurso Activate criará um novo caminho gerenciado explícito no aplicativo da web especificado (quero substituir a codificação dura, talvez pelo Properties.Feature.parent ou algo semelhante.)
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);
}
}
O código provavelmente pode ser aprimorado, mas é minha tentativa de converter o código acima.
Se você deseja criar um caminho gerenciado (explícito) e uma coleção de sites nesse caminho, faça o seguinte:
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;
}
}
}