Pergunta

Estou tentando abrir um arquivo XML da minha biblioteca de documentos.Estou executando um código como "Privilégio Elevado" em um arquivo que sei que existe.

O código que anotei é este:

 SPSecurity.RunWithElevatedPrivileges(() =>
                {
                    using (SPSite sito = new SPSite("SITE URL"))
                    {
                        using (SPWeb web = sito.OpenWeb())
                        {
                            SPList lista = web.Lists.TryGetList("DOCUMENT LIBRARY NAME");

                            foreach (SPFile file in lista.RootFolder.Files)
                            {
                                String fileUrl = web.Url + "/" + lista.RootFolder.Url + "/" + file.Url;
                                var ret = XDocument.Load(fileUrl);
                            }

                        }
                    }
                });

Quando alcanço o comando XDocument.Load, recebo a exceção "401 Unauthorized".

Há algo errado com meu código?O XDocument está sendo executado com privilégios errados?

Muito obrigado

Foi útil?

Solução

Acho que a implementação de XDocument.Load(string) não suporta uma solicitação autenticada para recuperar o arquivo XML.

No entanto, existe outra maneira porque a abordagem que você está adotando significa que cada vez que um documento é aberto, duas solicitações da web serão feitas.

  1. Um para construir o URL usando o objeto SPFile
  2. Para acessar o objeto SPFile usando o URL criado na etapa 1.

Que tal em vez de construir a variável fileUrl você usar outra sobrecarga do XDocument.Load()?Desta vez, em vez do Uri passar em um objeto Stream.

Você tem todas as informações de que precisa e pode fazer algo assim: -

SPFileCollection filesInFolder = lista.RootFolder.Files;
foreach(SPFile file in filesInFolder)
{
    using(Stream fileStream = file.OpenBinaryStream())
    {
         XDocument xmlDocument = XDocument.Load(fileStream);
         fileStream.Close()
    }
}

Não tentei o código, mas deixe-nos saber como você se saiu.Execute também SPDisposeCheck para garantir que isso não esteja causando vazamentos de memória.

Outras dicas

Descobri que, com as conversões certas, posso gerenciar o stream como se estivesse em um aplicativo "normal".

O código que uso agora (e funciona é:

SPSecurity.RunWithElevatedPrivileges(() =>
                {
                    using (SPSite sito = new SPSite("SITE URL"))
                    {
                        using (SPWeb web = sito.OpenWeb())
                        {
                            SPList lista = web.Lists.TryGetList("DOCUMENT LIBRARY NAME");

                            foreach (SPFile file in lista.RootFolder.Files)
                            {
                                MemoryStream mStream = new MemoryStream(file.OpenBinary());
                                StreamReader reader = new StreamReader(mStream, true);
                                XDocument documento = XDocument.Load(reader, LoadOptions.None);
                                //MY CODE
                            }

                        }
                    }
                });

O método de Simon Doy não funcionou para mim - eu recebo erros se eu ler em um fluxo em um método XDocument.Load() - "A melhor correspondência de método sobrecarregado para 'System.Xml.Linq.XDocument.Load(System.Xml.XmlReader)' tem alguns argumentos inválidos" e "Argumento '1':não é possível converter de 'System.IO.Stream' para 'System.Xml.XmlReader'"

Certo, eu estava tentando extrair um arquivo XML que acabei de adicionar à estrutura de pastas de um site do SharePoint usando o SharePoint Designer, em vez de um arquivo em uma biblioteca de documentos, mas me parece que a diferença de passar um StreamReader é muito importante, pois consegui fazê-lo funcionar usando o método do Ziba, mas ele não aceitava um Stream - ele só possui as opções uri, TextReader ou XmlReader (que pode ser na forma de StreamReader).

string siteUrl = SPContext.Current.Site.Url;
string xmlpath = siteUrl + @"/includes/XML/myFile.xml";
SPSecurity.RunWithElevatedPrivileges(delegate() 
    {
        using (SPSite site = new SPSite(siteUrl))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPFile file = web.GetFile(xmlpath);
                MemoryStream mStream = new MemoryStream(file.OpenBinary());
                StreamReader reader = new StreamReader(mStream, true);
                XDocument doc = XDocument.Load(reader, LoadOptions.None);
                //MY CODE
            }
        }
    });

Isso foi testado e funciona.

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