ODP.NET Managed library does resolve alias, but 32-bit library does

前端 未结 2 1289
悲&欢浪女
悲&欢浪女 2020-12-07 06:21

I have 32-bit drivers installed on my box (they were installed and configured by some DBAs)

I wrote a simple script to test the drivers which pretty much is as follo

相关标签:
2条回答
  • 2020-12-07 06:32

    May this workaround is suitable for you. You can query the LDAP server by your own and put the full connection string to your code.

    You can resolve the connection string from LDAP with this code:

    using (OracleConnection connection = new OracleConnection())
    {
        connection.ConnectionString = "Data Source=" + ResolveServiceNameLdap("alias") + ";User id=user;Password=password";
        connection.Open();
    }
    

    ...

      private static string ResolveServiceNameLdap(string serviceName)
      {
         string tnsAdminPath = Path.Combine(@"C:\oracle\network", "ldap.ora");
         // or something more advanced...
    
         // ldap.ora can contain many LDAP servers
         IEnumerable<string> directoryServers = null;
    
         if ( File.Exists(tnsAdminPath) ) {
            string defaultAdminContext = string.Empty;
    
            using ( var sr = File.OpenText(tnsAdminPath) ) {
               string line;
    
               while ( ( line = sr.ReadLine() ) != null ) {
                  // Ignore comments or empty lines
                  if ( line.StartsWith("#") || line == string.Empty )
                     continue;
    
                  // If line starts with DEFAULT_ADMIN_CONTEXT then get its value
                  if ( line.StartsWith("DEFAULT_ADMIN_CONTEXT") )
                     defaultAdminContext = line.Substring(line.IndexOf('=') + 1).Trim(new[] { '\"', ' ' });
    
                  // If line starts with DIRECTORY_SERVERS then get its value
                  if ( line.StartsWith("DIRECTORY_SERVERS") ) {
                     string[] serversPorts = line.Substring(line.IndexOf('=') + 1).Trim(new[] { '(', ')', ' ' }).Split(',');
                     directoryServers = serversPorts.SelectMany(x => {
                        // If the server includes multiple port numbers, this needs to be handled
                        string[] serverPorts = x.Split(':');
                        if ( serverPorts.Count() > 1 )
                           return serverPorts.Skip(1).Select(y => string.Format("{0}:{1}", serverPorts.First(), y));
    
                        return new[] { x };
                     });
                  }
               }
            }
    
            // Iterate through each LDAP server, and try to connect
            foreach ( string directoryServer in directoryServers ) {
               // Try to connect to LDAP server with using default admin contact
               try {
                  var directoryEntry = new DirectoryEntry("LDAP://" + directoryServer + "/" + defaultAdminContext, null, null, AuthenticationTypes.Anonymous);
                  var directorySearcher = new DirectorySearcher(directoryEntry, "(&(objectclass=orclNetService)(cn=" + serviceName + "))", new[] { "orclnetdescstring" }, SearchScope.Subtree);
                  SearchResult searchResult = directorySearcher.FindOne();
                  var value = searchResult.Properties["orclnetdescstring"][0] as byte[];
                  if ( value != null )
                     connectionString = Encoding.Default.GetString(value);
    
                  // If the connection was successful, then not necessary to try other LDAP servers
                  break;
               } catch {
                  // If the connection to LDAP server not successful, try to connect to the next LDAP server
                  continue;
               }
            }
    
            // If casting was not successful, or not found any TNS value, then result is an error 
            if ( string.IsNullOrEmpty(connectionString) ) 
               throw new Exception("TNS value not found in LDAP");
    
         } else {
            // If ldap.ora doesn't exist, then throw error 
            throw new FileNotFoundException("ldap.ora not found");
         }
    
         return connectionString;
      }
    
    0 讨论(0)
  • 2020-12-07 06:46

    ODP.NET Managed driver relies on TNS_ADMIN value being set in the config file to find the TNSNAMES.ORA file. If you don't want to set that value, you can include the TNSNAMES.ORA file in the working directory of the executable or create a TNS alias in the config file directly.

    Edit: If you are relying on SQLNET.ORA and LDAP.ORA you can also copy those into the working directory as well, or set the LDAP parameters in your config file. See the ODP.NET doc for the config file parameters available for LDAP.

    0 讨论(0)
提交回复
热议问题