R – Why would a web part fail on constructor the first time it’s being added to a page

exceptionmosssharepointsharepoint-2007web-parts

This question is a bit specific (MOSS2007) and I don't high hopes for getting an answer, but maybe luck will smile upon me.

I have a web part that works except the very first time it's being added to a page. It throws an exception inside a constructor when I'm trying to open a connection to a SQL server. The demand for the SqlClientPermission permission fails. When I say it works, I mean it is properly registered in any regard and works in every other case, including subsequent calls.

Someone said there is no way out. I'd like to know why. Is it by design?

I went so far as to give a full trust to everything I could (changed every .config file I could find on my server), but it did not help.

It appears that SharePoint is doing some kind of remoting the first time it adds a web part, which appears to run with minimal trust the first time it's constructed (same as defined in web_minimaltrust.config for ASP.Net). Attempts to grant permissions for everything in everything did not yield any fruitful results.

My solution was to move the data access code to the OnInit method, but that is irritating. Does anyone have any insight?

Thank you.

Some extra info from the debugger.

The only permitted permissions were:

<PermissionSet class="System.Security.PermissionSet" version="1">
    <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Execution"/>
    <IPermission class="System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Level="Minimal"/>
</PermissionSet>

The inner exception stack:

hresult = -2146233078
mscorlib
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.PermissionSet.Demand()
at System.Data.Common.DbConnectionOptions.DemandPermission()
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user)
at System.Data.Linq.SqlClient.SqlProvider.get_IsSqlCe()
at System.Data.Linq.SqlClient.SqlProvider.InitializeProviderMode()
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
at IManageDocumentsPart.ClientSideDocumentsWebPart.GetOfficeCode(Int32 employeeId)
at IManageDocumentsPart.ClientSideDocumentsWebPart..ctor()

The full stack:

IManageDocumentsPart.DLL!IManageDocumentsPart.ClientSideDocumentsWebPart.ClientSideDocumentsWebPart() Line 98    C#
[Native to Managed Transition]    
[Managed to Native Transition]    
mscorlib.dll!System.RuntimeType.CreateInstanceSlow(bool publicOnly, bool fillCache = true) + 0x68 bytes    
mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic) + 0x43 bytes    
System.Web.dll!System.Web.HttpRuntime.FastCreatePublicInstance(System.Type type) + 0x56 bytes    
System.Web.dll!System.Web.UI.WebControls.WebParts.WebPartManagerInternals.CreateObjectFromType(System.Type type) + 0x7 bytes    
System.Web.dll!System.Web.UI.WebControls.WebParts.WebPartManager.ImportWebPart(System.Xml.XmlReader reader = {EndElement, Name="metaData"}, out string errorMessage = null) + 0x35d bytes    
Microsoft.SharePoint.dll!Microsoft.SharePoint.WebPartPages.SPWebPartManager.ImportWebPartBase(System.Xml.XmlReader reader = {EndElement, Name="metaData"}, string importErrorMessage = "Cannot import this Web Part.", out string errorMessage = null) + 0x25 bytes    
Microsoft.SharePoint.dll!Microsoft.SharePoint.WebPartPages.WebPartImporter.CreateWebPart(bool clearConnections = true) + 0x1b4 bytes    
Microsoft.SharePoint.dll!Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(Microsoft.SharePoint.WebPartPages.SPWebPartManager manager = {Microsoft.SharePoint.WebPartPages.SPWebPartManager}, System.Xml.XmlReader reader = {None}, bool clearConnections = true, System.Uri webPartPageUri = {http://v-sp2007/testsite/default.aspx?PageView=Shared}, Microsoft.SharePoint.SPWeb spWeb = {Microsoft.SharePoint.SPWeb}) + 0x8e bytes    
Microsoft.SharePoint.dll!Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(Microsoft.SharePoint.WebPartPages.SPWebPartManager manager = {Microsoft.SharePoint.WebPartPages.SPWebPartManager}, System.Xml.XmlReader reader = {None}, bool clearConnections = true, Microsoft.SharePoint.SPWeb spWeb = {Microsoft.SharePoint.SPWeb}) + 0xa1 bytes    
Microsoft.SharePoint.dll!Microsoft.SharePoint.WebPartPages.WebPartQuickAdd.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(string eventArgument = "http%253A%252F%252Fv%252Dsp2007%252F%255Fcatalogs%252Fwp%252FClientSideDocumentsWebPart%252Ewebpart;ClientSideDocumentsWebPart") + 0x288 bytes    
System.Web.dll!System.Web.UI.Page.RaisePostBackEvent(System.Web.UI.IPostBackEventHandler sourceControl, string eventArgument) + 0xc bytes    
System.Web.dll!System.Web.UI.Page.RaisePostBackEvent(System.Collections.Specialized.NameValueCollection postData) + 0xb2 bytes    

…the rest of the stack is the same as when opening a page normally.

Best Answer

Just as a reference for the next ones coming, here there's one of the many articles were code in web part constructor is marked as a big NO-NO.