aspnet / Mvc

[Archived] ASP.NET Core MVC is a model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
5.62k stars 2.14k forks source link

Running on full .NET framework with referenced assemblies #4682

Closed skyflyer closed 7 years ago

skyflyer commented 8 years ago

I'm sorry if this has been asked before, but I can't find good/definitive information about this. The ASP.NET 5 RC1 MVC app had the option to be run either on full .NET framework or on .NET Core. The target monikers from RC1 are obviously not relevant anymore.

The reason I'm asking is because I'd like to reference existing .NET assemblies in the new MVC app which are not portable assemblies.

In the blank dotnet new app, I see only netcoreapp1.0 moniker:

 "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }

while the MVC app has the following moniker:

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "dnxcore50",
        "portable-net45+win8"
      ]
    }
  }

The "imports" suggest that it should be possible to run on full .NET CLR (I'm guessing) but I can't reference assemblies (.NET Core projects only support referencing .NET framework assemblies in this release. To reference other assemblies, they need to be included in a NuGet package and reference that package) nor can I reference a .NET nuget package (for instance, try log4net) -- (The dependency log4net 2.0.5 does not support framework .NETCoreApp,Version=v1.0.). So, are we unable to run the "new MVC" framework on full .NET? Is this a tooling issue (and if so, what would be the workaround) or RC2 issue or is it actually designed that way (to be run only on .NET core and not on full .net framework)?

To be as concrete as possible, we're looking into upgrading existing infrastructure in a corporate environment and we need to reference (among other stuff) IBM DB2 and CTG assemblies, which are not (and who knows when and if) .NET core "compatible").

I'm guessing it should be possible by wrapping existing DLL in a "project.json" wrapper project while defining target framework moniker compatible with netstandard1.5 and somehow referencing the wrapped project from the MVC, but I'm not sure whether this is a way to go and whether it is a supported approach. I got the idea from Corefx documentation.

Any feedback would be appreciated.

pranavkm commented 8 years ago

You could target net451 in your projects - for e.g. https://github.com/aspnet/Mvc/blob/dev/samples/MvcSandbox/project.json#L37

skyflyer commented 8 years ago

@pranavkm thanks, for the pointer; I tried that -- my project wouldn't build if I add the net451 target framework moniker to project.json. The errors are along the following line: Error NU1002 The dependency System.Diagnostics.Process 4.1.0-rc2-24027 does not support framework .NETFramework,Version=v4.5.1.

If I move the dependencies under the frameworks/netcoreapp1.0 element, the net451 does not build (missing dependencies, obviously).

I suppose I should use different dependencies for full .NET?

The referencing of the existing assembly is still unclear to me, though; previously we had a dnu wrap command to wrap an assembly; currently, there is no dotnet wrap command; Perhaps something like dotnet pack? Or is this because the tooling is "preview 1" and we should manually wrap the existing DLL?

I created a directory in the src folder (sibling of MVC Website project directory) and I put the simplest DLL in there with the following project.json:

{
  "dependencies": {
  },
  "frameworks": {
    "net451": {
      "bin": {
        "assembly": "ClassLibrary1.dll",
        "pdb": "ClassLibrary1.pdb"
      },
      "dependencies": {
      }
    }
  },
  "runtimes": {
    "win": { }
  },
  "version": "1.0.0-*"
}

I couldn't create a NuGet package:

C:\tmp\DeleteWeb\src\WrapLib>dotnet pack
Producing nuget package "WrapLib.1.0.0" for WrapLib
NuGetResources.CannotCreateEmptyPackage

nor could I reference this project.json project from the existing project.

So, in other words, recipe on how to target the full .NET framework and how to reference an existing assembly would be very nice.

Eilon commented 8 years ago

BTW I set up a quick mtg for Monday to discuss this.

Jupakabra commented 8 years ago

Yes, why default templates don't provide .NET framework (Windows only) templates?

Eilon commented 8 years ago

@Jupakabra that template is effectively Windows-only anyway, unless you use Mono.

Eilon commented 8 years ago

@skyflyer there are a few things going on here:

  1. If you're using netcoreapp then you cannot use .NET 4.x assemblies/packages
  2. If you're using net4xx then you can use the frameworkAssemblies section of project.json to reference DLLs that are installed by .NET Framework (the stuff in the GAC)

Either way, in general you should be able to "wrap" a DLL (either one that's on disk, or one that's built from a csproj) and then reference that from your app's project.json file.

@pakrym will see if we have a good sample we can share with you for how to do a wrapped project.

skyflyer commented 8 years ago

@Eilon, sounds good, but doesn't answer the question entirely. I'll tried searching for information, but came empty handed.

It would be nice if target framework monikers would be documented (or is it just me and I can't find them)?

And also, it would be nice if it was documented how to reference an existing dll with RC2 tooling.

Sure, this is not an MVC-only issue (and I should direct the question in another tracker), but the issues at hand relate to "how to run the new MVC on a full .NET framework". Given your answer, I suspect "File new project" and "changing netcoreapp to net451 framework should do the trick (will test it again ASAP tomorrow, but I tried that before and documented my failure above (3 days ago))? What about MVC dependencies?

javiercn commented 8 years ago

@skyflyer You can look at mappings and names in https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Frameworks/DefaultFrameworkMappings.cs

skyflyer commented 8 years ago

All,

I managed to get it working with the following steps:

  1. remove netcoreapp framework from project.json and replace it with an empty net451
  2. add relevant NuGet dependencies in the main dependencies section of the project file
  3. add a blank Class library project
  4. reference an existing DLL in a Class Library project: I used a snippet from the web to reference the DLL on the disk using the following syntax:

    "net451": {
     "bin": {
       "assembly": "external\\ClassLibrary1.dll",
       "pdb": "external\\ClassLibrary1.pdb"
     }
    }
  5. I referenced the class library project from the web project
  6. It compiles and runs fine, even though Visual Studio Intellisense is not happy and is complaining that the "type or namespace ClassLibrary1 can not be found", which is strange, since it compiles and runs just fine.

It runs from visual studio and from the command line using dotnet run. I've uploaded the solution for reference. I've also reported the Visual Studio Intellisense error through their feedback mechanism.

kotylo commented 8 years ago

Indeed, RC2 broke the adding of .NET DLLs. Your method worked, but didn't have any Intellisense, which is a must. But it works if you pack them using nuget and install via local nuget server for example.

How to create a package is here. First option (from dll) didn't work for me, so I did it from csproj using this command: nuget pack MyProject.csproj

inianp commented 8 years ago

Kotylo, Did you create a class library (core) project to reference DLLs/legacy (.NET 4.x) projects. Or directly created packages out of legacy csproj? Do you mind uploading your sample project to Github? I'm having lot of trouble referencing legacy DLL/projects (.NET 4.x). RC1 allowed us to directly reference legacy projects. I'm struggling to upgrade to RC2. I have a bunch of legacy projects (DLLs) to use in RC2.

I tried creating a class (Core) project and plain Class library project and referenced legacy projects and created Nuget packages and tried to install them in core project. Either way, it still complains "The dependency xxx could not be resolved"

Thanks much.

kotylo commented 8 years ago

@inianp This one:

Or directly created packages out of legacy csproj?

Just create package from your .NET 4.x .csproj, if you have sources, that is. For some reason it didn't work for me if I tried to create Nuget package directly from DLL. Maybe I did something wrong there.

mikebm commented 8 years ago

I was able to get the references to stop complaining by using the dnx RC1 wrap project.json and changing the target to net451.

It appears to build and work, but the using statements still show errors, and there is no intellisense like others have noted.

mikebm commented 8 years ago

@skyflyer Why was this closed if this is still an issue?

skyflyer commented 8 years ago

@mikebm, I closed this issue because I was asking how to run on full framework with referenced assemblies and I managed to get it working, even though the tooling is ...

I also shared my project on how I did it. Even though the VS reports that it is an unknown reference, the build succeeds and the end result is working (as you have mentioned yourself). For the visual studio, I've filed a bug from within visual studio. I don't think leaving this issue open will resolve this, unfortunately...

ddotlic commented 8 years ago

I'm seeing the issue of VS not recognizing the referenced DLL, so lots of red squiglies :disappointed:

Is there a relevant issue to discuss this problem?

mikebm commented 8 years ago

I just created an issue in the aspnet tooling repo. You can follow it here: https://github.com/aspnet/Tooling/issues/565

Hopefully that was the correct place to put it.

skyflyer commented 8 years ago

@ddotlic, I'm not sure what the correct issue for discussing this would be. In general it is a pretty sad state if you want to run on full .net framework.

@Eilon et al, a very concrete situation for my customers is that they'd like to use MVC 6 (ASP.NET Core MVC?) on full .NET framework (.NET 4.5.1, for instance), since they have 3rd party dependencies on .NET 4.5.1 (like IBM CTG, IBM DB2 etc. assemblies). So, we're left wondering when (if at all??) this scenario will be supported? Or is the only way forward to wrap the assemblies in project.json projects and export them as NuGet packages? If so, could you please point us in the direction of the previous dnu wrap command, which is not available anymore (with the new dotnet toolchain)?

ddotlic commented 8 years ago

@skyflyer Some of the devs on my client's team managed to work around this in some hyper-ugly way, but I'm not holding my breath until tooling reaches RTM... it's indeed a silly regression to have that Microsoft does not seem to recognize as a serious issue... sigh.

Eilon commented 8 years ago

@skyflyer yes, ASP.NET Core is fully supported on .NET Framework on Windows. To add a reference to a "loose" assembly on disk, you will indeed need to manually "wrap" it into a NuGet package. Unfortunately the Preview 2 tooling release that just came out doesn't have a built-in "wrap" feature, so you need to do that step manually.

ddotlic commented 8 years ago

@Eilon That's not really a solution, the problem did not exist prior to RC2, it's a regression, hence many disappointed comments here and in the other similar items. If we did this, we'd still throw that work away as soon as tooling is repaired. It would have been OK if there were a sample showing how to do this, but I'm not aware of one.

Eilon commented 8 years ago

@ddotlic I agree it's a take-back and it's certainly not ideal. There are plans to fix this in updating tooling but there isn't anything available just yet.

lilpug commented 8 years ago

@Eilon could you link where its scheduled in the tooling update as this issue still persists and we and many other companies cannot move to production when we cannot even add relevant dll libraries that are not in Nuget

Eilon commented 8 years ago

@lilpug we just did a blog post a few days ago that includes the roadmap. Check it out here: https://blogs.msdn.microsoft.com/dotnet/2016/07/15/net-core-roadmap/

The switch to MSBuild will make this work:

.NET Core Tooling • Support for .csproj/MSBuild project system

gerryLowry commented 8 years ago

My "me, too" and my actions to date ...

For me, it is unclear as to whether this is/will be resolved in a timely fashion.

Abbreviated steps to reproduce:

(a) create ANY basic .NET Framework Library, example:

https://github.com/gerryLowry/TemperatureConversionNet452

(b) Create a Web Api solution based on .NET 4.5.2 and reference the basic .NET Framework Library from (a), above.

The above works and the ValuesController method GET api/values can be easily tweaked to use static methods from (a) above.

(c) Create a CORE Web Api solution and reference the basic .NET Framework Library from (a), above.

THIS FAILS with this Error:

A) .NET Core projects only support referencing .NET framework assemblies in this release.

B) To reference other assemblies, they need to be included in a NuGet package and reference that package.

