SQL Reporting Service and SharePoint 2007 - For security reasons DTD is prohibited in this XML document

Friday, 22 May 2009 02:11 by RanjanBanerji

I had setup SQL reporting Service with SharePoint Integration and everything has been working fine.  Well, until a few days ago when I installed Project Server 2007.  I have three environments and the combination of Project Server 2007, SharePoint 2007, and SQL Reporting Service 2005 worked fine on two.  But on one of my development environments I started to get a strange error each time I would try to launch a report.  The error being:

“For security reasons DTD is prohibited in this XML document. To enable DTD processing set the ProhibitDtd property on XmlReaderSettings to false and pass the settings into XmlReader.Create method."

After searching the web I found that the most common explanation for this error is when the server is running out of memory.  I didn’t quite think that was the problem in my case.  Why?  Well I had the same reports working in two other environments, plus I created a simple report that executed a simple query to get one row of data and that too triggered the error.  Plus the machine had plenty of memory.  What was irritating is that neither the SQL Reporting Server logs nor the SharePoint ULS logs and for that matter the Event Logs showed any error.

Based on prior SharePoint experience I figured that this error is the result of some other error that was not handled correctly and then some code tried to parse the exception thinking it was XML and blew up.  Anyway, after much head scratching and analysis of my servers I finally found the culprit.  I am not sure how this happened but in IIS the default web site that hosted the report server virtual directory the following two account groups no longer had any permissions:

 

SQLServer2005ReportingServicesWebServiceUser$COMPUTER_NAME$MSSQLSERVER

SQLServer2005ReportServerUser$COMPUTER_NAME$MSSQLSERVER

 

Once assigned read, write permissions on the default side (cascading) the error vanished and everything was back to normal.

Categories:   SQL Server | SharePoint
Actions:   E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

SharePoint Harvester

Thursday, 13 November 2008 23:27 by RanjanBanerji

Often one has to write code to loop through all of SharePoint to make some sort of a sweeping change. Making such changes directly in the database is a bad idea and is not supported by Microsoft. So the best way to do so is to use the SharePoint WSS object model. SharePoint Harvester hopefully will make it easier to do so by providing a recursive traversal of a SharePoint application firing events when a site, list, item etc is found.

The SharePoint harvester code is really simple and can be accessed from http://www.codeplex.com/SharePointHarvester.  I am not going to start discussing the code itself.  Simple recursion and when webs, lists, items, etc are found it calls a virtual method and fires an event.  This way a user may choose to inherit from this class and override some methods or they can subscribe to relevant events.

So for example if you want to turn off versioning for every list in on every site in an application.  How would you do that?  You could go through the UI and browse to each site and each list and then turn off versioning for that list.  What if you had 500 sites each with 10 lists.  That is a lot of work.  Using SharePointHarvester you could do something like:

public void TurnOffVersioning() {
    SiteHarvester siteHarvester = new SiteHarvester();

    siteHarvester.Url = "http://some.sharepoint.url";
    siteHarvester.Recursive = true;

    siteHarvester.ListFound += new ListFoundHandler( siteHarvestor_ListFound );
    siteHarvester.RunHarvester();

}

void siteHarvestor_ListFound( object sender, ListFoundEventArg e ) {
    e._list.EnableVersioning = false;
    e._list.Update();
}

You do not have to run this code for the entire application.  The URL you provide could easily have been for some sub site, for example:

siteHarvester.Url = "http://some.sharepoint.url/SomeSite/SomeSubSite";

Harvester will now only get lists for SomeSubSite and all its descendant sites.  As you can see, it makes life a lot easier instead of having to write the recursive code over and over.  More complex situations can now be handled.  For example what if you wanted to check-in all images that have been checked out across the entire application, or delete versions of all images because you are suffering from DB bloat.

More examples will follow.