Ошибка метода функций Azure не найдена

Я пытаюсь настроить функцию Azure, которая импортирует большой двоичный объект в службу мультимедиа Azure. Но когда я пытаюсь запустить функцию в режиме отладки, некоторые точки останова никогда не срабатывают, и тогда я получаю эту ошибку.

Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Исключение при выполнении функции: Functions.EncodeJob ---> System.MissingMethodException : Метод не найден: 'System.Threading.Tasks.Task Microsoft.WindowsAzure.MediaServices.Client.CopyBlobHelpers.CopyBlobAsync( Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob, Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions, System.Threading.CancellationToken)». at MyApp.WebTasks.EncodeJob.EncodeJobTrigger.CreateAssetFromBlob(CloudBlob sourceBlob,CloudStorageAccount destinationStorageAccount) at C:\Source\Quickflix\MyApp.webtasks\MyApp.WebTasks\EncodeJob\EncodeJobTrigger.cs: 164 at.....(усечено из-за длина)

Кажется, причина в этом блоке здесь

            // Call the CopyBlobHelpers.CopyBlobAsync extension method to copy blobs.
        using (var task =
            CopyBlobHelpers.CopyBlobAsync((CloudBlockBlob)sourceBlob,
                (CloudBlockBlob)destinationBlob,
                new BlobRequestOptions(),
                CancellationToken.None))
        {
            task.Wait();
        }

Когда я комментирую этот блок, я могу попасть в точку останова, которую я застрял в методе, которому он принадлежит. Когда он не закомментирован, точка останова никогда не срабатывает, и я получаю эту ошибку. Исключение, кажется, происходит, как только я вхожу в CreateAssetFromBlob, а не в строку, которая фактически вызывает CopyBlobAsync. Я проверил, что все мои пакеты nuget обновлены и что версия Microsoft.WindowsAzure.MediaServices.Client.Extensions в каталоге bin совпадает с версией. Проект строится нормально, поэтому я не уверен, что мне не хватает. Я ломаю голову над тем, почему он так себя ведет, я упускаю что-то очевидное?

Таким образом, проект настроен как веб-приложение с использованием этого примера https://github.com/lindydonna/FunctionsAsWebProject. который, кажется, работает нормально, я могу отлаживать локально и развертывать приложение функций Azure с помощью git.

Для более полного фрагмента кода это почти то, что у меня есть

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using Newtonsoft.Json;
using MyApp.Integration.Services;
using MyApp.Logging;

namespace MyApp.WebTasks.EncodeJob
{
    public class EncodeJobTrigger
    {
        private static CloudMediaContext _context;
        private static MediaServicesCredentials _cachedCredentials;

        public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
        {
            var blob = Encode("vidcontainer", "vid.mp4");

            return req.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(blob.Exists()));
        }

        public static CloudBlob Encode(string containerName, string blobPath)
        {
            var logger = new DebugLogger();
            var amsConnectionString = "connectionstring";
            var blobStorageService = new AzureBlobStorageService(amsConnectionString, logger);
            var destStorageAccount = CloudStorageAccount.Parse("connectionstring");

            string mediaServicesAccountName = "myaccountname";
            string mediaServicesAccountKey = "mykey";

            _cachedCredentials = new MediaServicesCredentials(
                mediaServicesAccountName,
                mediaServicesAccountKey);

            _context = new CloudMediaContext(_cachedCredentials);
            var blob = blobStorageService.FindBlobInContainer(containerName, blobPath);

            ImportBlobIntoAms(blob, destStorageAccount);

            return blob;

        }

        public static IAsset ImportBlobIntoAms(CloudBlob blob, CloudStorageAccount destStorageAccount)
        {

            var asset = CreateAssetFromBlob(blob, destStorageAccount);
            return asset;
        }

        public static IAsset CreateAssetFromBlob(CloudBlob sourceBlob, CloudStorageAccount destinationStorageAccount)
        {

            CloudBlobClient destBlobStorage = destinationStorageAccount.CreateCloudBlobClient();

            // Create a new asset. 
            IAsset asset = _context.Assets.Create("NewAsset_" + Guid.NewGuid(), AssetCreationOptions.None);

            IAccessPolicy writePolicy = _context.AccessPolicies.Create("writePolicy",
                TimeSpan.FromHours(24), AccessPermissions.Write);

            ILocator destinationLocator =
                _context.Locators.CreateLocator(LocatorType.Sas, asset, writePolicy);

            // Get the asset container URI and Blob copy from mediaContainer to assetContainer. 
            CloudBlobContainer destAssetContainer =
                destBlobStorage.GetContainerReference((new Uri(destinationLocator.Path)).Segments[1]);

            if (destAssetContainer.CreateIfNotExists())
            {
                destAssetContainer.SetPermissions(new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Blob
                });
            }

