WebJob 在 Azure 上失败但在本地 运行 正常
WebJob Failing on Azure but Locally Running Fine
我 运行 在本地创建一个 WebJob -- 仍然连接到 Azure 上的同一个存储服务 -- 但是当我在 Azure 上发布它时,它失败了。
它也在本地失败并出现相同的错误,但我能够修复它并且 运行 它在我的本地开发机器上完全没问题。知道为什么它在 Azure 上可能会失败吗?
重申一下,即使它在本地 运行ning,它仍然连接到 Azure 上的相同队列和存储帐户。因此,唯一 运行 本地化的就是代码。
这是我在 WebJob 日志下的 Azure 门户上遇到的错误:
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.FunctionInvoker
1.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
还有一点很重要,我有一个 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 绑定 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>();
}
}
函数 class 看起来像这样:
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;
}
}
}
您得到的例外是
No parameterless constructor defined for this object
实现队列处理方法的对象必须具有无参数构造函数,以便 JobHost 能够创建它(抱歉,这是我在没有看到代码示例的情况下所能给出的最佳指示)
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.MissingMethodException: No parameterless constructor defined for this object.
根据你的描述,我自己测试了这个问题,根据你的代码,我可能会遇到同样的错误。经过一些试验后,我可以让它在我这边和 Azure 上按预期工作。以下是一些可能的原因,您可以参考:
Program.cs > 主要
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 to Output Directory"设置为Copy always
。
我的测试结果:
我 运行 在本地创建一个 WebJob -- 仍然连接到 Azure 上的同一个存储服务 -- 但是当我在 Azure 上发布它时,它失败了。
它也在本地失败并出现相同的错误,但我能够修复它并且 运行 它在我的本地开发机器上完全没问题。知道为什么它在 Azure 上可能会失败吗?
重申一下,即使它在本地 运行ning,它仍然连接到 Azure 上的相同队列和存储帐户。因此,唯一 运行 本地化的就是代码。
这是我在 WebJob 日志下的 Azure 门户上遇到的错误:
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.ActivatorInstanceFactory
1.Create() at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker
1.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
还有一点很重要,我有一个 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 绑定 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>();
}
}
函数 class 看起来像这样:
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;
}
}
}
您得到的例外是
No parameterless constructor defined for this object
实现队列处理方法的对象必须具有无参数构造函数,以便 JobHost 能够创建它(抱歉,这是我在没有看到代码示例的情况下所能给出的最佳指示)
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.MissingMethodException: No parameterless constructor defined for this object.
根据你的描述,我自己测试了这个问题,根据你的代码,我可能会遇到同样的错误。经过一些试验后,我可以让它在我这边和 Azure 上按预期工作。以下是一些可能的原因,您可以参考:
Program.cs > 主要
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 to Output Directory"设置为Copy always
。
我的测试结果: