c# – 无法使用Google Calendar API加载System.Threading.Tasks程序集

前端之家收集整理的这篇文章主要介绍了c# – 无法使用Google Calendar API加载System.Threading.Tasks程序集前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
解决了 !

非常感谢Sam Leach

以下是我工作的app.config文件的示例:

<configuration>
       ...
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.Net.Http" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-2.1.10.0" newVersion="2.1.10.0"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-2.1.10.0" newVersion="2.1.10.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

我也发现了source

编辑:原始问题在线下.

我正在使用.NET 4.0 Framework,从我的研究中我知道不再需要System.Threading.Tasks程序集(因为它是自动包含的).
我错了吗?

如果我是对的,我现在非常确定会引发错误,因为google-api-dotnet-client开发人员使用的System.Threading.Tasks版本与Visual Studio 2010使用的版本不同.

当我删除一些行时,我注意到在检查应用程序的行为时.

这些线出来了:

gcal = new CalendarService(new BaseClientService.Initializer()
{
    Authenticator = auth,ApplicationName = APP_NAME,});

所以,我的新问题是:

Is there a way to force the usage of one specific version of a reference assembly in VS2010 ?

感谢您帮助我,我相信它会对很多人有所帮助,因为google-calendar-api-v3的记录很糟糕.

亲切的问候,
布鲁诺.

我的问题是我无法通过VisualStudio访问Google API作为服务.

我收到此错误

L'exception System.IO.FileLoadException n'a pas été gérée
  Message=Impossible de charger le fichier ou l'assembly 'System.Threading.Tasks,Version=1.5.11.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a' ou une de ses dépendances. La définition trouvée du manifeste de l'assembly ne correspond pas à la référence de l'assembly. (Exception de HRESULT : 0x80131040)
  Source=MVMA
  FileName=System.Threading.Tasks,PublicKeyToken=b03f5f7f11d50a3a
  FusionLog==== Informations d'état de liaison préalable ===
JRN: utilisateur = MODAL\brbo
JRN: DisplayName = System.Threading.Tasks,PublicKeyToken=b03f5f7f11d50a3a
 (Fully-specified)
JRN: Appbase = file:///C:/Users/brbo/Documents/Visual Studio 2010/Projects/MVMA-V5.0 (With Gantt)/MVMA/bin/Debug/
JRN: PrivatePath initial = NULL
Assembly appelant: Google.Apis,Version=1.4.0.28227,PublicKeyToken=null.
===
JRN: cette liaison démarre dans le contexte de chargement de default.
JRN: utilisation du fichier de configuration de l'application: C:\Users\brbo\Documents\Visual Studio 2010\Projects\MVMA-V5.0 (With Gantt)\MVMA\bin\Debug\MVMA.vshost.exe.Config
JRN: utilisation du fichier de configuration d'hôte: 
JRN: utilisation du fichier de configuration de l'ordinateur à partir de C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
JRN: référence post-stratégie: System.Threading.Tasks,PublicKeyToken=b03f5f7f11d50a3a
JRN: tentative de téléchargement de la nouvelle URL file:///C:/Users/brbo/Documents/Visual Studio 2010/Projects/MVMA-V5.0 (With Gantt)/MVMA/bin/Debug/System.Threading.Tasks.DLL.
AVT: la comparaison du nom de l'assembly a entraîné l'incompatibilité: Version principale
ERR: impossible de terminer l'installation de l'assembly (hr = 0x80131040). Détection terminée.

  StackTrace:
   à MVMA.Classes.GoogleCalendar.BuildCalendarService()
   à System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx)
   à System.Threading.ExecutionContext.Run(ExecutionContext executionContext,Object state)
   à System.Threading.ThreadHelper.ThreadStart()

这是我的类(相同的命名空间),它尝试使用Json Web Tokens连接到Google Calendar API v3:

public class GoogleCalendar
{

    // Chaînes d'accès aux services Google
    public const string APP_NAME = "HIDDEN";
    public const string CLIENT_ID = "HIDDEN";
    public const string CLIENT_SECRET = "HIDDEN";
    public const string SERVICE_CLIENT_ID = "HIDDEN";
    public const string EMAIL_ADDRESS = "HIDDEN";
    public const string PUB_KEY = "HIDDEN";
    public const string PRIV_KEY_PATH = @"C:\MVMA\HIDDEN-privatekey.p12";
    public const string PRIV_KEY_SECRET = "notasecret";
    public const string SIMPLE_API_KEY = "HIDDEN";
    public const string SCOPE_CALENDAR = "https://www.googleapis.com/auth/calendar";
    public const string SCOPE_CALENDAR_READONLY = "https://www.googleapis.com/auth/calendar.readonly";

    private static CalendarService gcal;

    public static void ImportFromMVMA()
    {
        Thread yat = new Thread(new ThreadStart(BuildCalendarService));
        yat.Start();
    }

    // Permet de récupérer le service calendrier
    // Define the method that receives a callback when the results are available.
    private static void BuildCalendarService() {

        var certificate = new X509Certificate2(PRIV_KEY_PATH,PRIV_KEY_SECRET,X509KeyStorageFlags.Exportable);
        var privateKey = certificate.Export(X509ContentType.Cert);

        var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description,certificate)
        {
            ServiceAccountId = EMAIL_ADDRESS,Scope = SCOPE_CALENDAR
        };

        var auth = new OAuth2Authenticator<AssertionFlowClient>(provider,AssertionFlowClient.GetState);

