Standard: Add System.ComponentModel.DataAnnotations to .NET Standard

Created on 17 Aug 2017  Â·  32Comments  Â·  Source: dotnet/standard

I have started to upgrade our Domain / Logic libraries from PCL and full .NET to .NET Standard 2.0 libraries. Unfortunately, just one dependency is missing: System.ComponentModel.DataAnnotations.

Please add System.ComponentModel.DataAnnotations to the next version of .NET Standard so that I can upgrade my libraries.

netfx-compat

Most helpful comment

While this isn't part of the standard we do have a nuget package https://www.nuget.org/packages/System.ComponentModel.Annotations/4.4.0 that support .NET Standard that you can consume.

All 32 comments

Related issue: #435

While this isn't part of the standard we do have a nuget package https://www.nuget.org/packages/System.ComponentModel.Annotations/4.4.0 that support .NET Standard that you can consume.

Consuming the System.ComponentModel.Annotations NuGet package does not work.

Our Domain / Logic libraries are used within classic .NET Framework applications. These applications contain a lot assemblies which cannot be changed to .NET Standard (e.g. WPF). And they reference the System.ComponentModel.DataAnnotations from the classic .NET Framework. Some of them are 3rd party libraries so I cannot replace the System.ComponentModel.DataAnnotations reference with the NuGet package from the .NET Core Framework.

The solution is that .NET Standard includes System.ComponentModel.DataAnnotations like the _legacy_ PCL libraries do.

Just so I understand you correctly you are consuming .NET Framework libraries which have assembly references to System.ComponentModel.DataAnnotations? In which case adding the APIs to .NET Standard will also not help. What is needed in either case is a System.ComponentModel.DataAnnotations facade that unifies the APIs.

So that could be accomplished by adding System.ComponentModel.DataAnnotations APIs to .NET Standard and providing a facade assembly or we could also accomplish it by just adding the facade assembly to unify with System.ComponentModel.Annotations nuget package.

@terrajobst what are your thoughts on this? I think we could provide the facade and make it work today without a need for a revision of .NET Standard itself.

Maybe a concrete example helps to clarify my scenario. I use the class ValidatableModel which is part of a PCL library in a

  • WPF application which uses System.ComponentModel.DataAnnotations. Example: Book class
  • UWP app which uses System.ComponentModel.Annotations.

This works with PCL.

cc @lajones @ajcvickers who own DataAnnotations.

@jbe2277 I understand that PCL's supported this but that doesn't mean the APIs have to be part of .NET Standard. I definitely think we can make your scenario work when targeting .NET Standard we just need to figure out how to plumb in the necessary facades to unify the types.

Update: I got it running. The missing part was to install the NuGet package System.ComponentModel.Annotations in the application project and unit test projects as well. The package contains the necessary type forwards already.

See also the answer of Immo Landwerth to my blog comment: https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-standard-2-0

Now my question is still valid but the priority is lower with this workaround:

Could System.ComponentModel.DataAnnotations be added to the .NET Standard?

Update: The planing .NET Standard 2.1 page shows that DataAnnotations will NOT be included. Reason: Out-of-band today.

As mentioned in previous posts there is a workaround for using such .NET Standard libraries with .NET Framework applications (e.g. WPF). But I ran again into a lot issues (especially the unit test projects took much time). These issues are summarized here: #481.

Please reconsider to include DataAnnotations in .NET Standard vNext. The workaround has too much issues.

@jbe2277

I don't understand your reasoning. The issue you're linking is specific to .NET Framework 4.6.1 and .NET Standard 2.0. Whether or not we'll add these APIs to .NET Standard 2.1 is orthogonal (neither hurts not helps that case). If you consume .NET Standard 2.0 from .NET Framework 4.7.2 today, you won't see any of these issues.

@terrajobst

I checked it now with .NET Framework 4.7.2 and the latest VS 2017 version 15.8.4. But the issues are still here.

I have a .NET Standard 2.0 Lib which uses the NuGet package System.ComponentModel.Annotations.

Integrate into a newly created WPF 4.7.2 project
During runtime a developer will get a FileNotFoundException of assembly System.ComponentModel.Annotations. This exception message does not help to understand how this issue can be solved. The exception message nor the compiler would say anything about that a NuGet package needs to be installed.

Integrate into a newly created Unit Test 4.7.2 project
First, a developer will run into the same issue as for the WPF project. Additionally, the necessary binding redirects are not added to unit test projects. So a developer has to edit the .csproj file and add:

