C# 创建Azure函数时出现问题“未找到作业函数”错误

C# 创建Azure函数时出现问题“未找到作业函数”错误,c#,azure-functions,youtube-data-api,google-api-dotnet-client,C#,Azure Functions,Youtube Data Api,Google Api Dotnet Client,我试图实现的是,我希望能够创建一个Azure函数,使用YouTube API将视频上传到YouTube。示例:。创建azure函数后,我想在azure logic应用程序中使用该函数。以下是Azure functionuploded视频的代码: using Google.Apis.Auth.OAuth2; using Google.Apis.Services; using Google.Apis.Upload; using Google.Apis.Util.Store; using Google

我试图实现的是,我希望能够创建一个Azure函数,使用YouTube API将视频上传到YouTube。示例:。创建azure函数后,我想在azure logic应用程序中使用该函数。以下是Azure functionuploded视频的代码:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;


namespace Google.Apis.YouTube.Samples
    {
        /// <summary>
        /// YouTube Data API v3 sample: upload a video.
        /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher.
        /// See https://developers.google.com/api-client-library/dotnet/get_started
        /// </summary>
        public class UploadVideo
        {
            [STAThread]
            static void Main(string[] args)
            {
                Console.WriteLine("YouTube Data API: Upload Video");
                Console.WriteLine("==============================");

                try
                {
                    new UploadVideo().Run().Wait();
                }
                catch (AggregateException ex)
                {
                    foreach (var e in ex.InnerExceptions)
                    {
                        Console.WriteLine("Error: " + e.Message);
                    }
                }

                Console.WriteLine("Press any key to continue...");
                Console.ReadKey();
            }

            private async Task Run()
            {
                UserCredential credential;
                using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
                {
                    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        // This OAuth 2.0 access scope allows an application to upload files to the
                        // authenticated user's YouTube channel, but doesn't allow other types of access.
                        new[] { YouTubeService.Scope.YoutubeUpload },
                        "user",
                        CancellationToken.None
                    );
                }

                var youtubeService = new YouTubeService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
                });

                var video = new Video();
                video.Snippet = new VideoSnippet();
                video.Snippet.Title = "Default Video Title";
                video.Snippet.Description = "Default Video Description";
                video.Snippet.Tags = new string[] { "tag1", "tag2" };
                video.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
                video.Status = new VideoStatus();
                video.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
                var filePath = @"/Users/sean/Desktop/audio/test1.mp4"; // Replace with path to actual movie file.

                using (var fileStream = new FileStream(filePath, FileMode.Open))
                {
                    var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
                    videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
                    videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;

                    await videosInsertRequest.UploadAsync();
                }
            }

            void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress)
            {
                switch (progress.Status)
                {
                    case UploadStatus.Uploading:
                        Console.WriteLine("{0} bytes sent.", progress.BytesSent);
                        break;

                    case UploadStatus.Failed:
                        Console.WriteLine("An error prevented the upload from completing.\n{0}", progress.Exception);
                        break;
                }
            }

            void videosInsertRequest_ResponseReceived(Video video)
            {
                Console.WriteLine("Video id '{0}' was successfully uploaded.", video.Id);
            }
        }
    }
当我运行这段代码时,我没有看到像这样的预期结果:。相反,我得到了一个错误:

找不到作业函数。试着公开你的作业类和方法。如果您正在使用绑定扩展,例如Azure存储、ServiceBus、计时器等。请确保已在启动代码中调用扩展的注册方法,例如builder.AddAzureStorage、builder.AddServiceBus、builder.AddTimers等

我已经公开了我所有的方法。我不确定我遗漏了什么。

您遗漏了FunctionName属性

[FunctionName("Function1")]
        public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
             //UploadVideoToYoutube() method call here;
            return new OkResult();
        }
您缺少FunctionName属性

[FunctionName("Function1")]
        public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
             //UploadVideoToYoutube() method call here;
            return new OkResult();
        }

当您尝试创建Azure函数时,似乎使用了错误的模板,因此它创建了一个控制台应用程序。现在您缺少特定于Azure函数的Nuget包,我认为您的项目也缺少一些特定于Azure函数的文件,例如host.json

使用Visual Studio时,是否可以尝试按照以下说明操作:

或在使用VS代码时遵循以下说明:


这样,您将得到一个功能应用程序的正确结构,包括正确的依赖项。

当您尝试创建Azure功能时,似乎使用了错误的模板,因此它创建了一个控制台应用程序。现在您缺少特定于Azure函数的Nuget包,我认为您的项目也缺少一些特定于Azure函数的文件,例如host.json

使用Visual Studio时,是否可以尝试按照以下说明操作:

或在使用VS代码时遵循以下说明:


这样,您将得到一个功能应用程序的正确结构,包括正确的依赖项。

您能回答您的问题并提供您试图运行的代码吗?@MindSwipe我已经更新了它。为什么您的UploadVideo类是内部的?它不应该是公共的吗?@GauravMantri是的,我也尝试过公共的,但错误是一样的。@ZsoltBendes,你能给我指一些关于如何将它转换为Azure函数的教程吗?你能提出你的问题并提供你试图运行的代码吗?@MindSwipe我已经更新了它。为什么你的UploadVideo类是内部的?它不应该是公共的吗?@GauravMantri是的,我也尝试过这两种公共的,但错误是一样的。@ZsoltBendes,你能给我指一些关于如何将它转换为Azure函数的教程吗?我应该将这部分代码放在我的代码中的什么地方?当我将此属性添加到代码中时,出现了一个错误。谢谢。@Peter您应该清理所有内容并从.NET 5 Azure函数中的docsIn重新开始。您需要使用Function属性而不是FunctionName,否则这将不起作用。我应该将这部分代码放在我的代码中的什么位置?当我将此属性添加到代码中时,出现了一个错误。谢谢。@Peter您应该清理所有内容并从.NET 5 Azure函数中的文档重新开始。您需要使用函数属性而不是函数名,否则这将不起作用。您好@Marc谢谢您提供的信息。除了我选择了错误的模板之外,您现在还发现代码中缺少了什么吗?谢谢。我看到了一些关于文件路径的引用,这在开发无服务器函数时是一种不好的做法。您可以查看blob存储的Azure函数绑定,以便在函数中使用文件:。并删除对Console.Writeline.Hi@Marc的呼叫谢谢您提供的信息。除了我选择了错误的模板之外,您现在还发现代码中缺少了什么吗?谢谢。我看到了一些关于文件路径的引用,这在开发无服务器函数时是一种不好的做法。您可以查看blob存储的Azure函数绑定,以便在函数中使用文件:。并删除对Console.Writeline的调用。