COMMENT:
the assembly being referenced is a .NET framework assemblies; the error message appears to be incorrectly worded ... perhaps whoever coded the above error message intended CORE .NET framework assemblies ????

As presented, the statement A), above, is false.

Failed attempt # 1

added a NuGet package even though the .DLL is a .NET Framework 4.5.2 package.

see TemperatureConversion.1.0.0.0.nupkg

Failed attempt # 2

tweaked the json ... this may not be correct; however, it is roughly modelled on articles Miha Valencic a.k.a. skyflyer and others:

  "frameworks": {
      "net452": {
        "bin": {
        "assembly": "external\\TemperatureConversion666.dll",
        "pdb": "external\\TemperatureConversion666.pdb"
        }
      }
    },

Note that while lines for "assembly" and "pdb" are likely NOT correct,
even if they were, it is highly likely that the following errors
would occur nevertheless:

Error    
NU1002    
The dependency Microsoft.NETCore.App 1.0.0 does not support framework .NETFramework,Version=v4.5.2.    

Error
NuGet Package Restore failed for one or more packages.
See details in the Output window.

MORE INFORMATION

20116-07-15 Roadmap

1.0.1 (~August 2016) does not appear to address this issue (4682)

@Eilon ... for me, it is unclear as to why you referenced the roadmap above.

