Using native libraries in ASP.NET 5

In ASP.NET 5 RC1 we are adding a built-in support for native libraries. This may seem a little surprising – all in all ASP.NET 5 is all about managed code running on different platforms. There are, however, scenarios where this managed code needs to talk to unmanaged code. You can find such examples in ASP.NET 5 itself – the Kestrel Http server is build on top of the libuv library and Entity Framework ships a SQLite provider that uses the SQLite library. Before adding support for native libraries developers had to load native libraries on their own and then manually find and expose exported functions. Given the differences between platforms (Windows vs. non-Windows), architectures (x86 vs. x64 vs. ARM) and, possibly, runtimes (desktop Clr vs. CoreClr vs. Mono) the code to achieve the task was non-trivial. With the new feature the idea is that native libraries are shipped in a NuGet package, are part of a referenced project or live in a location where they can be automatically loaded from (e.g. /usr/lib) and the user just uses the DllImport attribute to get access to functions exported by the native library like this:

[DllImport(“mylib”)]
public static extern int get_number();

This is the simplest way of using the DllImport attribute. The name of the native library is passed as the parameter to the DllImport attribute while the exported function will be matched by convention using the name of the method attributed with the DllImport attribute. One important thing to note is that the name of the native library does not contain any filename extension. Both CoreClr and Mono will try appending different filename extensions if they can’t find a library with the exact name provided by the user and they will eventually use the extension specific for the given OS (Mono may also prepend the name with “lib”). Mono on OS X requires using __Internal as the name of the library – see below for more details.

Now, that you know how to consume native libraries in ASP.NET 5 let’s take a look at how to create a NuGet package that contains native libraries that can be consumed using the DllImport attribute. The most important thing is the package structure. Native libraries need to located in the $/runtimes/{runtime-id}/native folder where $ is the root of the package and the {runtime-id} describes the target platform the library is supposed to run on. Runtime Ids is a vast topic and I won’t go into a lot of details here – especially that, currently, they are not fully baked in when using native libraries and project references. For our purposes we can assume that a runtime id consists of the operating system name, version and architecture. For working with native libraries effectively it is enough to know the following runtime ids:

  • win7-x64
  • win7-x86
  • win7-arm
  • osx.10.9-x64
  • osx.10.10-x64
  • osx.10.11-x64

You can find a few oddities in this list. First a runtime id for Linux is missing. This is because you can’t really ship an .so that would work on any distribution of Linux in a package. While there are runtime ids that target selected distros (e.g. ubuntu.14.04-x64) or even just vanilla Linux (linux-x64) the recommended way of using native libraries on Linux is to have the user install the .so in a location from where it can be loaded automatically (e.g. install into /usr/lib or set the LD_LIBRARY_PATH environment variable accordingly). The second oddity is win7-arm. This seems odd because there was never an ARM version of Windows 7. The super-correct runtime to use here is actually win10-arm (ASP.NET 5 is not supported on Windows RT which would be win8-arm or win81-arm). However, if you used win10-arm you would need to remember to explicitly specify the runtime id each time you restore the package or publish your project. If you did not, you wouldn’t get your native library since without providing the runtime id packages will be restored for win7-{arch} (win7-arm in this case). So, because there aren’t any ASP.NET 5 runtimes that can run on pre-Windows 10 version of Windows it is safe to use win7-arm instead of win10-arm and it is much less troublesome. The last oddity is multiple runtime ids for osx. Currently, if you want to support multiple versions of OS X (officially CoreClr supports only OS X 10.10) you need to specify each version separately. Even if you use the same .dylib across all the versions it needs to be copied for each version of OS X you want to support.
For project references you need to use the same folder structure as for packages except that your root is now your project folder (i.e. the folder where the project.json lives).
The dnx repo contains sample projects for testing packages and project with native libraries. This is a good reference point if you ever get stuck.

What’s been covered so far should be enough to get started with native libraries in ASP.NET 5. You now know how to bind to functions exported from native libraries and how to build NuGet packages or structure projects containing native libraries. If you would like to understand how things are implemented under the cover (or need to know how to troubleshoot things) read on.
Loading native libraries works differently on different operating systems. In addition, different runtimes (CoreClr, desktop Clr, Mono) handle native libraries differently as well. CoreClr is consistent across all the platforms – whenever a native library needs to be loaded CoreClr will call ASP.NET 5 first and ask to provide the library. If the library CoreClr is asking for is in one of the referenced packages or projects ASP.NET 5 runtime will load it using a function exposed by CoreClr that allows to load a native library from a path. If you turn on tracing you will see the following trace entries when a native library is loaded:

Information: [LoaderContainer]: Load unmanaged library name=nativelib
Information: [PackageAssemblyLoader]: Loaded unmanaged library=nativelib in 1ms

On non-CoreClr runtimes things are a bit messy because non-CoreClr runtimes keep loading of native libraries to themselves. As a result it takes some tricks to help them load libraries from the right place. On Windows the LoadLibrary WINAPI function searches various locations when looking for a library. The search locations include folders specified in the %PATH% environment variable. So, when running on desktop Clr ASP.NET 5 will prepend the %PATH% environment variable with paths to native libraries. Note that one of disadvantages of this approach it is possible to hit the path length limit if a project references many packages with native libraries and this will most likely cause issues down the road. In traces this looks like this:

Information: [PackageDependencyProvider]: Enabling loading native libraries from packages by extendig %PATH% with: ;C:\Users\moozzyk\.dnx\packages\NativeLib\1.0.0\runtimes\win7-x86\native

On non-Windows systems the trick with the path does not work. While there is an environment variable that can be set to point the runtime linker to load a library from a non-default location (LD_LIBRARY_PATH on Linux and DYLD_LIBRARY_PATH on OS X) it has to be set before the process starts. The runtime linker reads and caches the value of the *_LIBRARY_PATH environment variable when the process starts and any further modifications have no effect. To work around this ASP.NET 5 on Mono on OS X will pre-load native libraries. This works but has one drawback – the name passed to the DllImport attribute can no longer be the library name but has to be __Internal to tell mono to look among already loaded libraries. This is ugly because it requires maintaining two sets of DllImport attributes – one that is specific to Mono on OS X with __Internal as the name and one that has the dll name which works everywhere else. If you want to see this ugliness at work you can take a look at Kestrel or the project for testing the DllImport attribute. In this case the traces will look as follows:

Information: [PackageDependencyProvider]: Attempting to preload: /Users/moozzyk/.dnx/packages/NativeLib/1.0.0/runtimes/osx.10.11-x64/native/nativelib.dylib
Information: [PackageDependencyProvider]: Preloading: /Users/moozzyk/.dnx/packages/NativeLib/1.0.0/runtimes/osx.10.11-x64/native/nativelib.dylib succeeded

The pre-loading trick does not work on Mono on Linux. In this scenario the user must make sure that the library can be loaded by the runtime linker. I don’t think this is a big problem – as explained above distributing .so’s in NuGet packages is not that a great idea anyways.

If you are trying to use a native library and ASP.NET 5 cannot find/load the library there are a few things you can try. First turn on tracing and check if you see traces similar to shown above. If you don’t see them and you are using a package reference most likely the native library was not restored correctly. To check this open the project.lock.json file and find a corresponding target section that contains the both the runtime and the runtime id (i.e. you are looking for "DNXCore,Version=v5.0/osx.10.11-x64" not "DNXCore,Version=v5.0"). Inside find the package description for your package with native libraries – e.g.:

"NativeLib/1.0.0": {
  "type": "package",
  "dependencies": {
    "System.Runtime": "4.0.21-beta-23506"
  },
  "compile": {
    "lib/dnxcore50/NativeLib.dll": {}
  },
  "runtime": {
    "lib/dnxcore50/NativeLib.dll": {}
  },
  "native": {
    "runtimes/osx.10.11-x64/native/nativelib.dylib": {}
  }
},

If the "native" does not exist, is empty or does not contain a correct path to your library this is the problem. In most cases the issue is with the runtime id – either the packages were not restored using the correct/expected runtime id or the package containing the native library did not have library for the given runtime id.
If you are seeing problems with loading native libraries on Mono you can try using the MONO_LOG_LEVEL environment variable. Setting it to debug will print a lot of traces which can be helpful troubleshooting issues. You can also filter out some categories. More details here.
Another helpful environment variable useful for debugging problems with loading libraries on Linux is LD_DEBUG. Again, if you turn on all tracing you will get a lot of stuff. You can however filter out things. This post contains a nice summary of available options.
Looks like on Mac you should be able to use DYLD_PRINT_LIBRARIES (I did not have to so far).
On Windows you can use Process Monitor to see what files are being accessed.
Also, remember that loading a dynamic library will fail if it depends on a library that cannot be found. You can check dependencies with ldd on Linux, otool -L on Mac OS X and dumpbin on Windows.

So, this more or less how native libraries can be used in ASP.NET 5 and how you troubleshoot issues.

