我有一个ASP.Net Core 2.2 Web API。在其中,我有一个端点,前端(Angular应用程序)可以将文件发送到API,而API则将该文件上传到Amazon S3存储桶(us-east-1区域)。
当我在Visual Studio中调试时,这非常有效,但当我发布到服务器(Windows server 2016)时,我会得到以下异常:
错误:调用在System.RuntimeMethodHandle.InvokeMethod(对象target,Object[]参数,Signature sig,布尔构造函数,布尔wrappeExceptions)System.Reflection.RuntimeConstructorInfo.IInvoke(BindingFlagsinvokeAttr,Binder Binder,Object[]参数,CultureInfo区域性)
在Amazon.Extensions.NETCore.Setup.ClientFactory.CreateClient(类型serviceInterfaceType、AWSCredentials凭据、ClientConfig配置)在Amazon.Extension.NETCore.Setup.ClientFactory.CreateServiceClient(ILoggerlogger、Type serviceInterfaceType、AWSOptions选项)Amazon.Extension.NETCore.Setup.ClientFactory.CreateServiceClient(IServiceProvider提供商)Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSitefactoryCallSite,ServiceProviderEngineScope范围)Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSitecallSite,TAargument参数)Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSiteconstructorCallSite,ServiceProviderEngineScope范围)Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSitecallSite,TAargument参数)Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine。<>c_DisplayClass1_0。b__0(ServiceProviderEngineScope范围)Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(类型serviceType,ServiceProviderEngineScope ServiceProviderEngineScope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(类型serviceType)Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvidersp,Type Type,Type requiredBy,Boolean isDefaultParameterRequired)
位于Microsoft.AspNetCore.Mvc.Controller.ControllerActivatorProvider。<>c__DisplayClass4_0。b__0(ControllerContext ControllerContext),位于Microsoft.AspNetCore.Mvc.Controller.ControllerFactoryProvider。<>c__DisplayClass5_0。g_CreateController |0(ControllerContextcontrollerContext)Microsoft.AspNetCore.Mvc.Interal.ControllerActionInvoker.Next(State&下一步,Scope&作用域,对象&state,布尔&isCompleted)Microsoft.AspNetCore.Mvc.Interal.ControllerActionInvoker.InvokeInnerFilterAsync()在Microsoft.AspNetCore.Mvc.Interal.ResourceInvoker.InvokeNextResourceFilter()在Microsoft.AspNetCore.Mvc.Interal.ResourceInvoker.Rethrow(ResourceExecutedContext上下文)Microsoft.AspNetCore.Mvc.Interal.ResourceInvoker.Next(State&Next,范围&作用域,对象&state,布尔&isCompleted)Microsoft.AspNetCore.Mvc.Interal.ResourceInvoker.IInvokeFilterPipelineAsync()在Microsoft.AspNetCore.Mvc.Interal.ResourceInvoker.InvokeAsync()
在Microsoft.AspNetCore.Routing.EndpointMiddleware.IInvoke(HttpContexthttpContext)Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.IInvoke(HttpContexthttpContext)PropWorx.API.中间件.租户标识符.调用(HttpContexthttpContext,SharedContext SharedContext)C: \Users\fabsr\source\repos\PropWorx。API \PropWorox。API \Middlewares\TenantIdentifier.cs:line73Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.IInvoke(HttpContext上下文)Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.IInvoke(HttpContext上下文)Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.IInvoke(HttpContext上下文)Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.IInvoke(HttpContexthttpContext)Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.IInvoke(HttpContexthttpContext,ISwakerProvider swaggerProvider)Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.IInvoke(HttpContext上下文)Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.IInvoke(HttpContext上下文)
我已经在%UserProfile%.aws文件夹中创建了"凭据"文件。
我在项目中添加了以下两个NuGet包:
- AWSSDK.Extensions.NETCore.Setup
- AWSSDK.S3
我的Startup.cs:中有这个
public void ConfigureServices(IServiceCollection services)
{
services.AddAWSService<IAmazonS3>();
services.AddSingleton<IS3Service, S3Service>();
}
S3Service.cs看起来像这样:
public class S3Service : IS3Service
{
private readonly IAmazonS3 _client;
public S3Service(IAmazonS3 client)
{
_client = client;
}
// Some methods to upload and delete objects... not important
}
我将此服务注入我的一个控制器:
public class FilesController : ControllerBase
{
private readonly IS3Service _s3Service;
public FilesController(IS3Service s3Service)
{
_s3Service = s3Service;
}
// Some actions to receive the file... not important
}
一旦我调用该控制器中的任何操作,就会发生错误。事实上,当S3Service被注入控制器的构造函数时,错误似乎正在发生。如果我删除构造函数注入,即:
public class FilesController : ControllerBase
{
private readonly IS3Service _s3Service;
public FilesController()
{
}
// Some actions to receive the file... not important
}
错误消失了(但当然不能正常工作)
有什么想法吗?正如我所说,在VS2017中调试时,这在我的笔记本电脑上非常适用。但当发布到服务器时,它不起作用。API中的所有其他控制器工作正常。在构造函数中注入S3Service时,这似乎是一个问题。。。
我保持简单。在我的本地机器中,我将密钥保存在用户机密中,而在prod服务器上,我将这些密钥保存在IIS配置文件中。并且只是从ConfigurationManager访问这些值。基本上,它使用了新的AmazonS3Client(字符串,字符串,字符串)语法。此外,我使用的是一个旧得多的.net核心版本,这个问题可能已经解决了。看看这个似乎有效。
我更改了代码,使IAmazonS3永不满足,不是通过而是直接在我的IS3Serice方法中实例化它,它成功了。不知怎的,DI无法选择配置值,这就是为什么无法解析对象的原因。
你可以从这里获得一些有关的信息
我查看了实际的文档https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-netcore.html
并发现以下内容:
如果查看项目属性中的"调试"选项卡,可以看到该文件已设置为"开发"。这对于本地测试非常有效,因为您可以将配置放在appsettings中。Development.json文件,该文件在本地测试期间是只读的。当您部署EnvironmentName设置为Production的Amazon EC2实例时,此文件将被忽略,用于.NET的AWS SDK将返回到为Amazon EC2示例配置的IAM凭据和区域
因此,这可能是您在生产中尝试使用访问密钥时初始配置不起作用的原因。
还可以看看下面的答案
如何在NET Core上的AWS SDK上设置凭据?