@ ALL ...

can it be unequivocally stated that Microsoft.NETCore.App(1.0.0) applications will function with .NET Framework 4.5.2 libraries?

if yes, HOW to make that happen?

thnx/Gerry

skyflyer commented 8 years ago

@gerryLowry, I very much feel your pain. From what I understand (and I may be totally wrong here), there's the "compatibility matrix" that defines which type & version of a "package" is compatible with what. See the doc explaining it.

In my experience, it is not intended to consume full .NET assemblies in .NET Core apps, but rather the other way around (Microsoft, am I wrong?). Having seen the matrix, it "reads" that if a package targets netstandard1.2, it can be consumed in a .NET 4.5.2 application. Looking through some of the published assemblies by Microsoft (i.e. Microsoft.Extensions.Configuration.Json) I see that they're mostly targeting two platforms. .NETStandard1.3 and .NETFramework4.5.1 in this case.

The experience in using those assemblies tells me everything is not tested, as I've had some issues getting those kind of assemblies to work in a .NET 4.5.1 web application.

To add to confusion, the TFMs (target framework monikers) in Microsoft's packages use different monikers than those listed in the document1 (.NETFramework4.5.1 instead of net451, .NETStandard1.3 instead of netstandard1.3, etc) or document2.

And, to finally address your question:

