NET 8 Host Controllers that run the API Services
/// <summary> Generic for any API solution </summary>
[ExcludeFromCodeCoverage]
public abstract class ControllerSubBase(ILogger logger) : ControllerBase()
{
private readonly ILogger _logger = logger;
protected IActionResult HandleModelStateBadRequest()
{
var modelStateErrors = ModelState.Select(x => x.Value?.Errors).Where(y => y != null && y.Count > 0);
_logger.LogWarning("Invalid ModelState {modelStateErrors}",JsonSerializer.Serialize(modelStateErrors));
return BadRequest(modelStateErrors);
}
protected void LogError(Exception ex, string location)
{
_logger.LogError(ex, "[E] " + location + " Failed: {error}", ex.Message);
}}
==================================================
/// <summary> Generic for any API solution </summary>
[ExcludeFromCodeCoverage]
public class Api(IWebHostEnvironment environment, IConfiguration configuration)
{
public IWebHostEnvironment Environment { get; } = environment;
public IConfiguration Configuration { get; } = configuration;
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore(options => { options.EnableEndpointRouting = false; });
services
.AddControllers(mvcOptions => mvcOptions.EnableEndpointRouting = false)
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.Never;
});
services.AddSingleton(Environment);
services.AddDependencies();
services.Configure<IISOptions>(options =>
{
options.AutomaticAuthentication = true;
options.ForwardClientCertificate = true;
});
services.AddAuthentication(config =>
{
config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
config.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
config.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]!))
};
});
}
public static void Configure(IApplicationBuilder app)
{
app.UseCors("AllowAll");
#if DEBUG
app.UseDeveloperExceptionPage();
#endif
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
===============================================
/// <summary> Generic for any API solution </summary>
[ExcludeFromCodeCoverage]
public static class Program
{
public static void Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Api>();
})
.UseSerilog((context, services, configuration) => {
configuration.ReadFrom.Configuration(context.Configuration);
configuration.Enrich.WithMachineName();
configuration.Enrich.WithProcessId();
configuration.Enrich.FromLogContext();
})
.Build();
host.Run();
}
}
===============================================
[ExcludeFromCodeCoverage]
public static class ApiDependencies
{
/// <summary> Registering all API dependencies.
/// (Used mostly for Postman calling controller methods.)
/// Order created in matters here. Do dependencies of later objects first. </summary>
public static IServiceCollection AddDependencies(this IServiceCollection services)
{
services.AddSingleton(typeof(Program).Assembly.GetName());
// each dependency like:
services.AddScoped<IMemoryCache, MemoryCache>();
return services;
}
}
Comments
Post a Comment