<PropertyGroup>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

At the moment I have to stay with Portable Libraries because they support DataAnnotations and they just work. But I hope that someday DataAnnotations will be added to .NET Standard. Then I can migrate my libraries to .NET Standard and they will just work again.

I'll take a look. It should just work on .NET Framework 4.7.2.

Are you building for .NET Framework 4.7.2 as well or are you just running on .NET Framework 4.7.2?

Hi Immo,

we have the same issue. Currently it is not possible to run a WinForm Application which references a .NET Standard Library containing Entity Framework Core 2.1.

Opening a Form in the Designer yields to the known exception:

Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.

The mentioned workarounds don't work. So I think the best way to avoid this problem is not using classic .NET 4.7.x with EF Core :-(

Or are there any other working solutions out there?

Greetings from Munich ;-)

I am able to use the latest EF Core with WPF 4.7.2.
Though there is a similar issue for System.ComponentModel.Annotations Version 4.2 in EF Core

This is actually a dupe of that issue that @gojanpaolo pointed out. In there I pointed out the workaround which is to ser the property RestoreProjectStyle to “PackageReference” in your main project and to migrate the library project to use PackageReference instead of packages.config.

This is not an issue with the framework, its an issue with the the way packages.config won’ copy transitive dependencies to other projects. PackageReference is the new and improved model so it should be the one used.

I'll take a look. It should just work on .NET Framework 4.7.2.

It won’t because this specific library is not inbox, its Oob.

@terrajobst
I was building the WPF project and the Unit Test project with .NET Framework 4.7.2 as target framework.

  • All projects are in the same Solution: A .NET Standard 2.0 library, a WPF project and a .NET Framework Unit Test project.
  • My WPF and Unit Test project are referencing the .NET Standard 2.0 library as project reference.
  • My .NET Standard 2.0 library references System.ComponentModel.Annotations version 4.5.0.

@jbe2277 can you try the workaround I outlined above to see if it fixes your issue?

@gojanpaolo I'm able to get it running with the workaround I have mentioned here. But this is quite complicated. As library author I need an approach that just works - like Portable Libraries.

The workaround you mention is about referencing the library via NuGet. Comments:

  • I would like that my libraries could be used without NuGet as well. Just be referencing the dll. -> Workaround needed.
  • NuGet solves this issue only if my library is directly referenced by the WPF or Unit Test project. If just another dependent class library references my library then this won't work. -> Workaround needed.

@jbe2277 could you please provide a sample project for repro (i.e. WPF w/ EF Core with this issue)?

@jbe2277 could you please provide a sample project for repro (i.e. WPF w/ EF Core with this issue)?

Hi, gojanpaolo!

I sent sample in another issue there: https://github.com/aspnet/EntityFrameworkCore/issues/13268#issuecomment-429987988

@gojanpaolo @terrajobst I have created two sample solutions for repro here: jbe2277/NetStandardAnnotationsIssues

I've just run into this issue in this project. I tried to update the Common library from .NET Core 2.0, but I ran into this issue for most versions of .NET Core from 2.0.3 to 2.1.5.

The message warns that System.ComponentModel.Annotations is missing, but it provides no other help. I've tried to install System.ComponentModel.Annotations via a nuget, but I still get the missing package message.

I don't get any of the workarounds discussed above. I'm stuck on .NET Core 2.0 until this issue is resolved. Any suggestions?

Experienced same issue in asp.net solution in integration tests project while porting EF->EF Core.
Fixed with adding following binding redirect to IntesrationTests/app.config.
First adding following binding redirect to each and every app.config/web.config fixed that error, than narrowed down to the integration tests' app.config itself

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.ComponentModel.Annotations" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
                <bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

The way I got this to work was to use System.ComponentModel.Annotations in the .net standard Lib and install the System.ComponentModel.Annotations in the WPF application and asp.net core application also. You have to install System.ComponentModel.Annotations in all the projects that will use the .net standard Lib