can it be unequivocally stated that Microsoft.NETCore.App(1.0.0) applications will function with .NET Framework 4.5.2 libraries?

I don't think so, since .NET 4.5.2 (the base class library) has more (and some different) functionality than .NET Core 1.0. I don't know exactly what's missing from .NET Core (but it would be nice if this was documented somewhere). Some references worth reading. I guess that netstandard-* is the answer to this confusion...

gerryLowry commented 8 years ago

@skyflyer

From the ASP.NET Core 1.0 Schedule and Roadmap:

"The November and May release candidates (RC1 & RC2) are supported and production-ready cross-platform releases."

production-ready

perhaps "somewhat production ready" would be more appropriate.

Here is a very trival 4.5.2 class library: TemperatureConversionNet452

using System;

namespace TemperatureConversion
{
    public class CelsiusFahrenheit
    {
        public static Double Celsius(Double fahrenheit)
        {
            return (fahrenheit - 32d) / 1.8d;
        }

        public static Double Fahrenheit(Double celsius)
        {
            return (celsius * 1.8d) + 32d;
        }
    }
}

There is nothing in the above code to prevent it from working in all versions including Core.

The pain you feel is more than just mine; it is the collective pain of our global gobsmacked community.

isA Lie by any other name still a lie?

"Does your dog bite?"

.NET Standard Library "Each .NET runtime version advertises the highest .NET Standard version it supports, a statement that means it also supports previous versions."

"It's not my dog."

The table ".NET Platforms Support" at .NET Standard Library implies that .NET Core, a.k.a. netcoreapp will never be able to reference .NET Standard, a.k.a. netstandard.

the real problem / truth in advertising

Given the number of globally gobsmacked complainants, imho it's fair to suggest that a disclaimer be presented when one is choosing, for example, which version of Web API to use.

 a disclaimer would keep us from painting ourselves into a corner

Miha, if you revisit the table, .NET Standard (netstandard), .NET Core (netcoreapp), and .NET Framework (net) are all on separate rows; imho, wishful thinking on my part, they should be able to reference one another.

.NET Core Roadmap, version 2016-07-15

the following is open to interpretation:

Q4 2016 / Q1 2017
This will be the first minor update, mainly focused on replacing .xproj/project.json
with .csproj/MSBuild.

Project format update should be automatic. Just opening a 1.0 project
will update it to the new project format. There will also be new functionality
and improvements in the runtime and libraries.

As context, .NET Core 1.0 included a preview version of the .NET Core Tools,
referred to as “Preview 2”. The tools were “preview” primarily because
we knew that we would change the tools experience post 1.0.
.NET Core and the .NET Core Tools will both be “RTM quality” or “stable” with this release.

.NET Core Tooling
Support for .csproj/MSBuild project system
dotnet restore improvements to not restore packages that are part of .NET Core
New commands for managing the frameworks on the machine
dotnet publish will publish only required dependencies, for optimal distribution size

BOTTOM LINE

WEB-facing applications and DESKTOP-facing applications share many Enterprise custom code bases; it's the customized code that can give one company a competitive advantage over another company.

FWIW, this needs to be fixed, soon; if that does not happen, it may cost Microsoft loss of customers; already it has cost Microsoft loss of trust.

Eilon commented 8 years ago

The support statements were true when they were made and continue to be true. Running .NET Framework assemblies on .NET Core is not supported. That doesn't mean it won't work. But it's definitely not supported. And there are countless cases where it in fact won't work - e.g. try using System.Web or WCF. It turns out that if the API surface used by the assembly is sufficiently limited and doesn't conflict with anything in .NET Core, it'll work. It's ultimately just a plain old .NET DLL that contains MSIL, so as long as it has the right references, it'll generally work.

The only supported ways to implement this scenario is to either:

  1. Cross-compile the code for each target framework, and thus have one assembly per target framework.
  2. Build one assembly that targets one of the netstandard targets that support all the desired .NET implementations, e.g. netstandard1.2.
redowl3 commented 8 years ago

