【问题标题】:"Exception has been thrown by the target of an invocation" error when injecting Amazon S3 Service in ASP .Net Core constructor在 ASP .Net Core 构造函数中注入 Amazon S3 服务时出现“调用目标引发异常”错误
【发布时间】:2026-02-10 08:30:01
【问题描述】:

我有一个 ASP .Net Core 2.2 Web API。在其中,我有一个端点,前端(Angular 应用程序)可以将文件发送到 API,然后 API 会将此文件上传到 Amazon S3 存储桶(us-east-1 区域)。

这在我在 Visual Studio 中调试时完美运行,但是当我发布到我的服务器 (Windows Server 2016) 时,我得到以下异常:

错误:异常已被一个目标抛出 调用。 在 System.RuntimeMethodHandle.InvokeMethod(Object 目标,Object[] 参数,签名 sig,布尔构造函数, 布尔 wrapExceptions) 在 System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr、Binder binder、Object[] 参数、CultureInfo 文化)
在 Amazon.Extensions.NETCore.Setup.ClientFactory.CreateClient(类型 serviceInterfaceType、AWSCredentials 凭证、ClientConfig 配置) 在 Amazon.Extensions.NETCore.Setup.ClientFactory.CreateServiceClient(ILogger logger,类型 serviceInterfaceType,AWSOptions 选项)在 Amazon.Extensions.NETCore.Setup.ClientFactory.CreateServiceClient(IServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite、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.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,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.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument 参数)在 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(类型 服务类型)在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
在 lambda_method(Closure, IServiceProvider, Object[]) 在 Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.c__DisplayClass4_0。 b__0(ControllerContext controllerContext) 在 Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.c__DisplayClass5_0。 g__CreateController|0(ControllerContext 控制器上下文)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态& next, Scope& 范围, Object& 状态, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(状态和下一个, 范围&作用域、对象&状态、布尔& isCompleted)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
在 Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) 在 PropWorx.API.Middlewares.TenantIdentifier.Invoke(HttpContext httpContext, SharedContext sharedContext) 中 C:\Users\fabsr\source\repos\PropWorx.API\PropWorx.API\Middlewares\TenantIdentifier.cs:line 73 在 Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext 上下文)在 Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext 上下文)在 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 上下文)在 Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文)在 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(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 时似乎有问题...

【问题讨论】:

  • 我在使用 S3 存储桶时遇到了同样的问题。如果我使用 DI 注入 IAmazonS3,它没有选择配置值,因此无法解析对象。我在没有 DI 的情况下使用它,它能够工作。

标签: asp.net-core aws-sdk asp.net-core-webapi


【解决方案1】:

我保持简单。在我的本地计算机上,我将密钥保存在用户机密中,而在产品服务器上,我将它们保存在 IIS 配置文件中。并且只是从 ConfigurationManager 访问这些值。基本上它使用的是新的 AmazonS3Client(string, string, string) 语法。此外,我使用的是较旧版本的 .net 核心,问题可能已得到修复。查看this,它似乎有效。

【讨论】:

  • 谢谢您,我正在阅读它...会尽快回复您
  • 我不知道自己做错了什么...在上传文件的那一刻,它抛出了一个异常,唯一的错误信息是“操作被取消。”我已将 AWS 凭证添加到 %UserProfile%/.aws/credentials 中的凭证文件中,我已使用 Powershell 和 AWS 工具包添加它,并将其添加到我的 appconfig.json 文件中。没有一个工作。我什至尝试将其添加为环境变量。我想知道这是否甚至是凭据问题?完全相同的代码在我的笔记本电脑上完美运行。一旦我发布到服务器,它就不会。
  • 您可以尝试将您的键/值对添加到 IIS 配置文件并进行测试吗?另外,我希望您知道,如果您有不同的 prod/dev 存储桶,则开发和生产环境通常有不同的密钥。此外,AWS 存储桶上的 IAM(身份和访问管理)也可以在服务器级别完成,然后您甚至不需要键/值(这是推荐的方式)
  • 感谢您对 mukesh 的所有支持。现在,我放弃了大声笑。创建 S3Client 时,我已将访问密钥和密钥硬编码到源代码中。现在可以了。出于某种原因,在生产中,我的代码不想从 SDK 存储或共享凭据文件(在 %UserProfile%\.aws\credentials 中)读取凭据。我不知道为什么。它在开发时(即从 Visual Studio 运行时)完美运行。但是现在将密钥硬编码到源代码中是可行的......
  • 如果您不想硬编码,可以将它们存储在 IIS 配置设置中(如果您使用的是 IIS),然后使用配置管理器来选择这些东西。
【解决方案2】:

我更改了我的代码,不是通过而是直接在我的 IS3Serice 方法中实例化它来获取 IAmazonS3 实例,并且它起作用了。不知何故,DI 无法选择配置值,这就是无法解析对象的原因。

您可以从here获得一些相关信息

我浏览了实际的文档 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 开发工具包回退到为 Amazon EC2 实例配置的 IAM 凭证和区域。

所以这可能是您的初始配置在您尝试在生产环境中使用访问密钥时不起作用的原因。

也看看下面的答案

How to set credentials on AWS SDK on NET Core?

【讨论】:

  • 谢谢mukesh...我现在正在测试...会尽快通知您
  • 快速提问 mukesh...也许您知道...我正在听从您的建议,并且我认为我正在取得进展,但我感觉它没有读取设置...我在 %UserProfile%/.aws/credentials 文件以及 appsettings.json 和 appsettings.Development.json 中都有设置。我的 ConfigureServices 方法(在 Startup.cs 中)中也有这一行: services.AddDefaultAWSOptions(Configuration.GetAWSOptions());我相信它可以从 appsettings.json 文件中读取设置?我错过了什么吗?