Question

I'm trying to open an XML file from my document library. I'm running some code as "Elevated Privilege" on a file I know exists.

The code I wrote down is this:

 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);
                            }

                        }
                    }
                });

When I reach the XDocument.Load command I get the "401 Unauthorized" exception..

Is there something wrong with my code? Is XDocument running with wrong pribilege?

Thank you very much

Was it helpful?

Solution

I guess the implementation of XDocument.Load(string) doesn't support an authenticated request to retrieve the XML file.

However, there is another way because the approach that you are taking will mean that each time a document is opened two web requests are being made.

  1. One to build the Url using the SPFile object
  2. To access the SPFile object using the Url built in step 1.

How about instead of building the fileUrl variable you use another overload of the XDocument.Load()? This time instead of the Uri pass in a Stream object.

You have all the information that you need and could do something like this:-

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

I haven't tried the code but let us know how you get on. Also run SPDisposeCheck to make sure that this isn't causing any memory leaks.

OTHER TIPS

I found out that, with the right conversions I can manage the stream as I am in a "normal" app.

The code I use now (and works is:

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
                            }

                        }
                    }
                });

Simon Doy's method did not work for me - I get errors if I read in a stream into an XDocument.Load() method - "The best overloaded method match for 'System.Xml.Linq.XDocument.Load(System.Xml.XmlReader)' has some invalid arguments" and "Argument '1': cannot convert from 'System.IO.Stream' to 'System.Xml.XmlReader'"

Now granted, I was trying to pull in an XML file I had just added to the folder structure of a SharePoint site using SharePoint Designer, instead of a file in a document library, but it appears to me the difference of passing a StreamReader is very important, since I was able to get it to work when using Ziba's method, but it would not accept a Stream - it only has uri, TextReader, or XmlReader options (which can be in the form of a 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
            }
        }
    });

This has been tested and works.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top