InvalidOperationException при создании Middleware для IP safelist
Вот класс самого Middleware:
public class IPSafelistMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<IPSafelistMiddleware> _logger;
private readonly byte[][] _safelist;
public IPSafelistMiddleware(
RequestDelegate next,
ILogger<IPSafelistMiddleware> logger,
string safelist)
{
var ips = safelist.Split(';');
_safelist = new byte[ips.Length][];
for (var i = 0; i < ips.Length; i++)
_safelist[i] = IPAddress.Parse(ips[i]).GetAddressBytes();
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
var remoteIp = context.Connection.RemoteIpAddress;
_logger.LogDebug("Запрос с IP-адреса: {RemoteIp}", remoteIp);
var bytes = remoteIp?.GetAddressBytes();
var badIp = true;
foreach (var address in _safelist)
{
if (address.SequenceEqual(bytes))
{
badIp = false;
break;
}
}
if (badIp)
{
_logger.LogWarning("Запрос с IP-адреса заблокирован: {RemoteIp}", remoteIp);
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return;
}
await _next.Invoke(context);
}
}
Вот классы Program и Startup:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddNewtonsoftJson();
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
});
services.AddHttpLogging(options =>
options.LoggingFields = Microsoft.AspNetCore.HttpLogging.HttpLoggingFields.RequestProperties);
services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseMiddleware<IPSafelistMiddleware>(Configuration["IPSafelist"]);
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
}
Не понимаю в чем проблема. В Debug всё работает, но после сборки делаю dotnet proj.dll
- выпадает следующий Exception:
crit: Microsoft.AspNetCore.Hosting.Diagnostics[6]
Application startup exception
System.InvalidOperationException: A suitable constructor for type 'Proj.Middleware.IPSafelistMiddleware' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.
at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.ReflectionMiddlewareBinder.CreateMiddleware(RequestDelegate next)
at Microsoft.AspNetCore.Builder.ApplicationBuilder.Build()
at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
Ответы (1 шт):
Автор решения: sakyrade
→ Ссылка
Глупая ошибка. Нужно было выполнять команду dotnet в той директории, где находится сама .dll, даже если вы указываете прямой путь до .dll. Только тогда dotnet увидит конфиги. Возможно у самого dotnet можно установить путь до appsettings.{env}.json через параметр, этого не проверял.