Aspnetcore: RC1 --> RC2: Severe migrations issues

Created on 24 May 2016  路  21Comments  路  Source: dotnet/aspnetcore

Dear sir or madam,

Since February this year, we have been developing our new solution in ASP.NET 5.
With the reason news and so forth - and a release to production being imminent - the migration from ASP.NET Core RC1 to RC2 gives us headaches.

We have followed various guides on the Internet, but every time we are a step closer, something else breaks.

Our solution (due to time-2-market) is build like this:

With the RC1 we had a target framework of dnx451 so we could use our legacy .NET 4 assemblies a long with the .NET 4 Framework assebmlies (mscorlib, etc.). We are running MVC Core 1 setup to serve both frontend UI with an associated frontend API. For the UI rendering, we use the REACT framework setup as a SPA.

With the RC2 release (which I understand will be close to RTM), we are forced to target netcoreapp1.0 which does not go well with the above mentioned assemblies. We have tried with the imports keyword for dnx451 but no change; I am unable to successfully let the two worlds play well together as I succeeded with RC1.

All development is happening under VIsual Studio 2015 with Update 2 on Windows 10 desktops. The server it will execute on, will for the time being, be a WIndows 2012R2 and IIS. Later, when early development is done, we will consider hosting on Unix .. but that is another story for another time.

Does anyone have a clue what to do?
I am sure the path we have chosen has been chosen by others as well, as we could not simple re-write all our assemblies over night.

And given the _huge_ changes from Microsoft in terms of RC1 to RC2, I am somewhat glad that we did not put all eggs in the same basket.

Any help will be much appreciated .. I am guessing its not a viable road to keep using RC1 why we must find a way to make RC2 work with our mixed environments.

Last but not least; if a mixed environment is not possible (perse), is it then possible to tell classes in the solution what framework to use? I have seen the if dnx451 end if syntax, but I want the entire class to use netcoreapp1.0 and another class to use dnx451 for instance.

UPDATE

I have tried to be inspired/search knowledge through these "guides" (among many).

Thanks.

Most helpful comment

