microsoftgraph / msgraph-sdk-dotnet

Microsoft Graph Client Library for .NET!
https://graph.microsoft.com
Other
689 stars 246 forks source link

[Client bug]: Updating Microsoft.Graph to version 4.12.0 (or later) breaks the GraphServiceClient's constructor call #1380

Closed licdar87 closed 2 years ago

licdar87 commented 2 years ago

As the subject says, updating the package via NuGet makes the build fail with the following errors:

Error CS1503: Argument 1: cannot convert from 'Azure.Identity.ClientSecretCredential' to 'Microsoft.Graph.IAuthenticationProvider' Error CS1503: Argument 2: cannot convert from 'string[]' to 'Microsoft.Graph.IHttpProvider'

The line of code where the issue occurs is:

using Azure.Identity; using Microsoft.Graph;

var graphClient = new GraphServiceClient(_clientSecretCredential, _scopes);

(documentation link: https://docs.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#using-a-client-secret)

To Reproduce Steps to reproduce the behavior: All I need to do is update the package via NuGet to any subsequent version of 4.11.0

Expected behavior No errors, build successful

Desktop (please complete the following information):

Thank you

licdar87 commented 2 years ago

Just to be clear: switching back to version 4.11.0 and earlier fixes the problem

andrueastman commented 2 years ago

Hey @licdar87,

Thanks for raising this.

Any chance you could provide more information on the dotnet runtime you are using and possibly other packages in your solution? Unfortunately, I am unable to replicate this from my end when switching from 4.11.0 to 4.12.0 (or higher).

licdar87 commented 2 years ago

Any chance you could provide more information on the dotnet runtime you are using and possibly other packages in your solution?

Right, I forgot to mention this:

Dotnet runtime is 4.6.1

These are all the project's references:

"Azure.Core, Version=1.19.0.0, "Azure.Identity, Version=1.4.1.0, "EntityFramework, Version=6.0.0.0, "EntityFramework.SqlServer, Version=6.0.0.0, "itextsharp, Version=5.5.13.0, "log4net, Version=2.0.14.0, "Microsoft.Bcl.AsyncInterfaces, Version=5.0.0.0, "Microsoft.Graph, Version=4.11.0.0, "Microsoft.Graph.Core, Version=2.0.8.0, "Microsoft.Identity.Client, Version=4.36.1.0, "Microsoft.Web.Infrastructure, Version=1.0.0.0, "MoreLinq, Version=3.0.0.0, "Newtonsoft.Json, Version=6.0.0.0, "System" "System.Buffers, Version=4.0.3.0, "System.ComponentModel.DataAnnotations" "System.Configuration" "System.Core" "System.Data.Entity.Design" "System.Data.Linq" "System.Diagnostics.DiagnosticSource, Version=5.0.0.1, "System.DirectoryServices" "System.DirectoryServices.AccountManagement" "System.Drawing" "System.IdentityModel" "System.IO.Compression" "System.IO.Compression.FileSystem" "System.Net" "System.Net.Http, Version=4.1.1.3, "System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, "System.Security" "System.Security.Cryptography.Algorithms, Version=4.1.0.0, "System.Security.Cryptography.Encoding, Version=4.0.1.0, "System.Security.Cryptography.Primitives, Version=4.0.1.0, "System.Security.Cryptography.X509Certificates, Version=4.1.1.0, "System.Text.Encodings.Web, Version=5.0.0.1, "System.Text.Json, Version=5.0.0.2, "System.Threading.Tasks.Extensions, Version=4.2.0.1, "System.Transactions" "System.ValueTuple, Version=4.0.3.0, "System.Web" "System.Web.Helpers, Version=3.0.0.0, "System.Web.Mvc, Version=5.2.7.0, "System.Web.Razor, Version=3.0.0.0, "System.Web.WebPages, Version=3.0.0.0, "System.Web.WebPages.Deployment, Version=3.0.0.0, "System.Web.WebPages.Razor, Version=3.0.0.0, "System.Windows.Forms" "System.Xml.Linq" "System.Data.DataSetExtensions" "Microsoft.CSharp" "System.Data" "System.Xml"

Thanks in advance

zengin commented 2 years ago

This looks like an ambiguous type resolution to me where the type system is trying to interpret the input for another constructor than the intended one based on type hints available.

@licdar87, do you mind sharing the lines of code that initializes _clientSecretCredential and _scopes variables (with secrets hidden :))?

