2016-05-19 26 views
6

Sono in esecuzione una funzione di Azure, denominata SmsWebhook. Si chiama un metodo in un assembly esterno, AzureFunctionsSample.Services.dll che ha un riferimento a Newtonsoft.Json 8.0.3Riferimento Newtonsoft.Json che si lamenta delle funzioni di Azure

I dettagli della mia Run.csx assomiglia:

#r "AzureFunctionsSample.Services.dll" 
using System.Net; 
using AzureFunctionsSample.Services 

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) 
{ 
    ... 
} 

All'interno del metodo Run() sopra, creare un'istanza e chiamare un metodo in l'istanza. Tuttavia, ogni volta che io chiamo quel metodo, ricevo il seguente errore:

2016-05-19T13:41:45 Welcome, you are now connected to log-streaming service. 
2016-05-19T13:41:46.878 Function started (Id=64fccf0c-d0ef-45ef-ac1c-7736adc94566) 
2016-05-19T13:41:46.878 C# HTTP trigger function processed a request. RequestUri=https://ase-dev-fn-demo.azurewebsites.net/api/smswebhook 
2016-05-19T13:41:46.878 Function completed (Failure, Id=64fccf0c-d0ef-45ef-ac1c-7736adc94566) 
2016-05-19T13:41:46.894 Exception while executing function: Functions.SmsWebhook. Microsoft.Azure.WebJobs.Script: One or more errors occurred. AzureFunctionsSample.Services: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040). 

ho aggiunto manualmente la stessa versione del Newtonsoft.Json.dll sotto la directory bin, ma ancora ottenuto lo stesso errore. Perché si lamenta al file Newtonsoft.Json.dll?

Se trasferisco tutte le logiche all'interno dell'assieme esterno in Run.csx, non si lamenterà, a proposito.

+0

Per curiosità, è possibile aggiungere la seguente direttiva prima del riferimento all'assembly privato: #r "Newtonsoft.Json.dll" e riprovare? –

risposta

4

@JustInChronicles, sto aggiungendo questo qui come una risposta di riferimento, ma il comportamento previsto dovrebbe essere che le dipendenze indirette di assembly privati ​​sono risolti dalla cartella bin, come previsto.

ho messo insieme il seguente test per riprodurre lo scenario:

  • Creato una libreria di classi semplice con un tipo semplice che utilizza Json.NET per serializzare un oggetto e restituisce la stringa JSON. Questo assembly fa riferimento a Json.NET 8.0.3. Il risultato include la versione assembly Json.NET che usa
  • creato una funzione che fa riferimento a questo tipo solocon un #r "DependencyWithJsonRef.dll" e restituisce il risultato ottenuto con il procedimento sopra menzionato
  • Distribuito DependencyWithJsonRef.dll e Newtonsoft.Json.dll (8.0.3) alla cartella bin della mia funzione

L'invocazione della funzione produce il risultato previsto.

Qui è la funzione, per riferimento:

#r "DependencyWithJsonRef.dll" 

using System.Net; 

public static string Run(HttpRequestMessage req, TraceWriter log) 
{ 
    var myType = new DependencyWithJsonRef.TestType(); 
    return myType.GetFromJson(); 
} 

Come si può vedere, non esplicito riferimento alle dipendenze indirette (Json.NET) necessari.

Questa è l'uscita ottengo:

{ 
    "Prop1":"Test", 
    "Prop2":1, 
    "AssemblyName": "Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" 
} 

nota rapida: Una cosa che si consiglia di verificare, in particolare se avete aggiornato che la dipendenza durante lo sviluppo la vostra funzione è che i risultati non sono stati assemblaggio resultion cache. Un modo sicuro per assicurarsi che stai iniziando con una lavagna pulita è (dopo aver distribuito la tua funzione e gli assembly) vai a Kudu e uccidi il processo non-scm w3wp per vedere se questo aiuta. Sarei curioso di sapere se questo fa il trucco in quanto ci sono alcune cose che possiamo per migliorare questo se lo fa.

+0

