dotnet_miniapi_quartz_ipaddress_check/Dtos.cs
using System.ComponentModel.DataAnnotations;
namespace GameStore.Api.Dtos ;
public record IpAddressDto (
Guid id,
string ip,
string name,
string domain,
string mac,
string location,
string cpe,
bool ? enable,
bool ? status,
int ? roundtripTime,
int ? ttl,
string ? url);
public record CreateIpaddressDto (
[Required][StringLength(20 )] string Ip,
[Required][StringLength (20 )] string Name,
[Required][StringLength (20 )] string Domain,
[Required][StringLength (20 )] string Mac,
[Required][StringLength (20 )] string Location,
[Required][StringLength (20 )] string Cpe,
[Required] bool Enable) ;
public record UpdateIpaddressDto (
[Required][StringLength(20 )] string Ip,
[Required][StringLength (20 )] string Name,
[Required][StringLength (20 )] string Domain,
[Required][StringLength (20 )] string Mac,
[Required][StringLength (20 )] string Location,
[Required][StringLength (20 )] string Cpe,
[Required] bool Enable) ;
dotnet_miniapi_quartz_ipaddress_check/appsettings.json
{
"Logging" : {
"LogLevel" : {
"Default" : "Trace" ,
"Microsoft" : "Warning" ,
"Microsoft.AspNetCore" : "Trace"
} ,
"Debug" : {
"LogLevel" : {
"Default" : "Information" ,
"Microsoft.Hosting" : "Trace"
}
} ,
"EventSource" : {
"LogLevel" : {
"Default" : "Warning"
}
}
} ,
"Kestrel" : {
"Endpoints" : {
"Http" : {
"Url" : "http://0.0.0.0:8889"
}
}
} ,
"AllowedHosts" : "*" ,
"ConnectionStrings" : {
"DefaultConnection" : "Data Source=./Dbs/Games.db"
} ,
"Quartz" : {
"BatteryJob" : {
"Schedule" : "0/5 * * * * ?"
} ,
"NetworkJob" : {
"Schedule" : "0/30 * * * * ?"
}
}
}
dotnet_miniapi_quartz_ipaddress_check/global.json
{
"sdk" : {
"version" : "7.0.306"
}
}
dotnet_miniapi_quartz_ipaddress_check/appsettings.Development.json
{
"Logging" : {
"LogLevel" : {
"Default" : "Information" ,
"Microsoft.AspNetCore" : "Warning"
}
}
}
dotnet_miniapi_quartz_ipaddress_check/Program.cs
using GameStore.Api.Data;
using GameStore.Api.Endpoints;
using GameStore.Api.Repositoriesa;
using Job;
using NLog;
using NLog.Web;
using Quartz;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog();
builder.Services.AddScoped<IIpAddressRepository, EntityFrameworkStatusRepository>();
builder.Services.AddRepositories(builder.Configuration);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddQuartz(q =>
{
q.AddJobAndTrigger<NetworkJob>(builder.Configuration);
});
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true );
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll" , builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
var app = builder.Build();
app.UseCors("AllowAll" );
if (true )
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors();
app.MapGet("/" , (ILogger<Program> logger) =>
{
return "hello world" ;
});
app.MapIpAddressEndpoints();
app.Run();
dotnet_miniapi_quartz_ipaddress_check/Endpoints/IpAddressEndpoints.cs
using GameStore.Api.Dtos;
using GameStore.Api.Entities;
using GameStore.Api.Repositoriesa;
using SQLitePCL;
namespace GameStore.Api.Endpoints ;
public static class IpAddressEndpoints
{
const string GetIpAddressEndpointName = "GetIpAddress" ;
public static RouteGroupBuilder MapIpAddressEndpoints (this IEndpointRouteBuilder endpoints )
{
var group = endpoints.MapGroup("/ipaddress" ).WithParameterValidation();
group .MapGet("/" , async (IIpAddressRepository repository, IHttpContextAccessor httpContextAccessor) =>
{
var ipAddressArray = await repository.GetAllAsync();
var totalCount = ipAddressArray.Count();
var enableCount = ipAddressArray.Where(ip => ip.Enable == true ).Count();
var onlineCount = ipAddressArray.Where(ip => ip.Enable == true && ip.Status == true ).Count();
var host = httpContextAccessor.HttpContext?.Request.Host;
var path = httpContextAccessor.HttpContext?.Request.Path;
var url = $"http://{host} {path} " ;
var result = new
{
TotalCount = totalCount,
EnableCount = enableCount,
DisableCount = totalCount - enableCount,
OnlineCount = onlineCount,
OfflineCount = enableCount - onlineCount,
IpAddressArray = ipAddressArray.Select(ipAddress => ipAddress.AsDto(url))
};
return result;
});
group .MapGet("/{id}" , async (IIpAddressRepository repository, ILogger<Program> logger, Guid id,IHttpContextAccessor httpContextAccessor) =>
{
IpAddress? ipAddress = await repository.GetAsync(id);
if (ipAddress is null )
{
return Results.NotFound();
}
var host = httpContextAccessor.HttpContext?.Request.Host;
var path = httpContextAccessor.HttpContext?.Request.Path;
var url = $"http://{host} {path} " ;
return Results.Ok(ipAddress.AsDto(url));
}).WithName(GetIpAddressEndpointName);
group .MapPost("/" , async (IIpAddressRepository repository, CreateIpaddressDto ipAddressDto) =>
{
IpAddress ipAddress = new ()
{
Ip = ipAddressDto.Ip,
Name = ipAddressDto.Name,
Mac = ipAddressDto.Mac,
Location = ipAddressDto.Location,
Cpe = ipAddressDto.Cpe,
Domain = ipAddressDto.Domain,
Enable = ipAddressDto.Enable
};
await repository.CreateAsync(ipAddress);
return Results.CreatedAtRoute(GetIpAddressEndpointName, new { id = ipAddress.Id }, ipAddress);
});
group .MapPut("/{id}" , async (IIpAddressRepository repository, Guid id, UpdateIpaddressDto updatedIpAddressDto) =>
{
IpAddress? existingIp = await repository.GetAsync(id);
if (existingIp is null )
{
return Results.NotFound();
}
existingIp.Ip = updatedIpAddressDto.Ip;
existingIp.Name = updatedIpAddressDto.Name;
existingIp.Domain = updatedIpAddressDto.Domain;
existingIp.Mac = updatedIpAddressDto.Mac;
existingIp.Location = updatedIpAddressDto.Location;
existingIp.Cpe = updatedIpAddressDto.Cpe;
existingIp.Enable = updatedIpAddressDto.Enable;
await repository.UpdateAsync(existingIp);
return Results.NoContent();
});
group .MapDelete("/{id}" , async (IIpAddressRepository repository, Guid id) =>
{
IpAddress? ipAddress = await repository.GetAsync(id);
if (ipAddress is not null )
{
await repository.DeleteAsync(id);
}
return Results.NoContent();
});
return group ;
}
}
dotnet_miniapi_quartz_ipaddress_check/Repositories/IPingRecordsRepository.cs
using GameStore.Api.Entities;
namespace GameStore.Api.Repositoriesa ;
public interface IPingRecordsRepository
{
Task<IEnumerable<IpAddress>> GetAllAsync();
Task<IpAddress?> GetAsync(Guid id);
Task CreateAsync (IpAddress ip ) ;
Task UpdateAsync (IpAddress updatedIpAddress ) ;
Task DeleteAsync (Guid id ) ;
}
dotnet_miniapi_quartz_ipaddress_check/Repositories/EntityFrameworkIpAddressRepository.cs
using GameStore.Api.Data;
using GameStore.Api.Entities;
using Microsoft.EntityFrameworkCore;
namespace GameStore.Api.Repositoriesa ;
public class EntityFrameworkStatusRepository : IIpAddressRepository
{
private readonly StandardStoreContext dbContext;
public EntityFrameworkStatusRepository (StandardStoreContext dbContext )
{
this .dbContext = dbContext;
}
public async Task CreateAsync (IpAddress ipAddress )
{
dbContext.IpAddresses.Add(ipAddress);
await dbContext.SaveChangesAsync();
}
public async Task DeleteAsync (Guid id )
{
await dbContext.IpAddresses.Where(ipAddress => ipAddress.Id == id).ExecuteDeleteAsync();
}
public async Task<IpAddress?> GetAsync(Guid id)
{
return await dbContext.IpAddresses.FindAsync(id);
}
public async Task<IEnumerable<IpAddress>> GetAllAsync()
{
return await dbContext.IpAddresses.AsNoTracking().ToListAsync();
}
public async Task UpdateAsync (IpAddress updatedIpAddress )
{
dbContext.IpAddresses.Update(updatedIpAddress);
await dbContext.SaveChangesAsync();
}
}
dotnet_miniapi_quartz_ipaddress_check/Repositories/IIpAddressRepository.cs
using GameStore.Api.Entities;
namespace GameStore.Api.Repositoriesa ;
public interface IIpAddressRepository
{
Task<IEnumerable<IpAddress>> GetAllAsync();
Task<IpAddress?> GetAsync(Guid id);
Task CreateAsync (IpAddress ip ) ;
Task UpdateAsync (IpAddress updatedIpAddress ) ;
Task DeleteAsync (Guid id ) ;
}
dotnet_miniapi_quartz_ipaddress_check/Jobs/NetworkJob.cs
using System.Net.NetworkInformation;
using System.Text;
using GameStore.Api.Data;
using GameStore.Api.Entities;
using Microsoft.EntityFrameworkCore;
using Quartz;
namespace Job ;
[DisallowConcurrentExecution ]
public class NetworkJob : IJob
{
private readonly ILogger<NetworkJob> logger;
private readonly StandardStoreContext dbContext;
public NetworkJob (ILogger<NetworkJob> logger, StandardStoreContext dbContext )
{
this .dbContext = dbContext;
this .logger = logger;
}
public async Task Execute (IJobExecutionContext context )
{
await DetectIpaddressJob();
}
private async Task DetectIpaddressJob ()
{
return ;
await PingAll();
}
public async Task PingAll ()
{
var ipAddresss = await dbContext.IpAddresses.Where(ipAddr => ipAddr.Enable == true ).ToListAsync();
foreach (var ipAddr in ipAddresss)
{
CheckIp(ipAddr);
await Task.Delay(new Random().Next(1000 , 15000 ));
}
await dbContext.SaveChangesAsync();
}
public void CheckIp (IpAddress ipAddr )
{
Ping pingSender = new Ping();
byte [] buffer = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
int timeout = 3000 ;
PingOptions options = new PingOptions(64 , true );
PingReply reply = pingSender.Send(ipAddr.Ip, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
Console.WriteLine($"{DateTime.Now} : {ipAddr.Name} : {ipAddr.Ip} is online" );
ipAddr.Status = true ;
ipAddr.RoundtripTime = (int ?)reply.RoundtripTime;
ipAddr.Ttl = reply.Options?.Ttl;
}
else
{
Console.WriteLine($"{DateTime.Now} : {ipAddr.Name} : {ipAddr.Ip} is offline" );
ipAddr.Status = false ;
}
}
}
dotnet_miniapi_quartz_ipaddress_check/Jobs/ServiceCollectionQuartzConfiguratorExtensions.cs
using Job;
using Quartz;
namespace Job ;
public class GenericCronJobOptions
{
public string ? Schedule { get ; set ; }
}
public static class ServiceCollectionQuartzConfiguratorExtensions
{
public static void AddJobAndTrigger <T >(this IServiceCollectionQuartzConfigurator quartz, IConfiguration configuration ) where T : IJob
{
string jobName = typeof (T).Name;
var configKey = $"Quartz:{jobName} " ;
var configurationSection = configuration.GetSection(configKey);
var options = new GenericCronJobOptions();
configurationSection.Bind(options);
if (string .IsNullOrEmpty(options.Schedule))
{
throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey} " );
}
var jobKey = new JobKey(jobName);
quartz.AddJob<T>(opts => opts.WithIdentity(jobKey));
quartz.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity(jobName + "-trigger" )
.WithCronSchedule(options.Schedule));
}
}
dotnet_miniapi_quartz_ipaddress_check/Data/GameStoreContext.cs
using System.Reflection;
using GameStore.Api.Entities;
using Microsoft.EntityFrameworkCore;
namespace GameStore.Api.Data ;
public class StandardStoreContext : DbContext
{
public StandardStoreContext (DbContextOptions<StandardStoreContext> options ) : base (options )
{
}
public DbSet<IpAddress> IpAddresses => Set<IpAddress>();
protected override void OnModelCreating (ModelBuilder modelBuilder )
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
dotnet_miniapi_quartz_ipaddress_check/Data/DataExtensions.cs
using Microsoft.EntityFrameworkCore;
namespace GameStore.Api.Data ;
public static class DataExtensions
{
public static async Task InitalizeDb (this IServiceProvider provider )
{
using var scope = provider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<StandardStoreContext>();
await dbContext.Database.MigrateAsync();
}
public static IServiceCollection AddRepositories (this IServiceCollection services, IConfiguration configuration )
{
services.AddSqlite<StandardStoreContext>(configuration.GetConnectionString("DefaultConnection" ));
return services;
}
}
dotnet_miniapi_quartz_ipaddress_check/Entities/IpAddress.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GameStore.Api.Entities ;
public class IpAddress
{
[Key ]
[Column("ID" ) ]
public Guid Id { get ; set ; } = new Guid();
[Required ]
[Column("IP" , TypeName = "varchar(20)" ) ]
public required string Ip { get ; set ; }
[Column("NAME" , TypeName = "varchar(20)" ) ]
public string ? Name { get ; set ; }
[Column("DOMAIN" , TypeName = "varchar(20)" ) ]
public string ? Domain { get ; set ; }
[Column("MAC" , TypeName = "varchar(20)" ) ]
public string ? Mac { get ; set ; }
[Column("LOCATION" , TypeName = "varchar(20)" ) ]
public string ? Location { get ; set ; }
[Column("CPE" , TypeName = "varchar(20)" ) ]
public string ? Cpe { get ; set ; }
[Column("ENABLE" , TypeName = "boolean" ) ]
public bool ? Enable { get ; set ; } = true ;
[Column("STATUS" , TypeName = "boolean" ) ]
public bool ? Status { get ; set ; }
[Column("ROUNDTRIPTIME" , TypeName = "NUMBER" ) ]
public int ? RoundtripTime { get ; set ; }
[Column("TTL" , TypeName = "NUMBER" ) ]
public int ? Ttl { get ; set ; }
}
dotnet_miniapi_quartz_ipaddress_check/Entities/EntityExtensions.cs
using GameStore.Api.Dtos;
namespace GameStore.Api.Entities ;
public static class EntityExtensions
{
public static IpAddressDto AsDto (this IpAddress ip,string url )
{
return new IpAddressDto(
ip.Id,
ip.Ip,
ip.Name!,
ip.Domain!,
ip.Mac!,
ip.Location!,
ip.Cpe!,
ip.Enable,
ip.Status,
ip.RoundtripTime,
ip.Ttl,
url
);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2023-02-27 python_sqlalchemy_mysql_learn_crud_demo_practice