Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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

share|improve this question
add comment

3 Answers 3

up vote 2 down vote accepted

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.

share|improve this answer
    
Depending on the size of the document, you may want to save the file to memory first, then try XDocument.Parse. That will separate your two proceses: 1. Downloading the file, and 2. Parsing the Xml document. –  Russell Feb 5 '13 at 3:18
1  
Thanks Russell a good point. –  Simon Doy Feb 5 '13 at 20:05
add comment

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
                            }

                        }
                    }
                });
share|improve this answer
1  
This is pretty much the same answer as @Simon Doy s, except you are passing a StreamReader instead. –  Russell Feb 5 '13 at 22:44
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.