未找到Azure函数方法错误

时间:2017-05-09 02:26:00

标签: azure azure-functions azure-media-services azure-blob-storage

我正在尝试设置一个将blob导入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)'。在MyApp.WebTasks.EncodeJob.EncodeJobTrigger.CreateAssetFromBlob(CloudBlob sourceBlob,CloudStorageAccount destinationStorageAccount)位于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包都是最新的,并且bin目录中的Microsoft.WindowsAzure.MediaServices.Client.Extensions的版本是相同的版本。该项目建设很好,所以我不知道我错过了什么。我正在摸不着为什么它表现得像这样,我错过了一些明显的东西吗?

因此,使用此示例将项目设置为Web应用程序 https://github.com/lindydonna/FunctionsAsWebProject似乎工作正常,我可以在本地调试并使用git部署到azure函数应用程序。

对于更完整的代码段,这几乎就是我所拥有的

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

2 个答案:

答案 0 :(得分:3)

这可能是由于您正在使用的Storage SDK版本不匹配造成的。你能否降级到7.2.1然后重试?

答案 1 :(得分:1)

我认为问题出在你的块中

{
    task.Wait();
}

尝试添加此导入

using Microsoft.Azure.WebJobs;