简体   繁体   中英

Can an ASP.NET 5 app communicate to MS SQL Server if it runs on Ubuntu?

I created a new ASP.NET 5 web application using the new application wizard in Visual Studio 2015, code on bitbucket here . After a bit of trouble with dnvm runtime setup , I got the sources to run on Ubuntu 14.04 LTS, well enough that the main static html page loads, while dnx web serves up my application. However if I click on the Register link, and try to put an email and password in I get "Error. An error occurred processing your request" on the web UI side, and on the dnx web side, I get this:

error   : [Microsoft.AspNet.Diagnostics.ExceptionHandlerMiddleware] 
An unhandled exception has occurred: Could not load file or assembly 
'System.Data.SqlClient, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. 
The system cannot find the file specified.
...
File name: 'System.Data.SqlClient'
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(AssemblyName assemblyName)
   at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
   at Microsoft.Data.Entity.Storage.Internal.SqlServerConnection.CreateDbConnection()
   at Microsoft.Data.Entity.Internal.LazyRef`1.get_Value()
   at Microsoft.Data.Entity.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at AspNetWebApplication.Controllers.AccountController.EnsureDatabaseCreated(ApplicationDbContext context)
   at AspNetWebApplication.Controllers.AccountController.<Register>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor.<CastToObject>d__8`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.<InvokeActionAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeActionFilterAsync>d__50.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeAsync>d__41.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.<RouteAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Routing.Template.TemplateRoute.<RouteAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Routing.RouteCollection.<RouteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__5.MoveNext()

It appears that lazy initialization is occurring, and that the System.Data.SqlClient class load fails.

The assembly exists in the "dnx cache" at ~/.dnx/packages/System.Data.SqlClient/4.0.0-beta-23409 .

I am assuming that the actual problem must be that the System.Data.SqlClient is not loading because it's actually not compatible with DNX and the Ubuntu coreclr x64 runtime environment. Alternatively perhaps I have to do something else to configure my app (a web.config or environment variable or something?). But in that case I would have expected the class to load, and fail to connect. I was kind of expecting it would try to find an MS SQL LocalDb instance just like it would try to find one on windows, but it doesn't, it just doesn't load, as if the .Net assembly itself was missing.

Update: It is interesting to look at packages like System.Text.Encoding. When NuGet fetches them, it has SEVEN, count-em SEVEN different actual DLLs in its package cache, by platform/os, each copy is in a different subfolder and those folders have these names:

DNXCore50      MonoTouch10  netcore50     xamarinmac20
MonoAndroid10  net46        xamarinios10

I believe that the System.Data.SqlClient, having not shipped any netcoreXX or DNXCoreXX variant folders in its nuget package, makes that package effectively non-portable though without any warning to users. So the class load failure is simply that NuGet has a package with that name, but it doesn't contain a variant folder that can be found and loaded by the coreclr x64 on ubuntu.

Update 19 November

As of ASP.NET 5 RC1 it should now be possible to use coreclr's System.Data.SqlClient on linux provided you have Multiple Active Result Sets turned off. See the release notes on Cross-platform SQL Client here .


It is possible to have ASP.NET 5 running linux communicate to MS MSQL, but perhaps not using the coreclr runtime.

System.Data.SqlClient was only flagged as Done on 14 October in corefx , and beta8 was released October 15. I'm unsure if it ended up being included in beta8 but the error you have posted is the same as that of beta7 which makes me believe the library is still not included. Your investigations also seem to point at this.

If this is the case your only option to run it on linux is using the mono runtime (same as beta7). To do this, remove the "dnxcore50": { } line from your project.json and tell dnvm to target mono rather than coreclr. This then also requires mono (4.1 or later I think) to be installed on your linux box.

If you don't want to install mono on the box, a mono-based aspnet 5 docker image is also an option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM