WebJob在Azure上失败但在本地运行良好

时间:2017-02-02 06:21:41

标签: azure azure-webjobs azure-webjobssdk

我在本地运行WebJob - 仍然连接到Azure上的相同存储服务 - 但是当我在Azure上发布它时,它失败了。

它在本地也失败了同样的错误,但我能够修复它并在我的本地开发机器上完全运行它。知道为什么它可能在Azure上失败了吗?。

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

以下是我在WebJob日志下访问Azure Portal时出现的错误:

  

Microsoft.Azure.WebJobs.Host.FunctionInvocationException:   Microsoft.Azure.WebJobs.Host.FunctionInvocationException:Exception   执行函数时:Functions.ProcessQueueMessage --->   System.MissingMethodException:未定义无参数构造函数   对于这个对象。在   System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值   publicOnly,Boolean noCheck,Boolean& canBeCached,   RuntimeMethodHandleInternal&安培; ctor,布尔& 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)   在System.Activator.CreateInstanceT at   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()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__31.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__2c.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)在System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务   任务)   Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext()   ---内部异常堆栈跟踪结束---在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__13.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.d__1.MoveNext()

P.S。我在VS 2015 Cloud中创建了WebJob - > Azure WebJob。此外,它还面向.NET Framework 4.6.2 enter image description here

另一个重点,我有一个包含一些设置信息的appsettings.json文件。这是在bin目录中。我确实阅读了这个文件,并获得了我的代码中使用的一些设置。当我FTP到WebJobs目录时,我在那里看到了appsettings.json文件。不确定问题是否与此有关。

更新: 这里是主要的:

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:

public class MyJobActivator : IJobActivator
{
   private readonly IKernel _container;

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

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

这是我的Ninject Bindings课程

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类看起来像这样:

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;
       }
    }
}

2 个答案:

答案 0 :(得分:0)

您获得的例外是

  

没有为此对象定义无参数构造函数

实现队列处理方法的对象必须具有无参数构造函数,以便JobHost能够创建它(抱歉,这是我能给出的最好的指针,而不会看到代码示例)

答案 1 :(得分:0)

  

Microsoft.Azure.WebJobs.Host.FunctionInvocationException:执行函数时出现异常:Functions.ProcessQueueMessage ---&gt; System.MissingMethodException:没有为此对象定义的无参数构造函数。

根据您的描述,我在我这边测试了这个问题,我可能会遇到与您的代码相同的错误。经过一些试验,我可以让它在我身边和Azure一起工作。以下是一些可能的原因,您可以参考它们:

Program.cs&gt;主

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文件,您可以按如下方式配置映射器:

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

我的测试结果: