What is deps.json, and how do I make it use relative paths?

I'm setting up an ASP.NET Core project on TeamCity. The binaries it builds crash on startup on other machines. The error message shows that it is looking for dlls in paths that only exist on the build server. DotPeek shows that there's an embedded resource file in the .exe called myproject.deps.json. In the targets section there, there are references to dlls using absolute paths. This means that ASP.NET Core binaries are only ever going to run on the machine on which they were built.

How do I fix this problem? What is this file, and how do I make it use relative paths? After some digging, it looks like the paths come from project.fragment.lock.json, which is a generated file. If I edit this to use relative paths, the file is just overwritten again. What generates this, and how can it be fixed, or stopped?

For those who asked, project.json looks like:

{
  "dependencies": {
    "CommandLineParser": "1.9.71",
    "Microsoft.AspNetCore.Mvc": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
    "System.Configuration.Abstractions": "1.0.0"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "net461": {
      "dependencies": {
        "Company.Common": {
          "target": "project"
        },
        "Company.Integration": {
          "target": "project"
        },
        "Company.Functions": {
          "target": "project"
        },
        "Company.Utils": {
          "target": "project"
        }
      }
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "Areas/**/Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Solution 1:

The answer to your first question, per the Runtime Configuration File Documentation:

And the answer to your second question, is to remove preserveCompilationContext in your project.json file (and rebuild).

MyApp.deps.json is a list of dependencies, as well as compilation context data and compilation dependencies. Not technically required, but required to use the servicing or package cache/shared package install features.

Per your comment to Dimitry, I couldn't tell if you have .net core installed in your target machine and therefore infer the kind of deployment you are trying to do. But assuming it is installed, you should be able to tune your myproject.runtime.json to fix your problems. In case you don't, I highly recommend reading about the two different types of .NET Core Application Deployment:

You can create two types of deployments for .NET Core applications:

Framework-dependent deployment. As the name implies, framework-dependent deployment (FDD) relies on a shared system-wide version of .NET Core to be present on the target system. Because .NET Core is already present, your app is also portable between installations of .NET Core. Your app contains only its own code and any third-party dependencies that are outside of the .NET Core libraries. FDDs contain .dll files that can be launched by using the dotnet utility from the command line. For example, dotnet app.dll runs an application named app.

Self-contained deployment. Unlike FDD, a self-contained deployment (SCD) does not rely on any shared components to be present on the target system. All components, including both .NET Core libraries and the .NET Core runtime, are included with the application and are isolated from other .NET Core applications. SCDs include an executable (such as app.exe on Windows platforms for an application named app), which is a renamed version of the platform-specific .NET Core host, and a .dll file (such as app.dll), which is the actual application.

Solution 2:

*.deps.json comes from preserveCompilationContext.

Preserving the compilation context is useful for runtime compilation (i.e. just-in-time compilation) and especially for compiling views. It is not usually useful for libraries. To fix your problem:

  1. Remove preserveCompilationContext from each Company.* library that your app references.
  2. If that does not work, also remove preserveCompilationContext from your main app.

There is an involved conversation here: https://github.com/aspnet/Mvc/issues/5141

Solution 3:

If you are using the newer .csproj format

Adding <PreserveCompilationContext>false</PreserveCompilationContext> under the <TargetFramework> tag fixed the issue for me.

<PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <PreserveCompilationContext>false</PreserveCompilationContext>
</PropertyGroup>