TypeInitializationException при открытии соединения SQL с олицетворением - PullRequest
0 голосов
/ 05 октября 2018

У меня проблема с TypeInitializationException в приложении Windows Form, при открытии SQLconnection при использовании олицетворения (когда олицетворение удалено, все работает), и я не могу понять, как решить проблему.

Вот StackTrace:

   v System.Data.SqlClient.SqlConnection..ctor()
   v System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Initialize(IDataServices dataServices, Object connection)
   v System.Data.Linq.DataContext.Init(Object connection, MappingSource mapping)
   v System.Data.Linq.DataContext..ctor(String fileOrServerOrConnection)
   v CallBackCvop.Persistance.UnitOfWork..ctor(String connectionString)
   v CallBackCvop.MainForm.RefreshOrders()
   v CallBackCvop.MainForm.BTN_Search_Click(Object sender, EventArgs e)
   v System.Windows.Forms.Control.OnClick(EventArgs e)
   v System.Windows.Forms.Button.OnClick(EventArgs e)
   v System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   v System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   v System.Windows.Forms.Control.WndProc(Message& m)
   v System.Windows.Forms.ButtonBase.WndProc(Message& m)
   v System.Windows.Forms.Button.WndProc(Message& m)
   v System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   v System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   v System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   v System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   v System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   v System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   v System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   v System.Windows.Forms.Application.Run(Form mainForm)
   v CallBackCvop.Program.Main()

Вот StackTrace для innerException

   v System.Diagnostics.FileVersionInfo.GetVersionInfo(String fileName)
   v System.Configuration.ClientConfigPaths.SetNamesAndVersion(String applicationFilename, Assembly exeAssembly, Boolean isHttp)
   v System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
   v System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
   v System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record)
   v System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   v System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   v System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
   v System.Data.SqlClient.SqlConnection..cctor()

Вот мой код олицетворения:

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class Impersonation : IDisposable
    {
        private readonly SafeTokenHandle _handle;
        private readonly WindowsImpersonationContext _context;

        const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

        public Impersonation(string domain, string username, string password)
        {
            var ok = LogonUser(username, domain, password,
                           LOGON32_LOGON_NEW_CREDENTIALS, 0, out this._handle);
            if (!ok)
            {
                var errorCode = Marshal.GetLastWin32Error();
                throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode));
            }

            this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
        }

        public void Dispose()
        {
            this._context.Dispose();
            this._handle.Dispose();
        }

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

        public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
        {
            private SafeTokenHandle()
                : base(true) { }

            [DllImport("kernel32.dll")]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            [SuppressUnmanagedCodeSecurity]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool CloseHandle(IntPtr handle);

            protected override bool ReleaseHandle()
            {
                return CloseHandle(handle);
            }
        }
    }

Проблема в том, что я использовал этот код олицетворениядо этого в разных ап и все работало.Я в отчаянии, любая помощь?Спасибо.

Вот строка подключения:

private readonly string _connectionString = "data source = xxx\\xxx; initial catalog = xxx; integrated security=True; MultipleActiveResultSets=True";

Вот открытие:

    using (UnitOfWork frt = new UnitOfWork(_connectionString))
    {
        _outCalls.DownloadOutCalls(frt, _orders.ReturnSetOfNumbers());
    }

UnitOfWork (здесь вы получаете исключение TypeInitializationException):

 public class UnitOfWork : IDisposable
    {
        ....repositories...

        private readonly DataContext _context;


        public UnitOfWork(string connectionString)
        {
            _context = new DataContext(connectionString);


            ....repositories...
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_context != null)
                    _context.Dispose();
            }
        }
    }

Не исключение - FileNotFoundException, но, похоже, оно ссылается на сам файл .exe - я не понимаю этого.

Edit - 8.10.2018 Я обнаружил, чтовсе работает нормально, когда .exe на моем рабочем столе, но не на общем диске внутренней сети.Но олицетворенная учетная запись имеет те же права, что и моя учетная запись.И, как уже было сказано, у меня есть другое приложение, использующее тот же код олицетворения, одну и ту же строку подключения, и все работает как на моем рабочем столе, так и на общем диске.

Edit - 8.10.2018 - 11:00 Так что его сбой.... System.Diagnostics.FileVersionInfo.GetVersionInfo (pathToExe),

  • Я проверил права олицетворенной учетной записи - все в порядке,
  • Я пробовал приложение без олицетворения и мою учетную запись- все в порядке,
  • Я попробовал приложение с олицетворением моей учетной записи (должно работать) - не работает

1 Ответ

0 голосов
/ 08 октября 2018

Итак ... Через некоторое время придумал обходной путь.Кажется, что ошибка была в --- System.Diagnostics.FileVersionInfo.GetVersionInfo (pathToExe), поэтому мой вызов олицетворения переместился из программы в единицу работы.Меняя это так:

public class UnitOfWork : IDisposable
{
    public IOrderRepository Orders { get; }
    public ICallRepository OutCalls { get; }
    public ILoginRepository Login { get; }

    private readonly DataContext _context;


    public UnitOfWork(string connectionString)
    {
        _context = new DataContext(new SqlConnection());

        using (new Impersonation("domain", "user", "password"))
            _context.Connection.ConnectionString = connectionString;

        Orders = new OrderRepository(_context);
        OutCalls = new CallRepository(_context);
        Login = new LoginRepository(_context);
    }

    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_context != null)
                _context.Dispose();
        }
    }
}
...