And if you are using Visual Studio for development, do you mind sharing which overloads of GraphServiceClient you get in Intellisense when you type new GraphServiceClient()?

Do you get all these 4 overloads? Is the experience the same when you can and can't repro the issue (i.e. 4.11.0 vs 4.12.0)?

image

image

image

image

licdar87 commented 2 years ago

@zengin Thanks for the reply. Here's my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Configuration;
using Azure.Identity;
using Microsoft.Graph;

static TestClass()
        {
            try
            {              
                _scopes = new[] { WebConfigurationManager.AppSettings["AZURE_APP_SCOPES"] };   
                _tenantId = WebConfigurationManager.AppSettings["AZURE_TENANT_ID"];        
                _clientId = WebConfigurationManager.AppSettings["AZURE_APP_ID"];
                _clientSecret = WebConfigurationManager.AppSettings["AZURE_APP_SECRET"];
                _options = new TokenCredentialOptions
                {
                    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
                };

                // https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
                _clientSecretCredential = new ClientSecretCredential(
                _tenantId, _clientId, _clientSecret, _options);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Write(e.Message);
            }
        }

Regarding the overloading hints, Visual Studio (I'm on 2022) shows the exact same results as yours, in all cases (tried with 4.11.0, 4.12.0, and the latest stable 4.31.0)

zengin commented 2 years ago

Thanks for providing more details. I was able to reproduce this, but only by moving the type hints in the object hierarchy, that is, when I declared the type of

Declaration part is not visible with the code shared above, so it might be worth checking where _scopes and _clientSecretCredential are declared.

@licdar87, could you please check if _scopes is strictly declared as string[] and _clientSecretCredential as ClientSecretCredential?

When the type hints are not specific enough, the compiler matches with the first constructor with default parameters and complains that there is a type mismatch. It is still a mystery why the behavior would be different between 4.11 and 4.12 as the constructors stay the same between the versions, I wonder if there is a non-deterministic ordering of constructors in the assemblies between the two versions, which makes the compiler pick the right one in one of the versions. Regardless, I believe type hints specific enough should solve this issue IMO.

licdar87 commented 2 years ago

@zengin I believe I've typed the variables correctly, to be sure here are some screens: image image

This is the overload used by the compiler: image

Now, this might be where the problem lies, as when I use 4.11 the selected overload is different: image

Thanks as always

licdar87 commented 2 years ago

Now that I noticed it, the compiler errors are different from those I posted in the OP. I have absolutely no idea why that changed... maybe that is due to the non-deterministic nature of the ordering as you said?

zengin commented 2 years ago

@licdar87, thanks for additional information. I couldn't reproduce this with static readonly fields similar to above in an ASP.NET project targeting 4.6.1.

I know it might be a lot to ask but is there any chance you can isolate this behavior in a sample project in GitHub where we can play around with.

licdar87 commented 2 years ago

@zengin OK... so, something really, really strange happened. As I was creating a new project in an attempt to replicate the error (on a completely different folder), I couldn't manage to replicate the error with Graph > v.4.11.0. However, I was able to replicate it by using v.3.35.

In case you're willing to fiddle around with it, here's the project's link: https://github.com/licdar87/Microsoft_Graph_Testcase

BUT that is not the strange part... the strange part is that I tried once more to install the latest Graph build on my original project, and... the problem is gone. I'm absolutely baffled right now. If you manage to find what is causing all this erratic behavior by looking at the mockup project it would be a very welcome thing. But at this point I can mark the problem as solved, I guess?

licdar87 commented 2 years ago

After the build, I tried to send a request via Graph, but then the system returned the following error: "Only HTTP/1.0 and HTTP/1.1 version requests are currently supported". After a search on previous issues, it has come to my attention that Graph only targets .Net v.4.6.2 and later.

So this might be the reason why it behaves so strangely between each version. At this point, I have no other choice but to upgrade my project in order to resolve this issue definitely, at least I hope so.

Thank you for all the help

zengin commented 2 years ago

@licdar87 it is expected to get this error when Microsoft.Graph is on v3.35 because that didn't have the constructor with TokenCredential. The isolated project doesn't reproduce the problem with 4.12 or higher either.

I will close this issue as updating the target framework seems to solve the issue. I am interested in knowing the root cause and please let us know if you figure it out, but I am glad to hear that there is an alternative solution to unblock you.

Thanks for using the Microsoft Graph SDK and reporting issues.