Closing as this is a dupe of the issues mentioned above (see https://github.com/dotnet/standard/issues/450#issuecomment-431028345)

@wtgodbe @joperezr I disagree with the closing comment. I still see the issue although I'm using PackageReference everywhere.

I have created two sample solutions for repro here: jbe2277/NetStandardAnnotationsIssues

We're just starting to use .Net Standard, I found the System.ComponentModel.Annotations library described above mostly works, but it doesn't contain MetadataTypeAttribute - how do we associate partial classes with metadata attributes for EF entities?

@jbe2277

I disagree with the closing comment. I still see the issue although I'm using PackageReference everywhere.

I'll take a look; that looks like a bug. However, I don't think the conclusion is that we need to add System.ComponentModel.Annotations to .NET Standard. There are many BCL-like features that we haven't added to .NET Standard, for example, immutable collections. The biggest reason is that updating the APIs/implementation is harder to do when the component is part of .NET Standard (as opposed to being available for .NET Standard). That being said, I'm not opposed to add it to .NET Standard (but I don't own data annotations, @lajones, @divega, and @ajcvickers do).

@jbe2277

As I suspected the problem is that the .NET Framework project doesn't use any packages yest (neither packages.config, nor PackageReference). This means MSBuild has to decide which mode the project is in. For backwards compatibility reasons, it defaults to the old style, which is package.config based. Changing the project property fixes the problem. I've submitted a PR for that.

I'm with @jbe2277 ; System.ComponentModel.DataAnnotations is a disaster and time sink for .NET Developers.

It seems @terrajobst main feedback is the decision on what to do with System.ComponentModel.DataAnnotations lies with @lajones and @ajcvickers . Here is my empassioned plea to those individuals.

Here are my main pain points:

  1. .NET Framework Pain: MSBuild.exe does not support bindingRedirect(s), so if you're on .NET Framework and want an MSBuild.exe Task that references System.ComponentModel.Annotations, you have to ensure that the version of MSBuild.exe you're running is compatible with the version of your Task. If this was handled as part of the framework, this would just go away.
  2. .NET Core Pain: The .NET Core CLI Tool User story is broken, in much the same way MSBuild.exe is broken because it does not support bindingRedirect(s). If I have a Common.dll that targets netstandard2.0 and want to reference in a netcoreapp3.0 CLI tool, I can't. The system cannot find the assembly. So, the default user story of "Global CLI Tool" introduced in .NET Core 2.2 is fundamentally broken from the start, and while adding System.ComponentModel.DataAnnotations does not fix this fundamental design flaw, including packages with ONE HUNDRED AND TWENTY MILLION DOWNLOADS sure does paper over this huge mistake/weakness - Microsoft already did a similar hack by writing their own System.Text.Json package so that the Microsoft internal Azure developers would stop getting Newtonsoft.Json version conflicts. Why can't you do it here? image
  3. The user experience of this Nuget package is bad, and reveals usability flaws in Visual Studio 2019.

    1. The versioning of this Nuget package is bad. Spare me the literal answer, and explain to the confused developer in me WHY Nuget package version 4.7 maps to dll version 4.2.

    2. Even if I was OK with a literal answer, explain to me WHY Visual Studio 2019 knows my package verison but when I expand my Dependencies, it can't tell me the DLL version.

      image

    3. Further, explain to me why when I go to my bin\Release\netstandard2.0\*.deps.json file, it knows that System.ComponentModel.Annotations 4.7 maps to 4.2 but VisualStudio does not.

      > json > "System.ComponentModel.Annotations/4.7.0": { > "runtime": { > "lib/netstandard2.0/System.ComponentModel.Annotations.dll": { > "assemblyVersion": "4.2.1.0", > "fileVersion": "4.6.26515.6" > } > } > } >

    4. When I get errors, I get the DLL verison (example below), not the nuget package version, so I expect my Integrated Development Environment (and nuget.org!) to help me search for the missing DLL. _While finding the right DLL won't work in all scenarios due to Diamond Dependencies, it might solve a large number of problems._ WHY IS THE ENTIRE .NET LINKER/LOADER SUB-SYSTEM DEPENDENT ON STACK OVERFLOW ANSWERS TO FIX BROKEN DEPENDENCIES, WHEN WE HAVE AN ELASTIC SEARCH ENGINE ON NUGET.ORG TO TELL US ALL THESE THINGS.

      > #### Example Error

      > While executing migrations the following error was encountered: Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

    5. Please, at least create an Microsoft Docs page and search engine optimize these pain points, or ask the SDK team to add some stupid MSBuild hack to give people some hints or warnings around this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

spottedmahn picture spottedmahn  Â·  5Comments

KexyBiscuit picture KexyBiscuit  Â·  3Comments

rathnagiri picture rathnagiri  Â·  3Comments

KexyBiscuit picture KexyBiscuit  Â·  3Comments

valeriob picture valeriob  Â·  4Comments