Фон
У нас есть веб-приложение asp.net 4.0, написанное на C #, которое вызывает веб-сервис .net 3.5, написанное на C #.Веб-службе передается идентификатор пользователя и возвращается список данных в зависимости от групп активных каталогов, к которым принадлежит пользователь.
Веб-служба использует версию System.DirectoryServices.AccountManagement .net 3.5 для получения Sids ofгруппы, к которым принадлежит пользователь.
Вызов UserPrincipal.GetGroups периодически прерывается с ошибкой ниже.Между событиями были очень большие промежутки времени, но когда это происходило, оно повторялось в течение нескольких минут.Эта проблема возникла для разных пользователей AD.
Трассировка стека этого исключения не имела для нас никакого смысла.Мы потратили много времени на просмотр кода Microsoft AD в Reflector / ILSpy, но не смогли выйти за пределы вызова IADsPathName.Retrieve.
Исключение
System.NotSupportedException: Specified method is not supported.
at System.Web.HttpResponseStream.get_Position()
at System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64 offset, Int32 origin)
at System.DirectoryServices.AccountManagement.UnsafeNativeMethods.IADsPathname.Retrieve(Int32 lnFormatType)
at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDomainInfo()
at System.DirectoryServices.AccountManagement.ADStoreCtx.get_DnsForestName()
at System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOf(Principal p)
at System.DirectoryServices.AccountManagement.Principal.GetGroupsHelper()
at System.DirectoryServices.AccountManagement.Principal.GetGroups()
at Data.SoftwarePublishingItemData.GetSids(String requestedForUserId)
at Data.SoftwarePublishingItemData.GetSoftwarePublishingItems(IDatabaseContext dbContext, GetSoftwarePublishingItemsSettings settings, XBXmlDocument parameters)
at Web.GetSoftwarePublishingItems.GetFlexiFieldData(String xml)
Код для воспроизведения
Обратите внимание, что метод CauseNotSupportedException имитирует код, который выполняется не в нашем приложении, а в коде где-то еще в среде, которую мы не контролируем.
class Program
{
static void Main(string[] args)
{
CauseNotSupportedException();
string samAccountName = "domain.user";
using (var principalContext = new PrincipalContext(ContextType.Domain))
{
using (var userPrincipal = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, samAccountName))
{
if (userPrincipal == null)
throw new ActiveDirectoryObjectNotFoundException();
using (var groups = userPrincipal.GetGroups())
{
foreach (GroupPrincipal group in groups)
{
Console.WriteLine(group.Sid);
}
}
}
}
}
public static void CauseNotSupportedException()
{
using (var b = new Bitmap(500, 500, PixelFormat.Format32bppArgb))
{
b.Save(new FakeStream(), ImageFormat.Png);
}
}
}
Реализация Stream для имитации поведения HttpResponseStream
public class FakeStream : Stream
{
public override bool CanRead { get { return false; } }
public override bool CanSeek { get { return false; } }
public override bool CanWrite { get { return true; } }
public override void Flush() { }
public override long Length { get { throw new NotSupportedException("No Seek"); } }
public override long Position
{
get { throw new NotSupportedException("No Seek"); }
set { throw new NotSupportedException("No Seek"); }
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new InvalidOperationException("Write only stream");
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException("net_noseek");
}
public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
}
Вопросы
- Если запустить приведенный выше пример, ошибка возникает вметод CauseNotSupportedException вызывается при вызове GetGroups.Как это может быть?Будем признательны за любые теории или дальнейшее понимание.
- Есть ли какие-либо предложения относительно дальнейших расследований?
- Есть ли какие-либо лучшие предложения, чем перехват исключения и повторная попытка?Это наша текущая работа.
Спасибо.
Уточнение
Я не уверен, насколько ясноЯ был в моем объяснении, так что вот некоторые пояснения.Во-первых, я доволен кодом активной директории, который получает Sids.Это делает то, что я хочу, и я не думаю, что проблема в этом.Реальная проблема заключается в том, что когда ошибка возникает в другом не связанном коде (его нет в нашем приложении), ошибка проявляется в вызове GetGroups, следовательно, странная трассировка стека с ошибкой, первоначально возникающей в System.Web.HttpResponseStream.get_Position ().В примере приложения NotSupportedException возникает в CauseNotSupportedException, но код там не нарушается, он прерывается при вызове GetGroups.Если вы закомментируете CauseNotSupportedException () в примере приложения, ошибка никогда не произойдет.
Мне неясно, как это может произойти.