Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use SqlServer.Types / spatial types within ASP.NET Core 1.0 application

One of our class libraries uses the Microsoft spatial types like DbGeography. When running our application on a clean machine without older versions of SQL Server and Visual Studio, we get this exception:

Spatial types and functions are not available for this provider because the assembly 'Microsoft.SqlServer.Types' version 10 or higher could not be found.

The solution is apparently to install this nuget package:

Install-Package Microsoft.SqlServer.Types

After installing, the nuget package gives instructions on how to reference the DLLs from each project type:

To deploy an application that uses spatial data types to a machine that does not have 'System CLR Types for SQL Server' installed you also need to deploy the native assembly SqlServerSpatial110.dll.

Both x86 (32 bit) and x64 (64 bit) versions of this assembly have been added to your project under the SqlServerTypes\x86 and SqlServerTypes\x64 subdirectories. The native assembly msvcr100.dll is also included in case the C++ runtime is not installed.

You need to add code to load the correct one of these assemblies at runtime (depending on the current architecture).

ASP.NET applications For ASP.NET applications, add the following line of code to the Application_Start method in Global.asax.cs: SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));

Desktop applications For desktop applications, add the following line of code to run before any spatial operations are performed: SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);

The nuget package project site is unresponsive, so I'm not sure this is the best approach to use now in 2016.

My problem is, I can't figure out how to call LoadNativeAssemblies from an ASP.NET Core 1.0 application. We're using the full framework (net461) and not the core framework.

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        ...
        SqlServerTypes.Utilities.LoadNativeAssemblies(env.WebRootPath);
        ...
    }
}

What is the best way to include the SqlServer.Types dll files within an ASP.NET 1.0 application?

Related questions here and here on StackOverflow.

Many thanks.

like image 793
Ender2050 Avatar asked Aug 12 '16 02:08

Ender2050


2 Answers

I got this working on an ASP.NET Core application today (.NET Framework underneath, not .NET Core, same as the original poster).

The thing I noticed is that adding the Nuget package directly to my ASP.NET Core site yielded no additional files. Not sure if the packages were ever updated to work with ASP.NET Core?

At any rate, I just added the package to a traditional .NET Framework 4.x project and ripped out the SqlServerTypes folder it creates, then put that folder in the root of my ASP.NET Core project. Changed the Copy to Output Dicrectory property for all 4 DLLs underneath from Do not copy to Copy Always, and added the call to the LoadLibrary().

It's worth noting that the 14.x version of the package is actually SQL vNext which is not out, it should have been marked as a pre-release in my mind. I stuck with 13.x since we're using SQL 2016.

Originally I had put this in the Program.cs file, as it didn't have anything to do with the Middleware, ServiceInjection or hosting Configuration setup. But then you have to get the Path to pass in from reflection, which felt ugly. So I put it as the first line of the Startup constructor instead, since from there I can use the HostingEnvironment path.

public Startup(IHostingEnvironment env)
{
    SqlServerTypes.Utilities.LoadNativeAssemblies(env.ContentRootPath);

    //The normal config as usual down here...
    var configuration = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
}
like image 173
Nick Albrecht Avatar answered Oct 10 '22 23:10

Nick Albrecht


i fix this with a bindingRedirect in web.config file.

  <dependentAssembly>
    <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-14.0.0.0" newVersion="14.0.0.0" />
  </dependentAssembly>

im using SQL 2016, ASP.NET (no core) and EF 6.0.0.0

like image 42
emo Avatar answered Oct 11 '22 01:10

emo