the cloud way

Upgrade from .NET 6 to 7, Microsoft.AspNetCore.DataProtection Missing Method Exception

Published Reading time
image

With every .NET release, there are usually some gotcha moments along the way.
In this article, we will resolve a Microsoft.AspNetCore.DataProtection Missing Method Exception.

Use Case

I have an AspNet Core Identity project on GitHub where I was testing generating an email confirmation token for a user.

The Test Project

The working test project targets both net6.0 and net7.0.

  <ItemGroup Condition=" '$(TargetFramework)' == 'net7.0' ">
    <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="7.0.0" />

    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
  </ItemGroup>

  <ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
    <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.8" />
    <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="6.0.8" />

    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
  </ItemGroup>

The Test in Question

The full test is Email Confirmed but the line in question uses the Identity UserManager to generate an email confirmation token.

    //Abbrevating code for simplicity
    var token = await UserManager<TUser>.GenerateEmailConfirmationTokenAsync(user).ConfigureAwait(false);

The net6.0 test worked fine, the net7.0 test threw the exception below.

Message: 

System.Security.Cryptography.CryptographicException : An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information.
---- System.MissingMethodException : Method not found: 'Boolean Microsoft.AspNetCore.Cryptography.UnsafeNativeMethods.CryptProtectData(Microsoft.AspNetCore.Cryptography.DATA_BLOB*, IntPtr, Microsoft.AspNetCore.Cryptography.DATA_BLOB*, IntPtr, IntPtr, UInt32, Microsoft.AspNetCore.Cryptography.DATA_BLOB ByRef)'.

Stack Trace: 

KeyRingBasedDataProtector.Protect(Byte[] plaintext)
DataProtectorTokenProvider`1.GenerateAsync(String purpose, UserManager`1 manager, TUser user)
BaseUserStoreTests`4.EmailConfirmed() line 137
--- End of stack trace from previous location ---
----- Inner Stack Trace -----
DpapiSecretSerializerHelper.ProtectWithDpapiCore(Byte* pbSecret, UInt32 cbSecret, Byte* pbOptionalEntropy, UInt32 cbOptionalEntropy, Boolean fLocalMachine)
DpapiSecretSerializerHelper.ProtectWithDpapi(ISecret secret, Boolean protectToLocalMachine)
DpapiXmlEncryptor.Encrypt(XElement plaintextElement)
XmlEncryptionExtensions.EncryptIfNecessary(IXmlEncryptor encryptor, XElement element)
IInternalXmlKeyManager.CreateNewKey(Guid keyId, DateTimeOffset creationDate, DateTimeOffset activationDate, DateTimeOffset expirationDate)
XmlKeyManager.CreateNewKey(DateTimeOffset activationDate, DateTimeOffset expirationDate)
KeyRingProvider.CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded)
ICacheableKeyRingProvider.GetCacheableKeyRing(DateTimeOffset now)
KeyRingProvider.GetCurrentKeyRingCore(DateTime utcNow)
KeyRingProvider.GetCurrentKeyRing()
KeyRingBasedDataProtector.Protect(Byte[] plaintext)

The Fix

Just add the package Microsoft.AspNetCore.DataProtection explicitly to the .NET 7 target.

<ItemGroup Condition=" '$(TargetFramework)' == 'net7.0' ">
...
    <PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="7.0.0" />
</ItemGroup>

Summary

This was a quick example of how to fix one of those .NET upgrade gotchas.

Open a discussion

Open Source Projects

 
image
Project Title

Project intro lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes.

NuGet Badge   NuGet Badge

image
Project Title

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

NuGet Badge   NuGet Badge

image
Project Title

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

NuGet Badge

image
Project Title

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

NuGet Badge