I am using VS Pro Update 3
I have been following the guide here: https://www.hanselman.com/blog/HowToReferenceAnExistingNETFrameworkProjectInAnASPNETCore10WebApp.aspx
I have 3 existing .NET 4.5.1 Class Libraries, written in VB.NET but I don't think that should matter as it's all on CLR.
My ASP.NET Core project is C#, targeting .NET 4.5.1.
Here is the Framework section of my project.json:
"frameworks": {
"net451": {
"dependencies": {
"WebApp.Api.Services": {
"target": "project"
}
}
}
},
If I add all my VB.NET class libraries using Add Existing Project to my solution and try to add them as project reference, I get the following error:
Project XXX type is unsupported by current project and cannot be added
as a reference
I also tried adding a C# class Library (WebApp.Api.Services), add VB.NET references to that, then add the C# Class Library as a reference to the ASP Core project
Doing this shows the references in Solution Explorer okay, it seems as though I can use types from the C# Class library but I can't use the VB.NET library's types in my code.
I also created a NuGet package, but no luck
I have read that you can create a 'wrapper' project somehow, or Visual Studio can do this automatically.
Has anyone ever tried adding VB.Net projects to ASP Core solution?
A project built for .NET Core cannot use class libraries built for .NET Framework. They are not directly compatible with each other. In fact I'm confused when you say:
My ASP.NET Core project is C#, targeting .NET 4.5.1.
If it's targeting .NET 4.5.1, then it's not actually a .NET Core project.
You should port your class libraries to .NET Standard; that way they can be used by a wide range of compatible frameworks. It is also possible to have a class library target multiple frameworks.
I managed to solve my issue.
The guide here is correct, I had another different issue that I didn't realize.
I found a System.BadImageFormatException error which lead me to the following question Start an asp.net core project as x86 under visual studio 2015
I uninstalled the x94 version of .NET Core and installed the x86 one.
I still could not add references to the VB.NET libraries to the ASP Core project, so my C# services 'Bridge' library was vital.
In my 'Bridge' library I have Models that I can return from my ASP Controllers:
Public BridgeModelA : VB.NETLibrary.ActualModelA
{
…
}
Then extensions
Public static VB.NETLibrary.ActualModelA ToModel(this BridgeModelA)
{
…
}
Although the base members of these models cannot be accessed in the controllers, due to ASP proj not referencing the VB projs, they are returned by the controller with JSON result containing all base members.
This is actually great as it fits in with the design of thin controllers.
Related
My understanding is that, starting with ASP.NET Core 3.0, .NET Framework is an unsupported target framework, and thus you can only run on the .NET Core runtime.
If this is the case, what NuGet packages can be imported into an ASP.NET Core 3 app?
I assume that you could reference any package that targets netstandard, but what about packages that only target the full framework (i.e., a legacy package that only targets net45)?
What happens if the package you import references an assembly that's not part of .NET Core—i.e., System.Drawing?
TL;DR: You can still reference (packages which depend upon) .NET Framework assemblies from .NET Core 3 and even .NET 5, but you will receive a runtime error if you call into any code which relies upon APIs or libraries not (yet) supported by .NET Core. You can discover these using Microsoft's .NET Portability Analyzer
Background
First off, you're correct that ASP.NET Core 3.x applications can no longer target the .NET Framework, as announced by Microsoft in 2018. That capability previously allowed ASP.NET Core applications to call into .NET Framework libraries, and thus offered an intermediate solution for web applications migrating to .NET Core.
Note: Since the .NET Framework only runs on Windows machines, writing ASP.NET Core web applications which targeted the .NET Framework implicitly restricted those applications to running on Windows.
Behavior
Even when targeting .NET Core or now .NET 5, however, you're still able to reference .NET Framework packages and assemblies, assuming you're on a Windows machine and have the corresponding .NET Framework installed. The inner workings of this are a bit involved, but the short of it is that .NET Core and .NET 5 will evaluate .NET Framework assembles as though they are .NET Standard assemblies. If the API call is also implemented in the .NET Core runtime, it will work fine—but if the API call is exclusively part of .NET Framework, you'll receive an exception.
Surprise! It's really important to emphasize that this is a runtime exception. You will still be able to reference the .NET Framework assembly, write calls to problematic members, and compile your code without any warnings. But as soon as you call into code dependent on a .NET Framework-specific assembly, you'll receive the runtime exception.
Example
With .NET 3.0, a significant portions of .NET Framework libraries have been ported over to .NET Core. In fact, this includes most of the System.Drawing libraries you referenced as an example—though there are good reasons you may not want to use them. If you dig a bit deeper, however, there are plenty of libraries which remain unsupported. One obvious example is the WebConfigurationManager, which could be used to access configuration settings from web.config files.
.NET Framework Code
So, as an example, let's say you have the following function in a .NET Framework class library, which returns an array of keys from your web.config's <AppSetting>s element:
public static class Configuration
{
public static string[] GetAppSettings() => System.Web.Configuration.WebConfigurationManager.AppSettings.AllKeys;
}
ASP.NET Core Code
And then, in an ASP.NET Core controller, you expose an endpoint to retrieve this data:
public class MyController: Controller
{
public IActionResult ApplicationKeys() => Content(String.Join(", ", Configuration.GetAppSettings()));
}
Exception
In an ASP.NET Core 2.x application targeting the .NET Framework, this will work just fine. In an ASP.NET Core 3.x or ASP.NET Core 5 application, however, you'll receive the following runtime error when you call the /My/ApplicationKeys/ route:
System.TypeLoadException: 'Could not load type 'System.Web.Configuration.WebConfigurationManager' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.'
Avoiding Surprises
If you're anything like me, this will make you incredibly nervous. You'd much rather receive design-time errors—or, at least, compile-time warnings—as soon as you attempt to call into a library relying upon unsupported code. Fortunately, Microsoft offers a .NET Portability Analyzer, which is also available as a Visual Studio Extension, for exactly this purpose.
As of .NET 5, there's also a compatibility analyzer built into the SDK which will identify calls that are not supported by the .NET 5 runtime on particular platforms. This requires that target libraries explicitly annotate their types with the [SupportedOSPlatform()] attribute, so you won't get any warnings for legacy .NET Framework types. But this will help identify similar types of compatibility issues for libraries targeting a variety of platforms.
Example
If you run the Portability Analyzer on the above sample code, for example, it will output an Excel spreadsheet identifying that T:System.Web.Configuration.WebConfigurationManager is Not Supported in e.g. .NET Core,Version=v3.1 or .NET Standard + Platform Extensions,Version=v2.0.
Note: Microsoft used to offer an API Analyzer as a NuGet package, which promised to provide design-time analysis in Visual Studio. Unfortunately, the code hasn't been updated in two years, and the latest release is 0.2.12-alpha. In my evaluation, it was not effective at identifying issues.
Sample Project
I've put together a sample project on GitHub which demonstrates the above behavior. It includes the following projects:
ASP.NET Core 2.0 Website targeting .NET Framework 4.8
ASP.NET Core 3.1 Website targeting .NET Core 3.1
.NET Framework class library with calls to the legacy WebConfigurationManager
Both ASP.NET Core websites include two endpoints which call into the same .NET Framework 4.8 class library. The first is a "Hello world" example which will execute fine on both projects, since it relies exclusively on common APIs:
http://localhost:5000/Basic/Index
The second will fail on the ASP.NET Core 3.1 project, since it calls into the legacy WebConfigurationManager API:
http://localhost:5000/Basic/Configuration
Disclaimer: This is a quick and dirty repository that I put together to verify my understanding prior to posting this. If there's interest, I'll tidy it up and document it. For now, however, it may prove useful for those of you who need to see this in action.
Acknowledgments
#Chris Pratt offered an excellent answer covering similar material last year. It's worth reading.
I am working on a .net core web application with razor pages.
My application structure is like :
DemoCoreApplication with class Libraries "BLL.Data" and "BLL".
In BLL.Data, I have made the DB context then I have added the reference of "BLL. Data" project into my main project i.e: DemoCoreApplication.
Refrences in BLL.Data class library:
After building the main project (DemoCoreApplication), I got some strange version conflicting errors.
I believe the following steps will solve your problem
Install .Net Core 2.2 SDK (if you don't have)
Convert all projects in the solution to use .Net Core 2.2
Rebuild, Start the project
I am new to this area. I already upgraded my VS2015 with update 3. So now I have: .Net Core 1.0.0 with preview tool 2 installed.
Then I use VS2015 to create a new .Net Source project (class library). I have copied some existing .net 4.6.1 code to the new place and compiled error as expected. Then I use "porting analyzer tool"(https://learn.microsoft.com/en-us/dotnet/articles/core/porting/index) to compare and it did give some suggestion how to use the new way in .Net Core.
But there are still few class missing and cannot compile, like 'TypeDescriptor' or 'NullableConverter' etc. Then I googled and someone from Github say they already added these feature but I still not sure why I still get compilation error.
I also noticed that my class libary project has a project.json file as:
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
I foundn if I remove the 'netstandard1.6' one but change to:
"frameworks": {
"net461": {}
}
All the compilation error gone, but I could guess it's NOT .Net core project anymore, and more likely as a standard .Net 4.6.1 project.
So basically I'd like to ask:
Why developer from Github saying that is fixed already but I still couldn't find/compile those classes in my project (e.g. TypeDescriptor : https://github.com/dotnet/corefx/issues/8262)?
Some sample also puts both 'net461' & 'netstard1.6' or 'netcoreapp1.0' under 'frameworks' in project.json file. What's the purpose for that?
If I just use 'net461' for the only framework, there seems no difference to traditional .Net Framework 4.6.1 project. Am I correct?
Thanks a lot!
Install package System.ComponentModel.TypeConverter and you are good to go with .NET Core project.
For building different output (binaries) each of which targeting different platform. net461 for applications which should run on (full) .NET Framework (under Windows or Mono). netcoreapp1.0 used for app which should be run under .NET Core. netstandard1.6 (avoid using netstandard1.5 and netstandard1.6 by the way - use previous versions) used for portable class libraries, which are supposed to run under different platforms: (full) .NET Framework, .NET Core, Xamarin, Universal Windows App, etc. You may read more about here and here.
Absolutely.
Our project structure is like,
native.dll :- This contains pure native code written in c\c++.
This native.dll exposes some functions using *def file.
Wrapper Library(wrapper.dll compiled with .Net framework v4.0) :-
In order to use functionality of native.dll, a Wrapper lib(wrapper.dll)
is written in C++\CLI using :clr\oldsyntax. This wrapper has all
code of Interoperability and Marshalling.
Application(Console App v4.0) directly uses wrapper.dll to use functionality provided
by native.dll.
Now this project needs to run in .Net Core. This means we will have an
.Net Core application that will reference wrapper.dll that in turn will refer
native.dll.
I know this will not directly work. But the issue is whether .Net Core(CoreCLR) supports
C++\CLI (clr\oldsyntax) runtime environment ?
If no, what can be the possible solutions to this application work ?
whether .Net Core(CoreCLR) supports C++\CLI (clr\oldsyntax) runtime environment ?
As far as I know there is no plan to support C++/CLI with .NET Core.
If no, what can be the possible solutions to this application work ?
You can (should) provide a C API. Mono e. g. supports P/Invoke and .NET Core also supports P/Invoke (see also this Stack overflow question and this DllMap related ticket).
Update (2022-09-02): This answer is from 2016. See the other answers (e.g., this) for what is possible with recent .Net Core versions.
Officially announced eventually...
(next wish... support linux # .Net 5 ^^)
https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/
C++/CLI will have full IDE support for targeting .NET Core 3.1 and higher. This support will include projects, IntelliSense, and mixed-mode debugging (IJW) on Windows. We don’t currently have plans for C++/CLI for targeting macOS or Linux. Additionally, compiling with “/clr:pure” and “/clr:safe” won’t be supported for .NET Core.
The first public previews for C++/CLI are right around the corner. Visual Studio 2019 16.4 Preview 1 includes an updated compiler with “/clr:netcore”
Updat: From replied of origin url:
"We are still working on the IDE and MSBuild integration, so I can’t share a sample project quite yet. Once it’s available, likely with 16.4 Preview 2 or 3"
(16.4 Preview1 cannot create C++/CLI with .NetCore project.)
191015
16.4 Preview2 Released.
I'v tried asp.net core 3.1 with c++/CLI dll, it works.
(need set plateform to x64 both asp.net core and c++/CLI dll)
.net Core team will only commit (now?) to supporting C++/CLI for Windows only.
The intention was to deliver it for .net Core 3.0. While I haven't found explicit mention of it yet in the release notes, C++/CLI support was a prerequisite for delivering WPF (windows-only), which is now supported in .net Core 3.0.
Support mixed-mode assemblies on Windows - #18013
This issue (#18013) will track progress toward supporting loading and running
mixed-mode assemblies on CoreCLR. The main goal is to provide support
for WPF and other existing C++/CLI code on .NET Core. Some of the work
will be dependent on updates to the MSVC compiler.
The github issue (#659) mentioned above by #Tomas-Kubes, Will CoreCLR support C++/CLI crossplat? - #659, is about cross-platform C++/CLI.
BTW, I am getting compiler warnings on "clr\oldsyntax" with VS2017/.net-4.7. So this compiler flag is already deprecated.
UPDATE: This isn't coming till .Net Core 3.1
Another potential solution (though obviously quite a difficult task) if you want to stick with C++ (i.e. expose an OO interface to .NET) might be to have a look at CppSharp from the mono project. It is able to expose native C++ code through an automatically generated C# wrapper. It supports Windows, Linux as well as OSX. However, I don't know if the generated code can be compiled to a .NET standard target (didn't try to). I can only suppose it would because the generated code does not use any fancy API (it is basically interop and marshalling code); and, by the way, it is also possible to customize the generation process (although, once again, probably not an easy task).
For those who are looking at this for general .Net Core stuff without specific clr parameters (as this is a high result on google) Microsoft have written a guide on how to port C++/CLI to .Net Core:
https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cli
Port a C++/CLI project
To port a C++/CLI project to .NET Core, make the following changes to the .vcxproj file. These migration steps differ from the steps needed for other project types because C++/CLI projects don't use SDK-style project files.
Replace <CLRSupport>true</CLRSupport> properties with <CLRSupport>NetCore</CLRSupport>. This property is often in configuration-specific property groups, so you may need to replace it in multiple places.
Replace <TargetFrameworkVersion> properties with <TargetFramework>netcoreapp3.1</TargetFramework>.
Remove any .NET Framework references (like <Reference Include="System" />). .NET Core SDK assemblies are automatically referenced when using <CLRSupport>NetCore</CLRSupport>.
Update API usage in .cpp files, as necessary, to remove APIs unavailable to .NET Core. Because C++/CLI projects tend to be fairly thin interop layers, there are often not many changes needed. You can use the .NET Portability Analyzer to identify unsupported .NET APIs used by C++/CLI binaries just as with purely managed binaries.
Build without MSBuild
It's also possible to build C++/CLI projects without using MSBuild. Follow these steps to build a C++/CLI project for .NET Core directly with cl.exe and link.exe:
When compiling, pass -clr:netcore to cl.exe.
Reference necessary .NET Core reference assemblies.
When linking, provide the .NET Core app host directory as a LibPath (so that ijwhost.lib can be found).
Copy ijwhost.dll (from the .NET Core app host directory) to the project's output directory.
Make sure a runtimeconfig.json file exists for the first component of the application that will run managed code. If the application has a managed entry point, a runtime.config file will be created and copied automatically. If the application has a native entry point, though, you need to create a runtimeconfig.json file for the first C++/CLI library to use the .NET Core runtime.
There are some more nuances but these are the actual steps to port
I am trying to create a class library that'll contain common objects (mainly DTOs) of a WebAPI (using ASP.NET 5) and a consuming UWP App. However, I have not yet figured out how to create the class library such that it can be referenced from both other projects.
What I have tried so far:
First, I tried a Class Library (Package), which can be found under Web. This type of library can be referenced from the ASP.NET project without problems, but when trying to reference it from the UWP project, I get the following message:
A reference to 'ClassLibrary1' could not be added.
Next, I tried a Class Library (Windows Universal), which can be found under Windows > Universal. This can easily be references from the UWP project, but when trying to reference it from ASP.NET, I get:
The following projects are not supported as references :
- The project ClassLibrary2 has a target framework that is incompatible or has version higher than the current project and cannot be referenced.
So: How can I create a class library that can be used in both an ASP.NET 5 project and an UWP project?
What you need is a Portable Class Library (under Windows).
Since you're only targetting ASP.NET 5 and Windows 10, you can limit the platforms to these two only, but there's no "error" in supporting more platforms (it can limit how much of the shared API is available though).
The .Net Standard class library should be thought of as a successor to the portable class library. Both aim to facilitate sharing code (in this case model objects/DTOs) between different .Net platforms.
In Visual Studio 2017, you can now choose a .Net Standard class library template. This class library can bet set to target different versions of the .Net Standard. The version of the .Net Standard that you should target will depend upon what .Net platforms you wish share code between.
For this particular question, we wish to support a Universal Windows Platform (UWP) app and Asp.Net Core app. So, we should refer to this compatibility table to determine the version of the .Net Standard that will support both of these platforms. In this case, it would be .Net Standard 1.4. Once you have set the class library to target the .Net Standard 1.4, you can add references to the class library from your UWP and Asp.Net core projects.
In order to better understand what the .Net Standard is and how it facilitates code sharing, I suggest reviewing the following:
Introducing .NET Standard
Video Series on .NET Standard (this is particularly good)
.Net Standard FAQ