Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error opening connection: 'String reference not set to an instance of a String' #1

Closed
sanjaybhagia opened this Issue Nov 7, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@sanjaybhagia
Copy link

commented Nov 7, 2018

I'm getting this exception when i try to open up the connection in .net core console application (.NET Core 2.1 on VS2017 Community - v15.8.9) .

Environment:

  • Visual Studio Community 2017 (version 15.8.9)
  • Windows Server 2012 R2 Standard

Exception

System.ArgumentNullException: 'String reference not set to an instance of a String.'

Stack Trace:
at System.Reflection.RuntimeAssembly.GetResource(RuntimeAssembly assembly, String resourceName, UInt64& length, StackCrawlMarkHandle stackMark, Boolean skipSecurityCheck)
at System.Reflection.RuntimeAssembly.GetManifestResourceStream(String name, StackCrawlMark& stackMark, Boolean skipSecurityCheck)
at System.Reflection.RuntimeAssembly.GetManifestResourceStream(String name)
at Microsoft.AnalysisServices.AdomdClient.AadAuthParams.GetResourceAsStream(String resourceName)
at Microsoft.AnalysisServices.AdomdClient.AadAuthParams.ReadLocalSecurityAuthParams()
at Microsoft.AnalysisServices.AdomdClient.AadAuthParams.get_LocalSecurityAuthParams()
at Microsoft.AnalysisServices.AdomdClient.AadAuthParams.FindMatchingAuthParams(String identityProvider, Uri dataSourceUri)
at Microsoft.AnalysisServices.AdomdClient.AadAuthenticator.AcquireToken(Uri dataSourceUri, String dataSource, String identityProvider, String userId, String password, Boolean useAdalCache)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenHttpConnection(ConnectionInfo connectionInfo, Boolean& isSessionTokenNeeded)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenConnection(ConnectionInfo connectionInfo, Boolean& isSessionTokenNeeded)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.Connect(ConnectionInfo connectionInfo, Boolean beginSession)
at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.XmlaClientProvider.Connect(Boolean toIXMLA)
at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.ConnectToXMLA(Boolean createSession, Boolean isHTTP)
at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.Open()
at ConsoleApp1.Program.Main(String[] args) in C:\Users<username>\Source\Repos\ConsoleApp1\ConsoleApp1\Program.cs:line 15

Here is the source code:
//Accessing Analysis service hosted in Azure using connection string string connectionString = "Provider=MSOLAP;Data Source=asazure://westeurope.asazure.windows.net/<server>;Initial Catalog=<catalog>;User ID=<user>;Password=<password>" using(AdomdConnection connection = new AdomdConnection(connectionString)) { connection.Open(); }

I did try it with query as well but the same error.

@bdebaere bdebaere self-assigned this Nov 7, 2018

@bdebaere

This comment has been minimized.

Copy link
Owner

commented Nov 7, 2018

The error is very cryptic. By specifying a username and password in the connection string the code detects you want to connect using the user name and password flow. This flow is deprecated in .NET Core (see https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Acquiring-tokens-with-username-and-password) and thus cannot be used anymore to connect to Azure Analysis Services (AAS).

Instead in .NET Core you have to drop the user name and password flow in favor of other authentication flows which you can find by using ADAL.NET's AcquireTokenAsync functions. Note that when using these authentication flows the User Id property of the connection string is always empty and the token is always set in the Password property.

For example this is one flow you could use:

           try
           {
                var authority = "<authority>";
                var authenticationContext = new AuthenticationContext(authority);
                var resource = "https://westeurope.asazure.windows.net";
                var clientId = "<client id of your AAS resource>";
                var clientSecret = "<client key of your AAS resource>";
                var result = await authenticationContext.AcquireTokenAsync(resource, new ClientCredential(clientId, clientSecret));
                var connectionString = $"Provider=MSOLAP;Data Source=asazure://westeurope.asazure.windows.net/server;Initial Catalog=<catalog>;User Id=;Password={result.AccessToken};Persist Security Info=True;Impersonation Level=Impersonate";
            }
            catch (Exception)
            {
                // Handle the exception.
            }

But it is definitely not limited to this one, you can go over all the AuthenticationContext.AcquireTokenAsync functions to see which one fits your scenario. I personally use the on behalf of token flow since my AAS is called via a web API.

@sanjaybhagia

This comment has been minimized.

Copy link
Author

commented Nov 9, 2018

This was a great help bdebaere!
I used app permission for my tests for now but look into other flows for authentication
I had to stuggle a bit as i was using my personal account with Azure, which i couldn't get it to work entirely (couldn't connect SQL Server Management Studio to access Analysis Services to assign the role) but it worked fine with corporate account.

Thanks a ton for pointing into the right direction

Regards
Sanjay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.