Just $.02 - We just migrated 4 web based projects of various sizes from RC1 to RC2. The smaller projects were relatively straightforward to convert, using the guidelines mentioned above. However the larger projects with several libs were a definite PITA. After several failed attempts on the larger projects we ended up doing as others suggested and created an entirely new web project for the web code. We also defaulted all projects to running on net46 due to having various nuget package compatibility issues. NuGet packages have definably been a pain point as also bower/npm packages (I guess that is b/c tooling is still in preview??). All-in-all I hope MS can tame these migrations for the sake of the platform. It is almost like we have reverted back to a dll hell like scenario but instead it is now NuGet and Bower/NPM package hell. For example some NuGet packages used in RC1 are incompatible with .NETStandard Lib, even trying to use imports.Hopefully it will level off as RTM approaches. Please MS no more bad migrations like this for a long time... :-{. Overall we are happy with the direction but just been kind of a nightmare getting there. Oh and in case someone wants to contribute the canned "wait until RTM if you don't want pain" comments. Just remember if MS wants real world feedback on the platform we need to build real world apps. Hello World and Contoso just don't cut it.

All 21 comments

Why not target net451?

With the RC2 release (which I understand will be close to RTM), we are forced to target netcoreapp1.0 which does not go well with the above mentioned assemblies. We have tried with the imports keyword for dnx451 but no change; I am unable to successfully let the two worlds play well together as I succeeded with RC1.

I think you can target net451 which would mean the same. However, mono 4.2 doesn't completely work for the assemblies produced by dotnet CLI AFAIK (ref). So, you might need to upgrade to 4.4 from the the beta channel.

I am not able to get debugging working with VS Code under mono though (https://github.com/aspnet/Home/issues/1502).

With the RC2 release (which I understand will be close to RTM), we are forced to target netcoreapp1.0 which does not go well with the above mentioned assemblies. We have tried with the imports keyword for dnx451 but no change; I am unable to successfully let the two worlds play well together as I succeeded with RC1.

What @smbecker said. You're not forced to use netcoreapp1.0.

image

You can pick ASP.NET Core Web Application (.NET Framework)

Why not target net451?

We have tried to target net451 as well; same error.The reason we went for dnx451 was because thats what worked with the previous version (RC1).

As an update to this thread, it is worth mentioning that I have followed these "guides":

To name a few. I will update my question with these.

What @smbecker said. You're not forced to use netcoreapp1.0.

Maybe i was not clear enough; we are migrating the existing website from RC1 to RC2. However, I will try to create an empty website with the suggestion you have .. maybe that can put me on the right path.

I am not able to get debugging working with VS Code under mono though (#1502).

We are running in a Windows environment - thanks for the heads up. I will update my question.

@gimlichael I have found it easier to create new applications (using VS2015) and dump all my source files into them than to manually convert an existing DNX project to .NET Core.

@gimlichael I have found it easier to create new applications (using VS2015) and dump all my source files into them than to manually convert an existing DNX project to .NET Core.

Hmm, that might be a way to go, although it does seems like a lot of work for what should have been a "simple" migration. Thanks for the suggestion, mate.

@gimlichael I have found it easier to create new applications (using VS2015) and dump all my source files into them than to manually convert an existing DNX project to .NET Core.

Frankly, that was the only way I was able to handle the migration in a reasonable time frame. There are just too many little odds and ends that were a nightmare to try and track down.

If you practiced decent separation of concerns this method will be much more reliable.

FYI, we also went from RC1 Framework to RC2 Framework (net451) and everything works now. There were still some code changes, but most of those were straight forward. It's all the configuration stuff that's a pain.

Frankly, that was the only way I was able to handle the migration in a reasonable time frame. There are just too many little odds and ends that were a nightmare to try and track down.

Thanks, this calms me down a little .. I will look into it tomorrow, and give my experience back to the community. I will see this as an opportunity to give it a make over in terms of following the SOLID principles. Some areas are in need of attention :-)

Okay, so I have now followed the sugestion from @SimonOrdo, and I have the first issue. We use REACT as the frontend framework setup as a SPA, hence this handles the routing. To my understanding, we need to reference "Microsoft.AspNetCore.SpaServices": "1.0.0-beta-000002" which relies on the .NETCoreApp 1.0. Any hints how to move along?

@SteveSandersonMS is working on fixing this

@SteveSandersonMS is working on fixing this

Thanks for the update, @davidfowl

@SimonOrdo, can you provide how you got the net451 dependencies resolved from RC1 to RC2? I have tried a multitude of different project.json configurations and nothing has worked. Thanks for any help.

@jkpindahbc

Yeah, I gave trying to fix project.json and let Visual Studio build it for me from scratch. The process I used was painstaking and time consuming, but we have a project that's been in full development for almost 7 months, so there was a lot of stuff to change.

Here is what I did:

  • Uninstall all RC1 bits from the machine (I actually ended up wiping my machine and reinstalling everything from scratch, skipping the RC1 install altogether and just installing RC2)
  • I created a new RC2 _Framework_ Web Project.
  • Then I copied all of my assets (Views, Controllers, wwwroot, etc) over. Took special care merging Startup.cs, where I moved code over line by line instead of replacing the file entirely. Lost of stuff changed in Startup.cs and moving the entire file over will give you headaches.
  • I re-scaffolded all of my EF models and used them to replace the RC1 versions.
  • At this point, I had about 800 "errors" in the code. Went through and resolved all of those. Mostly just used Visual studio "Quick Action" hints to remove unused namespaces and add ones that were required, again using the Visual Studio "Quick Actions" hint.
  • Ran the app and tested all functionality. Some views were blowing up when I hit them because of old namespace references or because I had inline Razor code that was not caught during compile time. Fixed those as needed.
  • Repeated that procedure for all project libraries as well

It definitely felt like a brute force way to do a migration, but now it runs better than before. I didn't want to take any chances of orphaned RC1 remnants still floating around the code or the configs.

All in all it took about a week to complete the move to RC2 (mostly because documentation for stuff isn't in place yet and we had to hunt and peck forums and github for solutions to obscure problems).

If it helps, my project.json now looks like this

{
  "userSecretsId": "yoursecretkeyhere",

  "dependencies": {
    "Microsoft.ApplicationInsights.AspNetCore": "1.0.0-rc2-final",
    "Microsoft.AspNet.Identity.Core": "2.2.1",
    "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Authorization": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.DataProtection": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics.Abstractions": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Http.Abstractions": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Http.Extensions": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Identity": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc.ViewFeatures": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Owin": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.AspNetCore.Routing": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Session": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.Relational": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0-rc2-final", 
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.EntityFrameworkCore.Tools.Cli": "1.0.0-preview1-final",
    "Microsoft.EntityFrameworkCore.Tools.Core": "1.0.0-rc2-final",
    "Microsoft.Extensions.Caching.Abstractions": "1.0.0-rc2-final",
    "Microsoft.Extensions.Caching.Memory": "1.0.0-rc2-final",
    "Microsoft.Extensions.Caching.SqlServer": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Abstractions": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Binder": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "Microsoft.Extensions.Options": "1.0.0-rc2-final",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Serilog.Extensions.Logging": "1.0.0-rc2-10104",
    "Serilog.Sinks.ColoredConsole": "2.0.0-beta-700",
    "Serilog.Sinks.RollingFile": "2.0.0-rc-703",
    "Serilog.Sinks.Trace": "2.0.0-rc-708",
    "System.Linq.Dynamic": "1.0.6"
  },

  "tools": {
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    },
    "Microsoft.Extensions.SecretManager.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "frameworks": {
    "net452": {
      "frameworkAssemblies": {
        "System.DirectoryServices": "4.0.0.0",
        "System.DirectoryServices.AccountManagement": "4.0.0.0",
        "System.IO.Compression": "4.0.0.0",
        "System.IO.Compression.FileSystem": "4.0.0.0"
      }
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
      //,"copyToOutput": [
      //"appsettings.json",
      //"appsettings.Staging.json",
      //"appsettings.Production.json",
      //"project.json"
    //]
  },

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

  "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp minify:bundle:js" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Just $.02 - We just migrated 4 web based projects of various sizes from RC1 to RC2. The smaller projects were relatively straightforward to convert, using the guidelines mentioned above. However the larger projects with several libs were a definite PITA. After several failed attempts on the larger projects we ended up doing as others suggested and created an entirely new web project for the web code. We also defaulted all projects to running on net46 due to having various nuget package compatibility issues. NuGet packages have definably been a pain point as also bower/npm packages (I guess that is b/c tooling is still in preview??). All-in-all I hope MS can tame these migrations for the sake of the platform. It is almost like we have reverted back to a dll hell like scenario but instead it is now NuGet and Bower/NPM package hell. For example some NuGet packages used in RC1 are incompatible with .NETStandard Lib, even trying to use imports.Hopefully it will level off as RTM approaches. Please MS no more bad migrations like this for a long time... :-{. Overall we are happy with the direction but just been kind of a nightmare getting there. Oh and in case someone wants to contribute the canned "wait until RTM if you don't want pain" comments. Just remember if MS wants real world feedback on the platform we need to build real world apps. Hello World and Contoso just don't cut it.

I have about 30 DNX projects that need updating to RC2. No freaking way am I doing each one manually... I have started developing an upgrade utility to upgrade RC1 projects to RC2. The idea will be to automate as much of the upgrade logic as possible (i.e changes to project.json, .xproj files as documented here: https://wildermuth.com/2016/05/17/Converting-an-ASP-NET-Core-RC1-Project-to-RC2) but accepting that their will still be some manual effort left at the end of the automated process like code refactoring etc. Still I think a tool will be useful to perform the grunt work, and it's a shame Microsoft are not interested in providing such a tool to help ease the migration journey themselves imho. If anyone is interested in helping out / contributing, it's here: https://github.com/dazinator/AspNetRC1toRC2UpgradeTool/

@dazinator There is such a tool/script. I don't recall who did it, but it was mentioned on JabbR a while back. @benaadams, do you recall who did that RC1-to-RC2 conversion tool/script?

@GuardRex - thanks I would definitely be interested to look at such a tool to see how much it covers.. in the meantime I am continuing on with my own one, slowly making it better. I have some approvaltests set up, to test migrating various RC1 project.json files to RC2 (and global.json) and so far its pretty promising. I've had to extend it a bit recently to also deal with Library projects though, and updating those to automatically target netstandard.

@GuardRex https://github.com/pranavkm/FixProjectJsonWarnings (by @pranavkm) :clap:

Was this page helpful?
0 / 5 - 0 ratings