            var assetFile = asset.AssetFiles.Create(sourceBlob.Name);

            ICloudBlob destinationBlob = destAssetContainer.GetBlockBlobReference(assetFile.Name);

            // Call the CopyBlobHelpers.CopyBlobAsync extension method to copy blobs.
            using (var task =
                CopyBlobHelpers.CopyBlobAsync((CloudBlockBlob)sourceBlob,
                    (CloudBlockBlob)destinationBlob,
                    new BlobRequestOptions(),
                    CancellationToken.None))
            {
                task.Wait();
            }

            assetFile.ContentFileSize = (sourceBlob as ICloudBlob).Properties.Length;
            assetFile.Update();
            Console.WriteLine("File {0} is of {1} size", assetFile.Name, assetFile.ContentFileSize);
            //            }

            asset.Update();

            destinationLocator.Delete();
            writePolicy.Delete();

            // Set the primary asset file.
            // If, for example, we copied a set of Smooth Streaming files, 
            // set the .ism file to be the primary file. 
            // If we, for example, copied an .mp4, then the mp4 would be the primary file. 
            var ismAssetFiles = asset.AssetFiles.ToList().FirstOrDefault(f => f.Name.Equals(sourceBlob.Name, StringComparison.OrdinalIgnoreCase));

            // The following code assigns the first .ism file as the primary file in the asset.
            // An asset should have one .ism file.  
            ismAssetFiles.IsPrimary = true;
            ismAssetFiles.Update();

            return asset;
        }
    }
}

Обновление 1 Итак, я обновил этот блок/функцию, чтобы он был асинхронным и не ждал выполнения задачи, но все равно получаю ту же ошибку. Обновленный код выглядит так.

            await CopyBlobHelpers.CopyBlobAsync((CloudBlockBlob) sourceBlob,
            (CloudBlockBlob) destinationBlob,
            new BlobRequestOptions(),
            CancellationToken.None);

Также у нее есть пакеты nugets.config.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
  <package id="Microsoft.Azure.KeyVault.Core" version="2.0.4" targetFramework="net45" />
  <package id="Microsoft.Azure.WebJobs" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.Azure.WebJobs.Core" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.0" targetFramework="net45" />
  <package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net45" />
  <package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net45" />
  <package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net45" />
  <package id="Microsoft.Net.Compilers" version="1.0.0" targetFramework="net45" developmentDependency="true" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
  <package id="System.ComponentModel.EventBasedAsync" version="4.0.11" targetFramework="net45" />
  <package id="System.Dynamic.Runtime" version="4.0.0" targetFramework="net45" />
  <package id="System.IdentityModel.Tokens.Jwt" version="4.0.2.206221351" targetFramework="net45" />
  <package id="System.Linq.Queryable" version="4.0.0" targetFramework="net45" />
  <package id="System.Net.Requests" version="4.0.11" targetFramework="net45" />
  <package id="System.Spatial" version="5.8.2" targetFramework="net45" />
  <package id="TransientFaultHandling.Core" version="5.1.1209.1" targetFramework="net45" />
  <package id="windowsazure.mediaservices" version="3.8.0.5" targetFramework="net45" />
  <package id="windowsazure.mediaservices.extensions" version="3.8.0.3" targetFramework="net45" />
  <package id="WindowsAzure.Storage" version="8.1.1" targetFramework="net45" />
</packages>

person Ryan Burnham    schedule 09.05.2017    source источник
comment
Это может быть несоответствие версий пакета nuget, например. для Microsoft.WindowsAzure.Storage. Покажите вам файл пакетов.   -  person Mikhail Shilkov    schedule 09.05.2017
comment
Я добавил packages.config основного веб-проекта. Я не включил пакеты моей общей библиотеки интеграции Azure, потому что, когда я скопировал эти классы в веб-проект и удалил ссылку на проект интеграции, я все равно получил ошибку. Я также пробовал несколько разных комбинаций версий .net. Он указан в .net 4.6, но я попробовал .net 4,5, потому что это максимальная версия, которую поддерживает библиотека windowsazure.mediaservices.extensions.   -  person Ryan Burnham    schedule 09.05.2017