Admittedly, I have only just started looking into moving from RC1 (and the only reason we're doing it now is that Azure now only supports RTM applications) but we're running into trouble at almost every turn. Third party libraries that we are using have not been moved to Core versions and bits of the framework haven't been ported across (System.Data).

If running .Net framework assemblies on .Net Core is not supported how do we move forward?

davidfowl commented 8 years ago

If running .Net framework assemblies on .Net Core is not supported how do we move forward?

You can run ASP.NET Core on .NET Framework or .NET Core.

redowl3 commented 8 years ago

Hi David, thanks for the response, how do we do this? As examples, we are using SendGrid for emails and there doesn't appear to be a Core compatible version. We also use DataSets for reading from Excel files and having trouble referencing that as well.

Eilon commented 8 years ago

@redowl3 have your project target net451 (or similar) instead of netcoreapp1.0 in the frameworks section of project.json. That will use .NET 4.5.1 (or similar), which means that you can use just about any .NET 4.5.1-compatible NuGet package. SendGrid should work just fine (I haven't tried it, but I can't imagine why it wouldn't work).

redowl3 commented 8 years ago

Thanks Eilon. When we target net451 does that mean all referenced projects need to target net451 instead of netcoreapp1.0?

Is this how MSFT envisaged working with non core assemblies would be?

redowl3 commented 8 years ago

We're having real trouble in finding out how to reference multiple frameworks to update our working RC1 solution to RTM (which has been forced on us by the decision by MSFT not to support these versions on Azure). The solution suggested by Eilon has helped fix some issues but created others.

djfr commented 7 years ago

I landed here trying to google if there is a way to target multiple frameworks in project.json and still do a nuget pack without using a nuspec, thanks google!

@redowl3 @gerryLowry

It saddens me to see everyone complaining about project.json and the dotnet CLI departure from MSBuild with expectations that one can actually move without changing stuff ... Using datasets in 2016, is doing it wrong, it's code that should have been refactored ages ago.

project.json and the dotnet CLI is a breeze of fresh air in the Microsoft space, it is a very clever attempt to bring the stack closer to what the rest of the world is doing in the node.js stack and the rest of the open source stack. Working with these two is a very nice development experience, despite all the current issues with packing and immature tooling around them.

MSBuild was/is a pain to customize, a pain to deploy custom extensions across a globalized code base, the development experience is a piece of crap and editing the proj files XML is clunky.

Azure doesn't force anyone to do anything! If I'm using Azure App Service without deploying my own ASE there's not much I can do to control my stuff. However if I want to do my own thing and have a high level of control I'm on other PaaS offerings with other level of control: Docker, App Service Fabric, Cloud Services, etc. I think there's still people maintaining Docker images with the preview versions of DNX :)

redowl3 commented 7 years ago

Hi djfr, thanks for joining in the discusssion.

In our particular circumstances we do need to use DataSets as we are using a 3rd party library that converts Excel to DataSets. Like a significant amount of 3rd party components this has not been ported to Core so we need to target multiple frameworks, which in our opinion has been a major pain, mainly due to the complexity of trying to understand multiple frameworks, dependencies, includes etc... We totally understand the direction MSFT are trying to move to and that there would be some pain points along the way.

And your right Azure does not force anyone to do anything(!) but again in our circumstances we had an ASP.NET RC1 application running very nicely in the cloud but since this announcement (https://blogs.msdn.microsoft.com/waws/2016/06/14/supporting-asp-net-5-core-rc1-on-azure-app-service/) if we want to continue hosting our application on Azure we are 'forced' to upgrade to Core.

benzhi2011 commented 7 years ago

Hello All, I haven't read all the discussion. I start working with .net core framework (not the real core, but ASP.NET Core Web Application(.net framework)) few weeks ago, I am having a problem with referencing the DLL. I can add the NuGet package that I created myself, but the intelligence would not recognize the namespace. If I add reference to the project directly with source code in the same solution, then everything works fine. In this way, I have to have the source code for the projects that I am willing to reference . I assume this is a bug, but correct me if the core framework is designed this way.

kotylo commented 7 years ago

@benzhi2011 I haven't read all your comment, but basically no actual support for "old" .net 4.5.2. Even Azure will only support Core.

As a workaround, you can have intellisense by adding the dll through Nuget Package manager. So you can create your own package from solution, then setup .net core project to use the Nuget.config file :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="MyProjectSource" value="nuget\packages" />
  </packageSources>
</configuration>
benzhi2011 commented 7 years ago

@kotylo Thank you for your workaround, it works perfect.

Eilon commented 7 years ago

We are closing this issue because no further action is planned for this issue. If you still have any issues or questions, please log a new issue with any additional details that you have.