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

Method not found: System.String System.String.TrimStart() exception #850

Closed
halcwb opened this issue Dec 14, 2020 · 13 comments
Closed

Method not found: System.String System.String.TrimStart() exception #850

halcwb opened this issue Dec 14, 2020 · 13 comments

Comments

@halcwb
Copy link

halcwb commented Dec 14, 2020

Describe the bug

Completely out of the blue I am no longer able to use the SqlDataClient in a script file getting the below error. I had previously problems to get things up and running, but managed it with setting the reference to the runtimes/win SqlDataClient dll and

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true)

See: #645.

Then suddenly out of the blue I get the below error:

Exception message:
Stack trace:
    System.MissingMethodException: Method not found: 'System.String System.String.TrimStart()'.
   at Microsoft.Data.LocalDBAPI.GetLocalDbInstanceNameFromServerName(String serverName)
   at Microsoft.Data.SqlClient.SqlConnectionString..ctor(String connectionString) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.cs:line 286
   at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs:line 140
   at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions) in /_/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs:line 230
   at Microsoft.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs:line 71
   at Microsoft.Data.SqlClient.SqlConnection.set_ConnectionString(String value) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 517
   at DustyTables.SqlModule.getConnection(SqlProps props)
   at DustyTables.SqlModule.execute[t](FSharpFunc`2 read, SqlProps props)
      {Data = dict [];
       HResult = -2146233069;
       HelpLink = null;
       InnerException = null;
       Message = "Method not found: 'System.String System.String.TrimStart()'.";
       Source = "Microsoft.Data.SqlClient";
       StackTrace = "   at Microsoft.Data.LocalDBAPI.GetLocalDbInstanceNameFromServerName(String serverName)
   at Microsoft.Data.SqlClient.SqlConnectionString..ctor(String connectionString) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.cs:line 286
   at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs:line 140
   at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions) in /_/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs:line 230
   at Microsoft.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs:line 71
   at Microsoft.Data.SqlClient.SqlConnection.set_ConnectionString(String value) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 517
   at DustyTables.SqlModule.getConnection(SqlProps props)
   at DustyTables.SqlModule.execute[t](FSharpFunc`2 read, SqlProps props)";
       TargetSite = System.String GetLocalDbInstanceNameFromServerName(System.String);}

To reproduce

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true)

let connStr ="Data Source=PC047133;Integrated Security=True;"
new SqlConnection(connStr)

And I get the error.

And just to be sure, I also copied a runtime nsi dll to the nuget cache folder for the runtime SqlDataClient.

Expected behavior

The connection to be created.

Further technical details

.NET SDK (reflecting any global.json):
Version: 5.0.100
Commit: 5044b93829

Runtime Environment:
OS Name: Windows
OS Version: 6.1.7601
OS Platform: Windows
RID: win7-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.100\

Host (useful for support):
Version: 5.0.0
Commit: cf258a14b7

.NET SDKs installed:
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.801 [C:\Program Files\dotnet\sdk]
2.2.301 [C:\Program Files\dotnet\sdk]
2.2.401 [C:\Program Files\dotnet\sdk]
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.101 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
5.0.100 [C:\Program Files\dotnet\sdk]

@karinazhou
Copy link
Member

Hi @halcwb ,

Have you tried your application with .NET Core 3.1 instead of .NET 5? Do you get the same System.MissingMethodException?

And another thing you can try is to comment out all the Microsoft.Data.SqlCient related stuff and just call String.TrimStart() in your application to see whether you still get the exception or not.

Thanks,

@halcwb
Copy link
Author

halcwb commented Dec 15, 2020

@karinazhou. Thanks for the quick reply:

  1. I tried all netstandard2.1 and 2.0. I never got it working with .netcore 3.1 or higher.
  2. String.Trim() just works with regular code.

The problem is the dependency resolution using FSI. But not being able to use the FSI is a real pain for an F# developer (at least for me), as it enables me to quickly develop in a REPL cycle.

I also tried using net472, but then I get (with the AppContext.SetSwitch):

System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.TdsParser' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNILoadHandle' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'Microsoft.Data.SqlClient.SNI.x64.dll': Kan opgegeven module niet vinden. (Exception from HRESULT: 0x8007007E)
at Microsoft.Data.SqlClient.SNINativeManagedWrapperX64.SNIInitialize(IntPtr pmo)
at Microsoft.Data.SqlClient.SNILoadHandle..ctor() in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParserSafeHandles.cs:line 19
at Microsoft.Data.SqlClient.SNILoadHandle..cctor() in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParserSafeHandles.cs:line 17
--- End of inner exception stack trace ---
at Microsoft.Data.SqlClient.TdsParser..cctor() in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParser.cs:line 177
--- End of inner exception stack trace ---
at Microsoft.Data.SqlClient.TdsParser..ctor(Boolean MARS, Boolean fAsynchronous) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\TdsParser.cs:line 38
at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlInternalConnectionTds.cs:line 1827
at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlInternalConnectionTds.cs:line 1714
at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, ServerCertificateValidationCallback serverCallback, ClientCertificateRetrievalCallback clientCallback, DbConnectionPool pool, String accessToken, SqlClientOriginalNetworkAddressInfo originalNetworkAddressInfo, Boolean applyTransientFaultHandling) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlInternalConnectionTds.cs:line 537
at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnectionFactory.cs:line 145
at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionFactory.cs:line 163
at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionPool.cs:line 943
at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionPool.cs:line 2007
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionPool.cs:line 1412
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) in H:\tsaagent1\_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionPool.cs:line 1295 at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionFactory.cs:line 354
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) in H:\tsaagent1\_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\ProviderBase\DbConnectionInternal.cs:line 768 at Microsoft.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource1 retry) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 2045
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 2016
at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides) in H:\tsaagent1_work\18\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 1577