        gcal = new CalendarService(new BaseClientService.Initializer()
                        {
                            Authenticator = auth,});
    }
}

public enum JwtHashAlgorithm
{
    RS256,HS384,HS512
}

public class JsonWebToken
{


    private static Dictionary<JwtHashAlgorithm,Func<byte[],byte[],byte[]>> HashAlgorithms;

    static JsonWebToken()
    {
        HashAlgorithms = new Dictionary<JwtHashAlgorithm,byte[]>>
        {
            { JwtHashAlgorithm.RS256,(key,value) => { using (var sha = new HMACSHA256(key)) { return sha.ComputeHash(value); } } },{ JwtHashAlgorithm.HS384,value) => { using (var sha = new HMACSHA384(key)) { return sha.ComputeHash(value); } } },{ JwtHashAlgorithm.HS512,value) => { using (var sha = new HMACSHA512(key)) { return sha.ComputeHash(value); } } }
        };
    }

    public static string Encode(object payload,string key,JwtHashAlgorithm algorithm)
    {
        return Encode(payload,Encoding.UTF8.GetBytes(key),algorithm);
    }

    public static string Encode(object payload,byte[] keyBytes,JwtHashAlgorithm algorithm)
    {
        var segments = new List<string>();
        var header = new { alg = algorithm.ToString(),typ = "JWT" };

        byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header,Formatting.None));
        byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload,Formatting.None));

        segments.Add(Base64UrlEncode(headerBytes));
        segments.Add(Base64UrlEncode(payloadBytes));

        var stringToSign = string.Join(".",segments.ToArray());

        var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);

        byte[] signature = HashAlgorithms[algorithm](keyBytes,bytesToSign);
        segments.Add(Base64UrlEncode(signature));

        return string.Join(".",segments.ToArray());
    }

    public static string Decode(string token,string key)
    {
        return Decode(token,key,true);
    }

    public static string Decode(string token,bool verify)
    {
        var parts = token.Split('.');
        var header = parts[0];
        var payload = parts[1];
        byte[] crypto = Base64UrlDecode(parts[2]);

        var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
        var headerData = JObject.Parse(headerJson);
        var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
        var payloadData = JObject.Parse(payloadJson);

        if (verify)
        {
            var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header,".",payload));
            var keyBytes = Encoding.UTF8.GetBytes(key);
            var algorithm = (string)headerData["alg"];

            var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes,bytesToSign);
            var decodedCrypto = Convert.ToBase64String(crypto);
            var decodedSignature = Convert.ToBase64String(signature);

            if (decodedCrypto != decodedSignature)
            {
                throw new ApplicationException(string.Format("Invalid signature. Expected {0} got {1}",decodedCrypto,decodedSignature));
            }
        }

        return payloadData.ToString();
    }

    private static JwtHashAlgorithm GetHashAlgorithm(string algorithm)
    {
        switch (algorithm)
        {
            case "RS256": return JwtHashAlgorithm.RS256;
            case "HS384": return JwtHashAlgorithm.HS384;
            case "HS512": return JwtHashAlgorithm.HS512;
            default: throw new InvalidOperationException("Algorithm not supported.");
        }
    }

    // from JWT spec
    private static string Base64UrlEncode(byte[] input)
    {
        var output = Convert.ToBase64String(input);
        output = output.Split('=')[0]; // Remove any trailing '='s
        output = output.Replace('+','-'); // 62nd char of encoding
        output = output.Replace('/','_'); // 63rd char of encoding
        return output;
    }

    // from JWT spec
    private static byte[] Base64UrlDecode(string input)
    {
        var output = input;
        output = output.Replace('-','+'); // 62nd char of encoding
        output = output.Replace('_','/'); // 63rd char of encoding
        switch (output.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: output += "=="; break; // Two pad chars
            case 3: output += "="; break; // One pad char
            default: throw new System.Exception("Illegal base64url string!");
        }
        var converted = Convert.FromBase64String(output); // Standard base64 decoder
        return converted;
    }
}

public class GoogleJsonWebToken
{

    public static string GetAccessToken(string email,string certificateFilePath,string serviceScope)
    {
        var utc0 = new DateTime(1970,1,DateTimeKind.Utc);
        var issueTime = DateTime.Now;

        var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
        var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; // Expiration time is up to 1 hour,but lets play on safe side

        var payload = new
        {
            iss = email,scope = serviceScope,aud = "https://accounts.google.com/o/oauth2/token",exp = exp,iat = iat
        };

        var certificate = new X509Certificate2(certificateFilePath,GoogleCalendar.PRIV_KEY_SECRET);

        var privateKey = certificate.Export(X509ContentType.Cert);

        return JsonWebToken.Encode(payload,privateKey,JwtHashAlgorithm.RS256);
    }
}

我不明白为什么我在System.Threading.Tasks程序集上有一个FileLoadException.
我尝试向已经使用任务而没有问题的应用程序添加功能.此应用程序使用在不同线程中运行的TabPage对象.

解决方法

删除对System.Threading.Tasks的所有引用,然后从您使用的任何.NET版本中添加一个(.NET 4.0).

Google Calendar API可能使用不同版本的.NET

Manually Redirecting Assembly

您可以指定要在app.config中使用的程序集版本

<dependentAssembly>
    <assemblyIdentity name="someAssembly"
      publicKeyToken="32ab4ba45e0a69a1"
      culture="en-us" />

    <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />
  </dependentAssembly>

猜你在找的C#相关文章