Ответы (2)


Вероятно, это вызвано несоответствием используемой вами версии Storage SDK. Не могли бы вы перейти на 7.2.1 и повторить попытку?

person Fabio Cavalcante    schedule 09.05.2017
comment
Это устранило проблему, но я до сих пор не уверен, почему функция работает нормально. Почему это проблема времени выполнения? После вашего сообщения я также нашел это, которое, кажется, намекает на изменение подписи метода github.com/Azure/azure-sdk-for-media-services-extensions/issues/ - person Ryan Burnham; 10.05.2017
comment
отметив это как ответ, хотя это не было моим окончательным решением. Это действительно исправило ошибку, которую я получал, но я столкнулся с другой ошибкой метода, не найденной, на этот раз с Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.StartCopyFromBlobAsync. Мое фактическое решение пришло из использования кода из примера ссылки Дэмиана в его ответе. Я все еще хотел бы знать, почему это не было обнаружено во время компиляции? - person Ryan Burnham; 10.05.2017

думаю проблема в вашем блоке

{
    task.Wait();
}

Попробуйте добавить этот импорт

using Microsoft.Azure.WebJobs;
person Damián Rafael Lattenero    schedule 09.05.2017
comment
есть идеи, почему это может вызвать исключение метода, не найденного? я планировал сделать этот асинхронный, но мне нужно выяснить, как отслеживать какое-то состояние, прежде чем делать это. - person Ryan Burnham; 09.05.2017
comment
Я знаю, что в большинстве импортов нет необходимости, они автоматически добавляются функциями Azure. Они импортировались автоматически? - person Damián Rafael Lattenero; 09.05.2017
comment
У нас также есть несколько примеров кодирования, интегрированного со службами мультимедиа, в этом примере репозитория — github.com/Azure-Samples/ Вы можете сослаться на некоторые реализации функций в этом исходном коде. - person johndeu; 09.05.2017
comment
Я только что заметил, что вы, возможно, пропустили импорт, вы пытались добавить это? - person Damián Rafael Lattenero; 09.05.2017
comment
Да, они, вероятно, были добавлены, когда я скопировал некоторые классы обслуживания Azure, которые я использую в качестве уровня интеграции для связи с Azure, в реальную функцию. Они были в другой библиотеке классов, и я хотел исключить проблемы с зависимостями. - person Ryan Burnham; 09.05.2017
comment
Да, но в вашем коде есть Microsoft.Azure.WebJobs.Host; импорт и нет Microsoft.Azure.WebJobs; import, и, проверив здесь, я увидел, что он использует оба импорта. docs.microsoft.com/en-us/azure/ лазурные функции/ - person Damián Rafael Lattenero; 09.05.2017
comment
потому что ошибка связана с Microsoft.Azure.WebJobs.Host, и, возможно, они должны быть в одном классе - person Damián Rafael Lattenero; 09.05.2017
comment
Может быть, там что-то есть, другое дело, что я использую только классы .cs, а не .csx. Я читал прекомпилированные документы, что это не имеет значения? но я вижу дополнительный синтаксис в .csx. например, есть #r Microsoft.WindowsAzure.Storage, а также использование Microsoft.WindowsAzure.Storage;. Является ли #r dll для загрузки? Я предполагаю, что это обрабатывается ссылкой на проект в веб-приложении? - person Ryan Burnham; 09.05.2017
comment
Ммм... Ты загрузил #r? Потому что я не уверен, что ссылка на проект обрабатывается сама по себе - person Damián Rafael Lattenero; 09.05.2017
comment
#r не является допустимым синтаксисом С#, поэтому он не компилируется. альтернативы ему я не видел. Я мог бы попробовать преобразовать его в .csx - person Ryan Burnham; 09.05.2017
comment
Слово предостережения. Будьте осторожны при использовании CopyBlobAsync с большими файлами при развертывании в Функциях Azure. Если копирование занимает более 5 минут, время ожидания истекает. - person johndeu; 09.05.2017
comment
@DamianLattenero Мне удалось получить альтернативную работу, используя образец кодирования функций azure, который вы связали. Я не уверен, какой метод будет лучше. Мне нужно проверить, что делает copyBlobHelper.CreateAssetFromBlob иначе, чем структура расширений ams. - person Ryan Burnham; 10.05.2017