为什么我的Azure V2时间功能因newtonsoft参考而崩溃?

时间:2018-11-01 07:04:15

标签: azure json.net azure-functions

我有一个简单的基于计时器的azure函数,它会崩溃并显示以下消息

我为newtonsoft.Json添加了nuget包,所以我不确定为什么会出现这个问题。

[1/11/2018 07:00:26] Executed 'PimDataFeeder' (Failed, Id=291e9147-7f57-4fd3-887d-a8001afc8230)
[1/11/2018 07:00:26] System.Private.CoreLib: Exception while executing function: PimDataFeeder. System.Private.CoreLib: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'.

----编辑----

这个简单的函数看起来像这样,基本上是从远程目标下载文件并在将其写入CosmosDB实例之前在内存中进行操作,或者至少在开始工作时就这样了。在循环中放置一个断点可以告诉我,第一次循环迭代是可行的,实际上字符串的第一行已正确分割,然后跟随崩溃

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using System.Net.Http;
using System.Net.Http.Handlers;
using System.Net.Http.Headers;
using System.IO.Compression;
using System.IO;
using System.Text;
using System.Net;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;

namespace NWCloudPimDataFeeder
{
    public static class PimDataFeeder
    {
        [FunctionName("PimDataFeeder")]
        public static async System.Threading.Tasks.Task RunAsync([TimerTrigger("0 */15 * * * *")]TimerInfo myTimer, TraceWriter log)
        {
            // The endpoint to your cosmosdb instance
            var endpointUrl = "https://example.com";
            // The key to you cosmosdb
            var key = "XXX";
            // The name of the database
            var databaseName = "XXX";
            // The name of the collection of json documents
            var databaseCollection = "XXX";

            log.Info($"C# Timer trigger function executed at: {DateTime.Now}");

            HttpClientHandler handler = new HttpClientHandler()
            {
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };

            HttpClient client = new HttpClient();

            client.DefaultRequestHeaders.Add("Authorization", "Bearer XXX");

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage file = await client.GetAsync("https://example.com");
            var content = await file.Content.ReadAsByteArrayAsync();

            MemoryStream originalFileStream = new MemoryStream(content);
            using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
            {
                MemoryStream decompressedFileStream = new MemoryStream();
                decompressionStream.CopyTo(decompressedFileStream);
                byte[] fileResult = new byte[decompressedFileStream.Length];
                decompressedFileStream.Position = 0;
                decompressedFileStream.Read(fileResult, 0, fileResult.Length);
                string result = System.Text.Encoding.UTF8.GetString(fileResult);
                //log.Info(result);

                foreach (var singleItem in result.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries))
                {
                    log.Info("singleItem looks like: " +singleItem);
                    log.Info("In the loop");
                    var itemWrapper = new ItemWrapper { NWID = Guid.NewGuid(), Item = singleItem, DocumentType = "Item"};

                    // Create a cosmosdb client
                    using (var docClient = new DocumentClient(new Uri(endpointUrl), key))
                    {
                        // Save the document to cosmosdb
                        docClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseName, databaseCollection), itemWrapper)
                            .GetAwaiter().GetResult();
                    }
                }
            }
        }
    }

    public class ItemWrapper
    {
        public Guid NWID { get; set; }
        [Required]
        [JsonProperty("item")]
        public string Item { get; set; }
        [Required]
        [JsonProperty("documentType")]
        public string DocumentType { get; set; }
    }
}

2 个答案:

答案 0 :(得分:1)

现在,当我们在VS中调试函数时,Cli和Runtime的输出如下。默认情况下,该函数项目是使用Microsoft.NET.Sdk.Functions 1.0.23(> = 1.0.14)引用Newtonsoft.Json 11.0.2创建的。

Azure Functions Core Tools (2.1.748 Commit hash: 5db20665cf0c11bedaffc96d81c9baef7456acb3)
Function Runtime Version: 2.0.12134.0

我只能用一些旧的Function运行时来再现问题,该运行时仍需要v10 Newtonsoft.Json。因此,请检查Function运行时版本,并确保VS使用最新版本。

手动下载并设置CLI

  1. 使用VS删除旧的功能CLI。删除%localappdata%\AzureFunctionsTools\Releases下的子文件夹。
  2. 删除VS %userprofile%\.templateengine使用的模板引擎。
  3. 转到CLI feed,下载最新的cli,现在是feed 2.10.1 and CLI 2.1.748
  4. 转到%localappdata%\AzureFunctionsTools\Releases并创建文件夹2.10.1
  5. 解压缩zip并将其重命名为cli,将其拖到2.10.1下。
  6. templates下的cli文件夹复制到2.10.1,然后通过删除版本在其中重命名两个文件。例如itemTemplates.2.0.0-10300.nupkgitemTemplates.nupkg
  7. 2.10.1下创建manifest.json并更改用户名。

        {
          "CliEntrypointPath": "C:\\Users\\UserName\\AppData\\Local\\AzureFunctionsTools\\Releases\\2.10.1\\cli\\func.exe",
          "FunctionsExtensionVersion": "~2",
          "MinimumRuntimeVersion": "2.1",
          "ReleaseName": "2.10.1",
          "RequiredRuntime": ".NET Core",
          "SdkPackageVersion": "1.0.23",
          "TemplatesDirectory": "C:\\Users\\UserName\\AppData\\Local\\AzureFunctionsTools\\Releases\\2.10.1\\templates"
        }
    

文件夹结构应该是这样

enter image description here

重新启动VS之后,一切都会按预期进行。

答案 1 :(得分:0)

这些错误通常是由于未安装最新版本的Functions SDK / Tools引起的。对Newtonsoft 11.0.0的引用表明情况可能是这样(最新版本为11.0.2)。您可以在VS中导航到“工具”->“扩展和更新”->“更新”(窗口左下角),以检查Azure Functions工具的更新。获得最新更新后,尝试重新创建该功能以查看其是否有效。