7

RISOLTO!

enorme grazie a Sam LeachImpossibile caricare l'assembly System.Threading.Tasks, utilizzando l'API di Google Calendar

Ecco un esempio del mio file app.config di lavoro:

<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> 

Ho anche scoperto che source


EDIT: La domanda originale è sotto la linea.

Utilizzo il .NET 4.0 Framework e dalla mia ricerca so che l'assembly System.Threading.Tasks non è più necessario (perché è incluso automaticamente). Mi sbaglio di questo?

Se ho ragione, ora sono abbastanza sicuro che l'errore viene generato perché la versione di System.Threading.Tasks utilizzata dagli sviluppatori di google-api-dotnet-client e quella utilizzata da Visual Studio 2010 sono diverso.

Ho notato che durante l'ispezione del comportamento della mia app quando rimuovo alcune linee.

E queste linee è venuto fuori:

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

Quindi, la mia nuova domanda è:

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

Grazie per avermi aiutato, sono sicuro che vi aiuterà un sacco di persone a causa della Google- calendar-api-v3 è mal documentato.

Cordiali saluti, Bruno.


mio problema è che non posso ottenere l'accesso alle API di Google come un servizio attraverso VisualStudio.

ottengo questo errore:

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, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
    FusionLog==== Informations d'état de liaison préalable === 
JRN : utilisateur = MODAL\brbo 
JRN : DisplayName = System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, 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, Culture=neutral, 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, Version=1.5.11.0, Culture=neutral, 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, ContextCallback callback, Object state) 
    à System.Threading.ThreadHelper.ThreadStart() 

Ed ecco le mie classi (stesso spazio dei nomi), che tenta di connettersi a Google Calendar API v3 utilizzando JSON Web Gettoni:

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, 
          ApplicationName = APP_NAME, 
         }); 
    } 
} 

public enum JwtHashAlgorithm 
{ 
    RS256, 
    HS384, 
    HS512 
} 

public class JsonWebToken 
{ 


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

    static JsonWebToken() 
    { 
     HashAlgorithms = new Dictionary<JwtHashAlgorithm, Func<byte[], byte[], byte[]>> 
     { 
      { JwtHashAlgorithm.RS256, (key, value) => { using (var sha = new HMACSHA256(key)) { return sha.ComputeHash(value); } } }, 
      { JwtHashAlgorithm.HS384, (key, value) => { using (var sha = new HMACSHA384(key)) { return sha.ComputeHash(value); } } }, 
      { JwtHashAlgorithm.HS512, (key, 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, string key, 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, 1, 0, 0, 0, 0, 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); 
    } 
} 

I don' t capisco perché ho un FileLoadException sull'assembly System.Threading.Tasks. Cerco di aggiungere una nuova funzionalità a un'applicazione che già utilizza Attività senza problemi. Questa app utilizza oggetti TabPage che vengono eseguiti in thread diversi.

+0

Sembra che tu abbia un problema di riferimento assemblato. –

+0

Grazie, mi ha aiutato molto. –

risposta

6

Rimuovere tutti i riferimenti a System.Threading.Tasks e quindi aggiungere quello da qualsiasi versione .NET che si sta utilizzando (. NET 4.0).

L'API di Google Calendar potrebbe essere utilizzando una versione diversa di .NET

Manually Redirecting Assembly

È possibile specificare quale versione del gruppo da utilizzare nella vostra applicazione.config

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

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

OMG !! Grazie ! C'è un esempio del mio file app.config funzionante nella domanda. –

+1

Prego. I problemi di riferimento/dll possono essere un incubo, sono contento che tu l'abbia risolto. –

Problemi correlati