Почему веб-часть перестала работать в конструкторе при первом добавлении на страницу? - PullRequest
1 голос
/ 18 марта 2009

Этот вопрос немного конкретен (MOSS2007), и я не очень надеюсь получить ответ, но, возможно, удача улыбнется мне.

У меня есть веб-часть, которая работает, за исключением в самый первый раз , который добавляется на страницу. Он выдает исключение внутри конструктора , когда я пытаюсь открыть соединение с сервером SQL. Требование разрешения SqlClientPermission не выполняется. Когда я говорю, что это работает, я имею в виду, что оно правильно зарегистрировано в любом отношении и работает в любом другом случае, включая последующие вызовы.

Кто-то сказал, что выхода нет. Я хотел бы знать почему. Это по замыслу?

Я зашел так далеко, что дал полное доверие всему, что мог (изменил каждый .config файл, который смог найти на своем сервере), но это не помогло.

Похоже, что SharePoint делает что-то вроде удаленного взаимодействия при первом добавлении веб-части, которая запускается с минимальным доверием при первом создании (то же, что определено в web_minimaltrust.config для ASP.Net). Попытки предоставить разрешения на все во всем не дали никаких плодотворных результатов.

Моим решением было перенести код доступа к данным в метод OnInit, но это раздражает. У кого-нибудь есть понимание?

Спасибо.

Некоторая дополнительная информация от отладчика.

Единственными разрешенными разрешениями были:

<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>

Внутренний стек исключений:

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()

Полный стек:

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    

... остальная часть стека такая же, как при обычном открытии страницы.

Ответы [ 5 ]

2 голосов
/ 18 марта 2009

Попробуйте настроить пакет решений для развертывания настроек безопасности доступа к коду. Вам определенно нужен SqlClientPermission. Посмотрите мой пост на Code Access Security для веб-частей для получения дополнительной информации.

1 голос
/ 13 октября 2011

Так же, как справочник для следующих, здесь есть одна из многих статей, где код в конструкторе веб-частей помечен как большой НЕТ-НЕТ .

1 голос
/ 12 августа 2011

Моим решением было перенести код доступа к данным в метод OnInit, но это раздражает. У кого-нибудь есть понимание?

Когда SharePoint обрабатывает и обрабатывает запрос, первое, что он будет делать, - это выполнение вашего конструктора для создания нового экземпляра объекта. Конструкторы, которые он вызывает, не имеют параметров, поэтому их можно сериализовать и десериализовать для импорта / экспорта. Внутри конструктора ни одна из конструкций безопасности или связанных объектов не была установлена ​​во вновь созданном объекте. Поэтому может быть так, что у вашего объекта нет контекстной информации о том, где он живет или что делает.

Переместив свой код в метод OnInit, вы сместили время выполнения назад как некоторые из связанных объектов, а также то, что не было автоматически связано этой точкой. В жизненном цикле ASP.net методы OnInit работают сверху вниз, а методы OnLoad - снизу вверх. Так что это также может повлиять на выполнение кода родителем или детьми.

1 голос
/ 19 марта 2009

В качестве простого теста вы можете развернуть сборку, содержащую веб-часть, в GAL. Там он будет работать с полным доверием.

Лично я бы не рекомендовал устанавливать соединение с базой данных в конструкторе веб-части, если у вас нет веских причин для этого.

[обновлено 3009-03-27]

Отладка часто сводится к исключению причин. Даже если вы считаете, что веб-часть работает в режиме полного доверия, я рекомендую протестировать дело GAC. Не забудьте удалить .dll из каталога Bin для теста. Это займет всего 5-10 минут, и вы узнаете , где вы стоите.

1 голос
/ 18 марта 2009

Это странно. Возможно, вы могли бы в особом случае, чтобы ваша веб-часть не выполняла вызов базы данных, когда страница находится в режиме редактирования / дизайна. Разве это не решит твою проблему?

...