Grazie! Dopo aver riavviato la stessa app funzione (perché fondamentalmente è un'app Web), non devo avere un riferimento al file, '#r" Newtonsoft.Json.dll "', ma '#r" Newtonsoft.Json "' era abbastanza, se ho bisogno di usarlo nel file 'run.csx'. Se non ne ho bisogno, il riferimento non era necessario. – JustInChronicles

+0

Ma, se non metto l'assembly 'Newtonsoft.Json.dll' nella directory' bin', viene visualizzato un errore. Sono ancora curioso, perché dovrei avere l'assemblea, anche se è già referenziato internamente. – JustInChronicles

+0

Non è necessario il riferimento al file se si fa riferimento all'assembly condiviso (nome semplice), se è necessaria una versione specifica, tuttavia, si posizionerà il file nella cartella bin e si farà riferimento all'estensione. –

11

Json.Net può essere facilmente fare riferimento aggiungendo questa riga nella parte superiore del vostro file di Run.csx:

#r "Newtonsoft.Json" 

Vedi questo articolo se volete sapere quali gruppi vengono aggiunti automaticamente dalle funzioni Azure ambiente di hosting:

in caso contrario, se si desidera utilizzare una versione specifica di JSON .Net, probabilmente si dovrebbe aggiungere un riferimento a Json.Net utilizzando NuGet pacchetto:

Quindi è necessario aggiungere un file Project.json che assomigliano a questo:

{ 
    "frameworks": { 
    "net46":{ 
     "dependencies": { 
     "Newtonsoft.Json": "8.0.3" 
     } 
    } 
    } 
} 

Se la dipendenza esterna fa riferimento a Newtonsoft.Json senza utilizzare un pacchetto nuget, è possibile dare un'occhiata a questo post che spiega come caricare i file binari:

+1

Sfortunatamente, questo non è il caso. Ho aggiunto '#r" Newtonsoft.Json "' e 'usando Newtonsoft.Json;' nel mio file 'run.csx', anche se questi non sono usati direttamente nel file. Ho anche aggiunto 'project.json' con il riferimento a NuGet come suggerivi tu, ma questo non mi ha aiutato. – JustInChronicles

+1

Il mio problema è che la libreria Json.NET non può essere caricata, anche se è lì. – JustInChronicles

+0

hai l'eccezione esatta che viene lanciata? – Thomas

2

Dopo qualche approccio per tentativi ed errori. Ho trovato quale fosse il problema qui.

@FabioCavalcante mi ha dato un suggerimento con un riferimento al file-based,

#r "Newtonsoft.Json.dll" 

Non ha funzionato in realtà.Ho copiato i quattro file di bin directory Funzioni Azure:

  • AzureFunctionsSample.Services.dll
  • AzureFunctionsSample.Services.pdb
  • Newtonsoft.Json.dll
  • Newtonsoft.Json.xml

E ancora mi ha dato lo stesso errore, anche se io ha fatto il riferimento basato su file. Poi, ho trovato un altro file, AzureFunctionsSample.Services.dll.config che definisce in realtà redirect assemblaggio vincolanti come:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
</configuration> 

Dopo che ho copiato questo file di configurazione nella directory delle funzioni Azure bin, ha funzionato!


Lessons Learned

  • Utilizzare il riferimento basata su file per Newtonsoft.Json, #r "Newtonsoft.Json.dll", se il montaggio esterno ha anche un riferimento ad esso.
  • Verificare che la configurazione del reindirizzamento del binding dell'assieme esista nella directory bin delle funzioni di Azure.

Correggimi, se ho ancora torto.

Cheers,

+0

Sono contento che stia lavorando per te! Come menzionato nel mio commento precedente, tuttavia, quei passaggi * non dovrebbero * essere richiesti. Il solo fatto che la dipendenza diretta n riferimento nella funzione e che si assicuri che la versione prevista di Json.NET sia distribuita nella cartella bin dovrebbe funzionare come previsto. Non sei sicuro di voler seguire questi passaggi, ma sarebbe interessante avere la configurazione descritta sopra, assicurandoti di riavviare l'host (per assicurarti una lavagna pulita con la risoluzione dell'assembly) per vedere se funziona. Come accennato, ho riprodotto il tuo scenario e ha funzionato come descritto qui. –

+0

Un altro piccolo chiarimento; tu ** non ** devi aggiungere riferimenti espliciti alle dipendenze indirette. Quindi il '#r" Newtonsoft.Json.dll "' (o con un nome semplice) non dovrebbe essere richiesto affatto. –

+0

@FabioCavalcante Sapete come evitare 'Impossibile caricare file o assembly 'log4net, Versione = 1.2.15.0'? Qualunque posto posso aggiungere i reindirizzamenti vincolanti? –