91 thoughts on “Using native libraries in ASP.NET 5

  1. When developing and the native dll is frequently changing it is not practical to constantly be creating nuget packages. I tried to reference the native c++ project, but that was not allowed. I tried to reference the dll directly, but it was not found. Only if I put the dll in a folder in the path is it found. But then it won’t be included when I deploy the package.

    Like

    1. Are you trying to develop a native library along with the manage library that consumes the native one? If so you probably want to use some scripts like precompile/prepack etc. in your project.json which would copy your dll to the right location for you so that both scenarios work.

      Thanks,
      Pawel

      Like

      1. Do you mean have the build automatically copy the native dll to a folder in the path while developing but use nuget when deploying?

        Like

  2. And then any other developers would get the solution from github, and add an environmental variable pointing to the folder with the native dll. Then when we want to deploy, create a new nuget package with the latest version of the native dll?

    Like

    1. I see that bin syntax seems to solve my problem, but only for managed assemblies. Do you know if there will eventually be a similar solution for unmanaged?

      Thanks

      Like

      1. Not sure what you refer to as to “bin syntax”. Managed dlls are not loaded with the DllImport attribute but by the host which reads the dependency graph (project.lock.json) and finds (or, in dnx, compiles) the right assembly and loads it.

        Like

    2. I guess there are a few options here
      – have the source for the native project in the same repo and have developers build it (requires C++ tooling)
      – have the dll committed in the repo (yeah, it’s kind of not nice) and copy using scripts (does not require C++ tooling)
      – just for build purposes create a package containing the dll and copy it using scripts (does not require C++ tooling)
      The last bullet point is how the Kestrel is built – we have libuv-build repo where we build the libuv library (granted there is almost no changes to it) and the CI publishes this package to a feed. Then in Kestrel repo we have build reference to this package which ensures that the package is restored during dotnet/dnx restore. Then we have this short program that copies libuv.dll to the right locations. Finally, this ensures that the dll ends up in the package when it is created. Yes, it’s a bit complicated but the requirement was that the people should not have to have C++ tooling installed because in general it is not needed for ASP.Net Core apps. Before this we had the libuv.dll committed in the repo but it is hard to track the version that is committed etc. I guess which way you choose depends on your requirements and constraints.

      Thanks,
      Pawel

      Like

      1. My structure is pretty much bullet point 1. I would like to have the native dll already wrapped in a nuget package in the project. But when developing will it take the (now old) nuget version rather than the latest one built? I guess that’s why you just copy it with scripts instead of having in in nuget.

        Like

        1. Copying to bin during development is perfectly fine and is much better then setting the %PATH% (you can implement it with the pre/post compile script instead of having developers know to set the variable). Yes, if the native dll is changing frequently creating NuGet package each time might be a hassle.

          Like

          1. And then on deployment I have to do the same thing right? It won’t get picked up automatically from the bin folder. I’ll study the kestrel repo to see how you do it.

            Thanks

            Sent from my iPhone

            >

            Like

          2. If I have the Nuget in the project will it take that dll during a dev build or the one in the path?

            Sent from my iPhone

            >

            Like

          3. As explained in the post dnx adds expands %PATH% to enable finding the native dll. I think the first folder on the %PATH% will win. I don’t remember from the top of my head at the moment but I think dnx prepends the path so it should win with what is already in there.

            Like

    3. If during development the dll is in the right location you shouldn’t need an environment variable. Otherwise you can add the folder to the %PATH% and then DllImport should load it as per the search order of LoadLibrary

      Like

  3. Not sure if this is the place for this question.

    I can’t seem to step from the asp.net5 project running under iisexpress into the unmanaged code.

    I can do this in other .Net projects by setting a property to allow unmanaged debugging.

    But I can’t find this setting in the asp.net project.

    Any idea?

    Like

    1. As far as I know it is not possible to debug managed and native at the same time if you use F5. I did file a bug on this in an internal tooling repo but it has not been addressed so far. What you can do however is start the app without debugging and then attach to the process. When attaching to the process you can select code type to debug so you can select managed and native.

      Hope this helps,
      Pawel

      Like

    1. VS must be set to run clr and not coreclr. You should be able to change this in the properties. The slowness might be related to runtime compilation. When you start your app before the code runs it’s being compiled (this is changing with replacing dnx with dotnet). VS also does a lot of work to start IIS etc. You can try starting you application with the –debug flag (e.g. dnx –debug kestrel) which will bypass IIS. –debug will make dnx wait for the debugger to be attached.

      Like

  4. There was a best practice not to use parallel processing under asp.net. Is that still the case with asp.net 5?

    Like

    1. Well, I think it always depends on what you do and how you do it. Most if not all APIs/classes in Asp.Net Core are not thread safe so if you are trying to access/modify common application state from multiple threads that is not going to fly. I don’t know what kind of processing you have in mind but if it is something limited to your own concepts and concepts/objects it might be fine. I am a bit curious about what scenario you have in mind. Also remember about async APIs – they should also be fine if used correctly.

      Pawel

      Like

      1. At this link: http://stackoverflow.com/questions/23137393/parallel-foreach-and-async-await-issue

        This following comment suggested it should be avoided:

        @DirkBoer: Parallel code will dramatically reduce ASP.NET scalability, and interfere with its thread pool heuristics. It is only useful if you have parallelizable CPU-bound work to do and know for certain that you will only have a small number of concurrent users. – Stephen Cleary Sep 29 ’14 at 18:40

        I am developing an api using MVC 6 to price fixed income instruments. The calculation engine is in c++, hence the original question about native dlls.

        I would like the api to accept several scenarios at once and price them. So pricing them in parallel should improve performance.

        It seems to be working okay using async/await and tpl parallel.foreach.

        Not sure if I’ll have scalability issues because of the warning. However since asp.net5 is a total rewrite I’m hoping it will be safe.

        Like

        1. I honestly have not worked too much with the previous versions of ASP.NET so can’t comment on the “thread pool heuristics”. In ASP.NET Core I think the only thing that creates threads explicitly is Kestrel – it creates a number of threads during the server start up to handle requests. The higher layers are using async/await. ASP.NET Core also does not have a synchronization context. Certainly if you start multiple threads to do some calculations it they can negatively affect your server or response times. As opposed to IO – these threads don’t need to wait – so either they are running and calculating things or they are not running and there is no progress in completing your requests. Alternatively you can run the calculations completely out of the process/web app (e.g. as a separate service) and asynchronously send requests from the web app to the service to get results. If you approach the problem this way you could even move the service to a separate machine (or machines).

          Pawel

          Like

          1. Maybe running through VS is complicating this. Here are some things I am observing:

            If I open an Asp.Net 5 project in VS a dnx.exe process is created even before running it.
            When I start the project (with or without debugging) a second dnx.exe starts which has the expected dll’s from the project loaded.

            If I ever kill the first dnx.exe, a new one is created. Then if I run the project the second dnx.exe is created but the dll’s are not loaded. I have to restart VS to get it working again.

            Once I have the project running I test it through an MS Test project. If I send a batch of calculations, the server will process them in parallel using parallel.foreach. I see the expected performance gain running them in parallel. I also see all the cpu’s spiking to 100% when this is happening.

            However I see almost no activity in the dnx.exe, whereas the VS devenv.exe is very busy and the thread count goes up and down.

            Like

          2. VS is using dnx internally to be able to build your project, restore packages etc (this is the Design Time Host). If you kill this dnx process VS will restart it otherwise you won’t be able to run your poject at all. If you try to verify something it might be much easier to just create a command line app and start without VS being involved at all.

            Like

  5. I’ve tried this differently and am seeing more what I expected:

    With the website running, I browse to it and do an expensive calculation. Then I see the dnx.exe doing all the work.

    Like

  6. The first test above was invalid. That test method was linking directly to the calc.dll and not going through the web service.

    Like

  7. Thanks for another great article! I want to access a legacy database from my ASP.NET 5 API and therefore need to use a native DLL. Your article is clear on most things but I have no experience in creating Nuget packages. Yesterday I tried CoApp but the project doesn’t seem to be very active anymore. I found the Nuget Packager by Ove Anderson but I’m not sure if that can do what is needed for native packages. Would you share what tools you use or give me a reference that I should read regarding that point?

    Like

    1. You don’t need to use CoApp (or maybe even you shouldn’t). You can easily crate packages just by preparing the package contents in a folder (i.e. the folder structure should be the same as you want it in the package) and the .nuspec file and running nuget.exe pack on this folder. However, because you have an Asp.Net 5/AspNet 1 Core app you can streamline the process even further – make sure the dll is available in one of the project folders/subfolders and then include it in the packInclude section of your project.json file (here is how we do it for Kestrel – the path on the left is the target subfolder in the NuGet package the path on the right is where to take the files from). Make sure that the target package path is in form runtimes/native/{RID}/{lib} (RID is a runtime id – e.g. win7-x64 for 64-bit Windows). Once you do it and call dnu pack (or soon dotnet pack) you should end up with a package with a native lib.

      Hope this helps,
      Pawel

      Like

      1. Many thanks! OK, I realized shortly after my comment that it’s not that hard to create a package with one DLL directly with Nuget and got it working with my ASP.NET app. Tomorrow I will try your suggestion about directly doing it from project.json.

        Like

        1. CoApp was good to crate packages containing native dlls which were supposed to be consumed by a MSBuild based systems since it created .targets file for different bitnesses and configuration that which then was integrated by nuget with the solution. Asp.Net is not MSBuild based so as you discovered it’s relatively easy to create packages manually because you don’t need to care about MSBuild stuff.
          Leveraging project.json saves you the manual work since in the new dotnet/Asp.Net Core world basically everything is a NuGet package and you just need to add some content to a package that would be created for you when you build your project anyways.

          Liked by 1 person

  8. Trying to use a nuget package developed with xproj+project.json, and I’m struggling to deploy the native dlls (this is not for an ASP project). The packInclude is working (I can see that files are embedded in the nupkg), but I’m unable to get these files copied to a regular csproj project (with a project,json)…
    Any ideas if this can be achieved?

    Like

    1. Hi Alexandre,

      I am not sure I understand the scenario – My understanding is that if you have a csproj then you don’t have a project.json. With project.json you should not have to do anything. The packages are restored into the packages folder and dnx should be able to find them there. Post rc1 when dnx is replaced with dotnet the structure is a bit different but when you build the application the native libs should be copied to the target bin folder for you. Finally if this is an actual csproj file when the packages are restored they should be in the packages folder in the solution folder. Now, when you compile the code I don’t think the dlls will be copied. In the past for msbuild based projects you were able to include a .targets file that was used to extend the project and this is how you would go about this. As a sample you could take a look at how I did it in the SignalR C++ project: https://github.com/aspnet/SignalR-Client-Cpp/blob/dev/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template

      Hope this helps,
      Pawel

      Like

  9. Any idea how we will be able to call into a (native) COM DLL? Will we first have to create an interop assembly? How would that be added? Is a nuget package still necessary? I am already trying with dotnet cli, so I don’t know if that makes a difference.

    Like

    1. I haven’t tried so can only speculate. First, COM objects are registered globally in registry. As a result, I don’t think, you won’t even be able to ship a COM in a NuGet package. Second, I don’t know if it is possible to call COM at all when using CoreClr as the runtime. I would start from using the full CLR and maybe try CoreClr only after you were able to make it work with full CLR. Or just skip CoreClr completely – COM objects are Windows only so it might be just fine to only support the full CLR. Yes, you would need the interop assembly/classes. These will be part of your application and can be shipped as a NuGet package. As, I said above – they won’t work if the COM object is not registered so you would need to have some way to prep the machine before you run the application for the first time (maybe your application can somehow do that). Another way could be to strip all COM related stuff from the dll and just PInvoke. This however will most likely require changes to you COM/dll so may not be feasible.

      Thanks,
      Pawel

      Like

  10. Thanks for sharing your ideas. As I have the source code for the COM DLL everything is in principle feasible, I will check what is the easiest solution. Stripping the COM stuff may be an option as would be the interop assembly option. If I understand correctly, a native DLL can be used with the CoreCLR, ehh, I think I am doing this already. So writing a native wrapper around the COM interface would probably be another option.
    Unfortunately this DLL can not be easily rewritten to be cross-platform portable 😦 Therefore sticking to full CLR is acceptable. Enjoying all the other great things of ASP.NET 5 it is still worth doing it with ASP.NET 5.
    Thanks, Nicolas

    Like

  11. I am having trouble getting my package to work. Firstly I am unsure what rid to use. I am running on Windows 10, so picked win7-arm. I also tried win7-x64 and win7-x86, but with the same problem. Here is what I see in project.lock.json after installing the package. notice there are no compile, runtime or native sections. The web page never shows and when I check the process in procexp I don’t see the calc.dll loaded. Though if I uninstall the package and place the dll in the dnx\bin folder it loads fine.

    “FinSysCalc/1.0.0”: {
    “type”: “package”,
    “sha512”: “rOJYmElh4ZMCRBP7cU8/kKqPhCGO5MurxzBZ7E6Fnoh1qNoV8XvIncb+v/4a6yV89UEjQp9Z6uW5jlOOTKeEeQ==”,
    “files”: [
    “FinSysCalc.1.0.0.nupkg”,
    “FinSysCalc.1.0.0.nupkg.sha512”,
    “FinSysCalc.nuspec”,
    “runtimes/win7-arm/native/Calc.dll”
    ]
    },

    Like

    1. You need to pick the architecture you are running your application on. win7-arm is basically for Windows 10 IoT Core running on Raspberry Pi. It doesn’t seem to me you are running on Raspberry Pi so you should pick win7-x64 or win7-x86 or both. The architecture must match the architecture your runtime is using. If you do dnvm list you will see which one is active.
      If the webpage does not show up you need turn on logging and configure the error page to see what exactly is failing. From what you describe it’s very likely that the dll cannot be loaded (especially if you try to load ARM on x86/x64) and this is causing failures. Turn on dnx tracing (set the DNX_TRACE environment variable to 1) and try the troubleshooting I described towards the end of the article.

      Thanks,
      Pawel

      Like

        1. Glad you were able to make it work. The first part of the RID (i.e. win7/win8/win10) refer to the operating system while x86/x64/arm refer to processor architectures. For the OS part there is a hierarchy and this is why if you use win7 it will work on win10.

          Like

  12. I am having trouble installing a native nuget package I built. I get the below in my project.lock.json. I am only targeting 4.5.1. However when running the application, the dll is not found. I do see it in this path though:
    C:\Users\Patrick\.dnx\packages\FinSys.Calc\1.0.0\runtimes\win7-arm\native

    Both:

    “FinSys.Calc/1.0.0”: {
    “type”: “package”
    },

    And:

    “FinSys.Calc/1.0.0”: {
    “type”: “package”,
    “sha512”: “mLXjLdPjCGfINz3XevgrmS2xC7zea06vOgRtC9WcHLA0wDv9Q0p7dIZLRizwnpPg31Nd8yjvPKzrZ/JoxI1gWg==”,
    “files”: [
    “FinSys.Calc.1.0.0.nupkg”,
    “FinSys.Calc.1.0.0.nupkg.sha512”,
    “FinSys.Calc.nuspec”,
    “runtimes/win7-arm/native/Calc.dll”
    ]
    },

    And this at the end:

    “projectFileDependencyGroups”: {
    “”: [
    “Microsoft.AspNet.Mvc >= 6.0.0-rc1-final”,
    “Microsoft.AspNet.Server.Kestrel >= 1.0.0-rc1-final”,
    “Microsoft.AspNet.StaticFiles >= 1.0.0-rc1-final”,
    “Microsoft.AspNet.Mvc.TagHelpers >= 6.0.0-rc1-final”,
    “Microsoft.Extensions.Logging.Debug >= 1.0.0-rc1-final”,
    “AutoMapper >= 4.1.1”,
    “Angular.UI.Bootstrap >= 1.1.1”,
    “EntityFramework.Core >= 7.0.0-rc1-final”,
    “EntityFramework.MicrosoftSqlServer >= 7.0.0-rc1-final”,
    “EntityFramework.Relational >= 7.0.0-rc1-final”,
    “EntityFramework.Commands >= 7.0.0-rc1-final”,
    “Microsoft.CodeAnalysis.FxCopAnalyzers >= 1.1.0”,
    “FinSys.Calc >= 1.0.0”
    ],
    “DNX,Version=v4.5.1”: []
    }

    Like

  13. If I wanted to create a proprietary native dll which I did not want generally downloadable through nuget, how would I integrate that into asp.net Core?

    Like

    1. I used a private Nuget repo for that, i.e. a local directory that contains the nuget package. In my case this repository is part of the global nuget config but I guess you could certainly add this in a project local nuget config. Then add the package reference to project.json as usuable.

      Like

      1. If I use the package manager through Visual Studio how do I reference a local package? package source just offers nuget.org and Microsoft and .Net

        Like

  14. Go to the options window -> Nuget package manager -> Package Sources. Here you can set up a new package source. Besides entering a URL you can add a local file system path. After that this source is available in your project and you can search for your package using this source.

    Like

  15. Have not yet thought about that. For this specific project there are no team members that need to access that repository.

    Like

    1. In the simplest case it can be just a share and you point to the share in your NuGet.config. You can also set up a local/internal/private NuGet server. Finally you can use myget (http://myget.org) (this is what the Asp.Net team uses but we have many packages builds daily).

      Like

  16. I was trying to get an asp.net core app hosted in IIS, but found it to be pretty difficult compared to self hosting through Kestrel. Have you looked at that at all? Also, how would you recommending starting a self hosted app on windows? Should I start a windows service which starts the app or just have it started whenever the server starts?

    Thank

    Like

    1. I actually spent the last few days fixing the publish-iis tool to work again. In Asp.Net Core your application is always hosted using Kestrel. Even if you use IIS it is acting merely as a reverse proxy and forwards all the requests to Kestrel. Setting up IIS and to “host” (i.e. forward requests to) AspNet Core app may seem complex (the steps are here – they will change for RC2 a little bit because HttpPlatformHandler is being replaced by AspNetCoreModule) but if you do it once things get easy. Kestrel is great for development but I don’t think it’s a great idea to allow external requests hit it directly – at least not at this point. In the wild I would recommend putting IIS (or Nginx on non-windows in front of Kestrel) until Kestrel is proven in real world scenarios.
      If you use IIS for your app you won’t have the dilemma of how to start your app. If you don’t use IIS you may try going the service route but I am not sure how easy/difficult it is. You will also have to figure out what to do in situation when the application crashes or misbehaves.

      Thanks,
      Pawel

      Like

      1. If I run web.cmd from the command prompt it works fine, but trying it from IIS gives this:

        An unhandled exception was thrown by the application.
        Microsoft.AspNet.Server.Kestrel.Networking.UvException: Error -4077 ECONNRESET connection reset by peer
        at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
        at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
        at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
        at Microsoft.AspNet.Server.Kestrel.Http.SocketOutput.Microsoft.AspNet.Server.Kestrel.Http.ISocketOutput.Write(ArraySegment`1 buffer, Boolean immediate)
        at Microsoft.AspNet.Server.Kestrel.Http.Frame.WriteChunked(ArraySegment`1 data)
        at Microsoft.AspNet.Server.Kestrel.Http.Frame.Write(ArraySegment`1 data)
        at Microsoft.AspNet.Server.Kestrel.Http.FrameResponseStream.Write(Byte[] buffer, Int32 offset, Int32 count)
        at Microsoft.AspNet.Mvc.HttpResponseStreamWriter.FlushInternal(Boolean flushStream, Boolean flushEncoder)
        at Microsoft.AspNet.Mvc.HttpResponseStreamWriter.Dispose(Boolean disposing)
        at System.IO.TextWriter.Dispose()
        at Microsoft.AspNet.Mvc.JsonResult.ExecuteResultAsync(ActionContext context)
        at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__56.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__55.MoveNext()
        — End of stack trace from previous location where exception was thrown —
        at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
        at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__54.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__49.MoveNext()
        — End of stack trace from previous location where exception was thrown —
        at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
        at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__44.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Routing.RouteCollection.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Builder.RouterMiddleware.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.IISPlatformHandler.IISPlatformHandlerMiddleware.d__8.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.d__3.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 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
        at Microsoft.AspNet.Hosting.Internal.HostingEngine.c__DisplayClass32_0.<b__0>d.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 System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
        at Microsoft.AspNet.Server.Kestrel.Http.Frame.d__79.MoveNext()

        Like

  17. That might be a red herring. It is logged from the application when running IIS. But now I don’t see it. I just get 500 Internal Server error, but when running the web.cmd from command prompt it runs ok. I don’t see anything in Event Viewer or IIS log, or in the application log. I’m going to try to set it up in IIS again.

    Like

    1. In the event viewer I am noticing that when I browse to the IIS site it gives the following which indicates a process pointing to a command window and listening on port different from the one I configured IIS for I get a 500 on the configured port or the one in the command window:

      – System

      – Provider

      [ Name] HttpPlatformHandler

      – EventID 1001

      [ Qualifiers] 0

      Level 4

      Task 0

      Keywords 0x80000000000000

      – TimeCreated

      [ SystemTime] 2016-04-17T20:21:12.878892500Z

      EventRecordID 61259

      Channel Application

      Computer Pat

      Security

      – EventData

      Process ‘4216’ started successfully and is listening on port ‘6939’.

      Like

      1. Turn on logging in your web.config file and see the output – should be in the logs\stodout.log file (or whatever path you configured). Also, check if the process that IIS started is running – if not configure capturing start up errors. Finally, if you are using views the issue might be that the app cannot find views – when you start your application from command line from the application folder Views are probably already there. In RC1 IIS starts application from the wwwroot folder and views are not there. To test this you can do two things – 1) try starting your app from command line from the wwwroot folder and see if it works, 2) copy Views to wwwroot and start the app using IIS and see if it works.

        Pawel

        Like

  18. I turned on tracing like this, then I see it is a 500.19. Did you mean some other setting? I don’t see anything in the logging folder:

    The process is there in procexp, It is a cmd with no visible screen. I am using MVC 6 and angular with routing.

    If I start it from the command line with web.cmd it works fine.

    Copying the views did not make a difference.

    Like

    1. Hard to tell. Did you check your event log? I would recommend checking some discussions about using IIS in the https://github.com/aspnet/IISIntegration repo. This would also be a place to report issues. Note that we have already moved away from HttpPlatformHandler to AspNetCoreModule and from dnx to dotnet. I would recommend doing the same – it will be easier to find help for new than for obsolete things.

      Like

        1. Take a look at this comment: https://github.com/dotnet/cli/issues/2135#issuecomment-212692267. It contains a set of links that should be helpful. Migrating to RC2 is not as straightforward as before. dnx is gone and you need to switch to dotnet cli. Most of the packages were renamed from Microsoft.AspNet.* to Microsoft.AspNetCore.*. Setting up the application also changed a bit. On top of that you need switch to dev NuGet feeds at the moment since RC2 has not been released yet so you need to work with “nigthly” builds. On the other hand you will have to do this soon anyways since, as I said, dnx/dnvm/dnu will cease to exist when RC2 is shipped.

          Pawel

          Like

  19. From these posts it looks like it might be better to wait until things stabilize before switching from rc1 to rc2. I might work on functional issues in the app and return to converting to rc2 later.

    Like

    1. There is quite a lot of changes required to move from RC1 to RC2 – especially for bigger project. We are working on stabilizing the release though so I don’t expect a lot of breaking changes between what is there now and what ends up in the actual RC2. I understand however where you are coming from and how early adopters were bitten by the number and caliber of changes in each release.

      Like

      1. Do you think the steps in the convert RC1 to RC2 steps are the best path to follow? I basically have an RC1 dnx version which works fine except for publishing to IIS.

        Like

        1. Yes. Follow the steps and solve issues as you go. Once you have your app converted to RC2 you can work on IIS – this part is relatively easy.

          Like

  20. Don’t know if this is still active. I converted an RC1 project to the dotnet Core release, and my pinvoke calls are failing withSystem.BadImageFormatException

    Like

      1. I have a c++ dll built in VS, which used to work with dnx, but does not work with dotnet. I put the dll in the same folder as the exe (dnx or dotnet), then run through VS to debug. does dotnet.exe require 54 bit native binaries?

        Like

    1. This is the correct solution. By default on a 64-bit machine a 64-bit version of dotnet.exe is installed. If you are using 32-bit dlls in your project you need to run this project with 32-bit version of dotnet.exe.

      Like

  21. Now that I’ve got it converted to Asp.Net Core, I’d like to host it in IIS. Is there a link which describes this?

    Like

  22. I think this is related to native code, but I’m not sure. I built a standalone app, which works fine on my workstation, but after deploying it to the server, I get the following error:

    Unhandled Exception: System.Reflection.TargetInvocationException: Exception has
    been thrown by the target of an invocation. —> System.DllNotFoundException: Un
    able to load DLL ‘api-ms-win-core-registry-l1-1-0.dll’: The specified module cou
    ld not be found. (Exception from HRESULT: 0x8007007E)
    at Interop.mincore.RegOpenKeyEx(SafeRegistryHandle hKey, String lpSubKey, Int
    32 ulOptions, Int32 samDesired, SafeRegistryHandle& hkResult)
    at Microsoft.Win32.RegistryKey.InternalOpenSubKey(String name, Int32 rights)
    at Microsoft.AspNetCore.DataProtection.RegistryPolicyResolver.ResolveDefaultP
    olicy()
    at Microsoft.Extensions.DependencyInjection.DataProtectionServices.d__0.MoveNext()
    at Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescr
    iptorExtensions.TryAdd(IServiceCollection collection, IEnumerable`1 descriptors)

    at Microsoft.Extensions.DependencyInjection.DataProtectionServiceCollectionEx
    tensions.AddDataProtection(IServiceCollection services)
    at Microsoft.Extensions.DependencyInjection.MvcViewFeaturesMvcCoreBuilderExte
    nsions.AddViewServices(IServiceCollection services)
    at Microsoft.Extensions.DependencyInjection.MvcViewFeaturesMvcCoreBuilderExte
    nsions.AddViews(IMvcCoreBuilder builder)
    at Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.Ad
    dMvc(IServiceCollection services)
    at FinSysCore.Startup.ConfigureServices(IServiceCollection services)
    — End of inner exception stack trace —
    at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments,
    Signature sig, Boolean constructor)
    at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Objec
    t[] parameters, Object[] arguments)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke
    Attr, Binder binder, Object[] parameters, CultureInfo culture)
    at Microsoft.AspNetCore.Hosting.Internal.ConfigureServicesBuilder.Invoke(Obje
    ct instance, IServiceCollection exportServices)
    at Microsoft.AspNetCore.Hosting.Internal.ConfigureServicesBuilder.c__Displa
    yClass4_0.b__0(IServiceCollection services)
    at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(ISer
    viceCollection services)
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
    at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
    at FinSysCore.Program.Main(String[] args)

    Like

    1. Looks like you are trying to run an application that was published for a newer version of windows on an older version of windows (e.g. you published your app for win8-x64 but then you are running it on Windows 7/Windows 2008 R2).

      Like

  23. Dear Pawel, a while ago you helped us with creating nuget packages for a native library. In the meantime .NET Core has gotten quite a comprehensive documentation and I found this article https://github.com/dotnet/core-docs/blob/master/docs/core/tutorials/libraries.md which mentions a packOptions option that would allow me to bypass the creation of a nuget package and specify the native library directly. Does this option only work for library projects or also for apps? I tried to use it with a WebApp but my native lib did not end up in the publish. Any idea?

    Like

Leave a comment