@halcwb
Copy link
Author

halcwb commented Dec 15, 2020

OK, at last I got it working again:

  1. I have to use the .net framework (using net472, which loads in fact a net461 version).
  2. I have to reference the win runtime, i.e. .nuget\\packages\\microsoft.data.sqlclient\\2.1.0\\runtimes\\win\\lib\\net46\\Microsoft.Data.SqlClient.dll"
  3. I have to copy the Microsoft.Data.SqlClient.SNI.x64.dll to the above folder.
  4. Setting the AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true) is not necessary, and doesn't work anyway.

So, I can't get it running using a netcore version.

@karinazhou
Copy link
Member

@halcwb Thank you for the update.

Yes, AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true) only works for .net core applications and has no impact on .net framework applications.

Though I am not familiar with F# application, it is surprising that the driver doesn't work with .net core version. If you can share a simple sample app that just opens a connection to SQL Server, we can help to look into it and see why it doesn't work for .net core.

@JRahnama
Copy link
Member

JRahnama commented Dec 16, 2020

@halcwb just to make it more clear, I have created an F# application as simple as this :
I am not a F# developer and sorry for any mistake I have made in the code in advance

open System
open Microsoft.Data.SqlClient

[<EntryPoint>]
let main argv =
    AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true)
    let connStr ="Data Source=localhost;Integrated Security=True;"
    let conn = new SqlConnection(connStr)
    conn.Open()
    let state = conn.State
    printf "Connection state = %s" (state.ToString())
    0 // return an integer exit code

I tried this with net5.0, netcoreapp3.1 and net48 and all worked without any issue. Am I missing something?

@halcwb
Copy link
Author

halcwb commented Dec 18, 2020

@JRahnama. Thanks for looking into this, and you are completely right, in compiled code everything works.

But as an F# developper I typically write my code in a script file. This enables quickly running pieces of code and exploring possibilities. So when you run the code in a script file you need to reference all necessary libraries. Normally this is without a problem, but when libraries depend on local copied other libraries, this fails (or you not to manually figure out what to copy where). So there is no bin folder where everything is put and run from.

So, the problem is trying to use the library from an F# script file.

@JRahnama
Copy link
Member

@halcwb Can you try your code with this PR.

On some other notes, can you tell me how you run your F# script against dotnet framework?
I tried

dotnet fsi --targetprofile:"netstandard"
#r "nuget:Microsoft.Data.SqlClient"
open Microsoft.Data.SqlClient

let constr = "Data Source = localhost; Integrated Security = true;"
new SqlConnection(connstr);;

That did not throw any exception.

@cheenamalhotra
Copy link
Member

cheenamalhotra commented Dec 21, 2020

Even I tried and could not reproduce with both netstandard and netcore:

image

Enabling App Context switch has not effect too and no issues found:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);

Also not reproducible with standard F# Console Apps. All target frameworks work fine!

Can you explain more about your target server so we can confirm we're testing similar env?
I tested with:

  • (local) [Local DB]
  • (localdb)SQLEXPRESS [SQL Express 2019 instance]
  • localhost
  • localhost\\<instance>

@cheenamalhotra cheenamalhotra moved this from Under Investigation to Needs More Info in SqlClient Triage Board Dec 21, 2020
@halcwb
Copy link
Author

halcwb commented Dec 22, 2020

@cheenamalhotra and @JRahnama. Thanks for taking so much trouble to look into this!

I think the main confusion is that I use the FSI available in VS or VSCode. Secondly, indeed with the new #r "nuget: ..." option this seems to work, but this is not available for the VS FSI.

The only available option to directly reference dependencies in a F# script file has been for years paket, With paket you can generate load scripts with the obvious command dotnet paket generate-load-scripts.

I think the whole issue boils down to how the nuget files are arranged and referenced in the script. I realize this isn't directly related to Microsoft.Data.SqlClient, but I am very curious why #r "nuget: ..." works, while loading from the .nuget directory doesn't.

@cheenamalhotra
Copy link
Member

@halcwb

Could you try the fix from #859 to see it it resolves your issue?
You can download NuGet package to test this changeset here: https://dev.azure.com/sqlclientdrivers-ci/sqlclient/_build/results?buildId=21718&view=artifacts&pathAsName=false&type=publishedArtifacts

@halcwb
Copy link
Author

halcwb commented Jan 14, 2021

@cheenamalhotra I am terribly sorry that I didn't reply sooner, while you are trying to help me. My apologies. It's just that I am also very busy and don't have the immediate time to start checking. Hoop I will be able to do that next week.

@cheenamalhotra
Copy link
Member

No problem, let us know when you happen to test the change.

@halcwb
Copy link
Author

halcwb commented Jan 21, 2021

I can confirm that using the fsi directly with dotnet fsi --targetprofile:"netcore" everthing seems to work fine. So, it has to do with VSCode and VS using the FSI and setting the runtime.

I guess I have to wait for better FSI support using the new net5.0.

@halcwb halcwb closed this as completed Feb 8, 2021
SqlClient Triage Board automation moved this from Needs More Info to Closed Feb 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

4 participants