WebJob在Azure上失败但在本地运行良好 [英] WebJob Failing on Azure but Locally Running Fine

查看:90
本文介绍了WebJob在Azure上失败但在本地运行良好的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在本地运行WebJob,但仍连接到Azure上的同一存储服务,但是当我在Azure上发布它时,它就失败了.

I'm running a WebJob locally -- still connecting to the same Storage service on Azure -- but when I publish it on Azure, it's failing.

它在本地也失败,并出现相同的错误,但是我能够对其进行修复,并在本地开发机上完美运行.知道为什么它可能在Azure上失败吗?.

It was failing locally as well with the same error but I was able to fix it and run it perfectly fine on my local dev machine. Any idea why it may fail on Azure?.

要重申一点,即使它在本地运行,它仍然连接到Azure上的相同队列和存储帐户.因此,唯一在本地运行的是代码.

To reiterate the point, even though it's running locally, it still connects to the same queue and storage account on Azure. So the only thing that's running locally is the code.

这是我在WebJob日志下的Azure Portal上遇到的错误:

Here's the error I'm getting on Azure Portal under WebJob logs:

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Microsoft.Azure.WebJobs.Host.FunctionInvocationException:异常 执行函数时:Functions.ProcessQueueMessage ---> System.MissingMethodException:未定义无参数构造函数 对于这个对象.在 System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔 publicOnly,布尔值noCheck,布尔值& canBeCached, RuntimeMethodHandleInternal& ctor,布尔值和放大器; bNeedSecurityCheck),网址为 System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔 skipCheckThis,布尔值fillCache,StackCrawlMark& stackMark) System.RuntimeType.CreateInstanceDefaultCtor(布尔publicOnly, 布尔型skipCheckThis,布尔型fillCache,StackCrawlMark& stackMark) 在System.Activator.CreateInstanceT在 Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstanceT 在 Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory 1.Create() at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker 1.d__0.MoveNext() ---从之前引发异常的位置开始的堆栈跟踪- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__31.MoveNext() ---从之前引发异常的位置开始的堆栈跟踪- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__2c.MoveNext() ---从之前引发异常的位置开始的堆栈跟踪- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task 任务) Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext() -内部异常堆栈跟踪的结尾--在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在 Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext() ---从之前引发异常的位置开始的堆栈跟踪- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__1.MoveNext()

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.MissingMethodException: No parameterless constructor defined for this object. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstanceT at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstanceT at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory1.Create() at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker1.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__31.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__2c.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext() --- End of inner exception stack trace --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__1.MoveNext()

P.S.我在VS 2015 Cloud-> Azure WebJob中创建了WebJob.此外,它的目标是.NET Framework 4.6.2

P.S. I created the WebJob in VS 2015 Cloud -> Azure WebJob. Also, it targets .NET Framework 4.6.2

另一个要点,我有一个appsettings.json文件,其中包含一些设置信息.这在bin目录中.我确实阅读了该文件,并获得了我的代码中使用的一些设置.当我通过FTP进入WebJobs目录时,在那里看到了appsettings.json文件.不知道问题是否可能与此有关.

One other important point, I have an appsettings.json file that contains some setting info. This is in the bin directory. I do read this file and get some settings that are used in my code. When I FTP'ed into the WebJobs directory, I see the appsettings.json file there. Not sure if the issue could be related to that.

更新: 这是主要的:

class Program
{
   static readonly IKernel Kernel = new StandardKernel();
   static JobHostConfiguration config;

   static void Main()
   {
      BootStrapIoc();

      var host = new JobHost(config);
      host.RunAndBlock();
   }

   private static void BootStrapIoc()
   {
      Kernel.Load(Assembly.GetExecutingAssembly());
      config = new JobHostConfiguration
      {
         JobActivator = new MyJobActivator(Kernel)
      };
   }
}

这是MyJobActivator:

Here's MyJobActivator:

public class MyJobActivator : IJobActivator
{
   private readonly IKernel _container;

   public MyJobActivator(IKernel container)
   {
      _container = container;
   }

   public T CreateInstance<T>()
   {
      return _container.Get<T>();
   }
}

这是我的Ninject绑定类

Here's my Ninject Bindings class

public class NinjectBindings : Ninject.Modules.NinjectModule
{
   IConfiguration Configuration;

   public override void Load()
   {

      Bind<IConfiguration>().ToMethod(ctx => {
            var builder = new ConfigurationBuilder();
            builder.SetBasePath(Directory.GetCurrentDirectory());
            builder.AddJsonFile("appsettings.json");
            Configuration = builder.Build();
                return Configuration;
            });

       // Bind clients
       var docDbClient = new Clients.DocumentDb.DocumentDbClient(Configuration);

       // Bind Services
       Bind<ISomeService>().To<SomeService>();

       // Bind Repositories
       Bind<ISomeRepository>().To<SomeRepository>();
    }
}

Functions类如下:

The Functions class looks like this:

public class Functions
{
   private ISomeService _someService;

   public Functions(ISomeService someService)
   {
      _someService = someService;
   }

   public async Task ProcessQueueMessage([QueueTrigger("my-queue")] MyMessageObject message, TextWriter log)
   {
      switch(message.typeId)
      {
         case MyEnum.TypeA:
            _someService.FunctionA(message);
            break;
         case MyEnum.TypeB:
            _someService.FunctionB(message);
            break;
       }
    }
}

推荐答案

Microsoft.Azure.WebJobs.Host.FunctionInvocationException:执行函数时发生异常:Functions.ProcessQueueMessage ---> System.MissingMethodException:未为此对象定义无参数构造函数.

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.MissingMethodException: No parameterless constructor defined for this object.

根据您的描述,我在这一方面进行了测试,根据您的代码,我可能会遇到相同的错误.经过一番试验后,我可以使它在我和Azure上按预期工作.以下是一些可能的原因,您可以参考它们:

According to your description, I tested this issue on my side and I could encountered the same error based on your code. After some trials, I could make it work as expected on my side and Azure. Here are some possible causes, you could refer to them:

Program.cs> Main

IKernel Kernel = new StandardKernel();
Kernel.Load(Assembly.GetExecutingAssembly());
var config = new JobHostConfiguration
{
    JobActivator = new MyJobActivator(Kernel)
};

//Initializes a new instance of the Microsoft.Azure.WebJobs.JobHost class using the configuration provided.
var host = new JobHost(config);
host.RunAndBlock();

要加载appsettings.json文件,可以按以下方式配置映射器:

For loading appsettings.json file, you could configure your mapper as follows:

Bind<IConfiguration>().ToMethod(ctx =>
{
    var builder = new ConfigurationBuilder();

    //set base path to the current working directory of your application
    builder.SetBasePath(Directory.GetCurrentDirectory());
    builder.AddJsonFile("appsettings.json");
    IConfigurationRoot Configuration = builder.Build();
    return Configuration;
});

注意:确保appsettings.json位于项目的根目录下,并将复制到输出目录"设置为Copy always.

Note: Make sure appsettings.json is under the root dir of your project and set "Copy to Output Directory" as Copy always.

我的测试结果:

这篇关于WebJob在Azure上失败但在本地运行良好的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