7

GIẢI PHÁP!

cảm ơn

lớn để Sam LeachKhông thể tải lắp ráp System.Threading.Tasks, sử dụng API Lịch Google

Dưới đây là một mẫu của file app.config làm việc của tôi:

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

Tôi cũng đã phát hiện ra rằng source


EDIT: Các câu hỏi ban đầu ở dưới dòng.

Tôi đang sử dụng .NET 4.0 Framework và từ nghiên cứu của mình tôi biết rằng việc lắp ráp System.Threading.Tasks không còn cần thiết nữa (vì nó được bao gồm tự động). Tôi có sai về điều này không?

Nếu tôi đúng, bây giờ tôi khá chắc chắn rằng lỗi được nêu ra vì phiên bản System.Threading.Tasks được sử dụng bởi các nhà phát triển của google-api-dotnet-client và được sử dụng bởi Visual Studio 2010 khác nhau.

Tôi nhận thấy rằng khi kiểm tra hành vi của ứng dụng của tôi khi tôi xóa một số dòng.

Và những dòng này ra:

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

Vì vậy, câu hỏi mới của tôi là:

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

Cảm ơn bạn đã giúp đỡ tôi, tôi chắc chắn nó sẽ giúp rất nhiều người vì google- calendar-api-v3 bị ghi lại không đúng.

Trân trọng, Bruno.


Vấn đề của tôi là tôi không thể truy cập Google API như một dịch vụ thông qua VisualStudio.

tôi nhận được lỗi này:

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

Và đây là lớp học của tôi (cùng không gian tên) mà cố gắng để kết nối với API Lịch v3 Google bằng Json Web Tokens:

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 hiểu lý do tại sao tôi có một FileLoadException trên lắp ráp System.Threading.Tasks. Tôi cố gắng thêm một chức năng mới vào một ứng dụng đã sử dụng Tác vụ không có vấn đề. Ứng dụng này sử dụng các đối tượng TabPage chạy trong các chủ đề khác nhau.

+0

Dường như bạn có sự cố tham chiếu tập hợp. –

+0

Cảm ơn, nó đã giúp tôi rất nhiều. –

Trả lời

6

Xóa tất cả các tham chiếu đến System.Threading.Tasks và sau đó thêm vào từ phiên bản .NET bất kỳ bạn đang sử dụng (.NET 4.0).

Lịch Google API có thể được sử dụng một phiên bản khác của .NET

Manually Redirecting Assembly

Bạn có thể chỉ định phiên bản của hội đồng để sử dụng trong các ứng dụng của bạn.config

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

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

OMG !! Cảm ơn bạn ! Có một mẫu tệp app.config đang hoạt động của tôi trong câu hỏi. –

+1

Bạn được chào đón. Tham khảo/dll vấn đề có thể là một cơn ác mộng, tôi vui vì bạn đã có nó giải quyết. –

Các vấn đề liên quan