I denne guide vil du lære, hvordan man opbygger en DICOM anonymisering mikroservice i ASP.NET Core, der modtager DICUM filer via HTTP, anonymiserer dem ved hjælp af konfigurable profiler, og returnerer de de-identificerede resultater.
Tabellen af indhold
- arkitektonisk overblik
- Oprettelse af projektet
- Implementering af Service Layer
- Opbygning af API-kontroller
- Konfigurerbare profiler
- Sikkerhedsovervejelser
- Optimering af præstationer
- Konklusion
Oversigt over arkitektur
Mikroservice følger en lageret arkitektur med klar adskillelse af bekymringer. API-laget håndterer HTTP anmodninger og svar gennem ASP.NET Core kontroller. Tjenestelaget indeholder forretningslogik ved hjælp af Aspose.Medical Anonymizer. Konfigurationslagen administrerer profilindstillinger og applikationsmuligheder. Optionelle komponenter omfatter lagring til logging og quuing til batch behandling.
Denne arkitektur giver mulighed for horisontalt skalering, nem testing og enkel integration med hospitaloplysningssystemer og PACS-servere.
Sæt projektet op
Start ved at oprette et nyt ASP.NET Core Web API-projekt og installere det nødvendige pakke:
dotnet new webapi -n DicomAnonymizationService
cd DicomAnonymizationService
dotnet add package Aspose.Medical
Konfigurer projektet til store filopladninger i Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Configure for large DICOM files
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 500_000_000; // 500MB
});
builder.Services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 500_000_000;
});
// Register services
builder.Services.AddScoped<IDicomAnonymizationService, DicomAnonymizationService>();
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
Udførelse af Service Layer
Oprett en grænseflade og implementering for anonymiseringstjenesten:
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Anonymization;
public interface IDicomAnonymizationService
{
Task<byte[]> AnonymizeAsync(Stream inputStream, string? profileName = null);
Task<byte[]> AnonymizeAsync(byte[] inputBytes, string? profileName = null);
}
public class DicomAnonymizationService : IDicomAnonymizationService
{
private readonly ILogger<DicomAnonymizationService> _logger;
private readonly Dictionary<string, ConfidentialityProfileOptions> _profiles;
public DicomAnonymizationService(ILogger<DicomAnonymizationService> logger)
{
_logger = logger;
_profiles = new Dictionary<string, ConfidentialityProfileOptions>
{
["basic"] = ConfidentialityProfileOptions.BasicProfile,
["research"] = ConfidentialityProfileOptions.BasicProfile |
ConfidentialityProfileOptions.RetainPatientChars,
["internal"] = ConfidentialityProfileOptions.RetainUIDs |
ConfidentialityProfileOptions.RetainDeviceIdent,
["clean"] = ConfidentialityProfileOptions.CleanGraph |
ConfidentialityProfileOptions.CleanDesc
};
}
public async Task<byte[]> AnonymizeAsync(Stream inputStream, string? profileName = null)
{
using var memoryStream = new MemoryStream();
await inputStream.CopyToAsync(memoryStream);
return await AnonymizeAsync(memoryStream.ToArray(), profileName);
}
public Task<byte[]> AnonymizeAsync(byte[] inputBytes, string? profileName = null)
{
return Task.Run(() =>
{
// Create anonymizer with selected profile
Anonymizer anonymizer = CreateAnonymizer(profileName);
// Load DICOM from bytes
using var inputStream = new MemoryStream(inputBytes);
DicomFile dcm = DicomFile.Open(inputStream);
// Anonymize
DicomFile anonymizedDcm = anonymizer.Anonymize(dcm);
// Write to output stream
using var outputStream = new MemoryStream();
anonymizedDcm.Save(outputStream);
_logger.LogInformation("Anonymized DICOM file using profile: {Profile}",
profileName ?? "default");
return outputStream.ToArray();
});
}
private Anonymizer CreateAnonymizer(string? profileName)
{
if (string.IsNullOrEmpty(profileName) || !_profiles.ContainsKey(profileName.ToLower()))
{
return new Anonymizer();
}
var options = _profiles[profileName.ToLower()];
var profile = ConfidentialityProfile.CreateDefault(options);
return new Anonymizer(profile);
}
}
Opbygning af API-kontroller
Skab en kontroller, der håndterer filopladninger og returnerer anonyme DICOM-filer:
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class AnonymizeController : ControllerBase
{
private readonly IDicomAnonymizationService _anonymizationService;
private readonly ILogger<AnonymizeController> _logger;
public AnonymizeController(
IDicomAnonymizationService anonymizationService,
ILogger<AnonymizeController> logger)
{
_anonymizationService = anonymizationService;
_logger = logger;
}
/// <summary>
/// Anonymize a single DICOM file
/// </summary>
[HttpPost]
[RequestSizeLimit(500_000_000)]
public async Task<IActionResult> AnonymizeFile(
IFormFile file,
[FromQuery] string? profile = null)
{
if (file == null || file.Length == 0)
{
return BadRequest("No file uploaded");
}
try
{
_logger.LogInformation("Processing file: {FileName}, Size: {Size}",
file.FileName, file.Length);
using var stream = file.OpenReadStream();
byte[] anonymizedBytes = await _anonymizationService.AnonymizeAsync(stream, profile);
string outputFileName = $"anonymized_{file.FileName}";
return File(anonymizedBytes, "application/dicom", outputFileName);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error anonymizing file: {FileName}", file.FileName);
return StatusCode(500, $"Anonymization failed: {ex.Message}");
}
}
/// <summary>
/// Anonymize DICOM data from request body
/// </summary>
[HttpPost("stream")]
[RequestSizeLimit(500_000_000)]
public async Task<IActionResult> AnonymizeStream([FromQuery] string? profile = null)
{
try
{
byte[] anonymizedBytes = await _anonymizationService.AnonymizeAsync(
Request.Body, profile);
return File(anonymizedBytes, "application/dicom", "anonymized.dcm");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error anonymizing stream");
return StatusCode(500, $"Anonymization failed: {ex.Message}");
}
}
/// <summary>
/// List available anonymization profiles
/// </summary>
[HttpGet("profiles")]
public IActionResult GetProfiles()
{
var profiles = new[]
{
new { name = "basic", description = "Standard anonymization removing most identifiers" },
new { name = "research", description = "Retains patient characteristics for research" },
new { name = "internal", description = "Retains UIDs for internal tracking" },
new { name = "clean", description = "Removes burned-in graphics and descriptions" }
};
return Ok(profiles);
}
}
Konfigurerbare profiler
Profiler kan konfigureres via appsettings.json:
{
"AnonymizationProfiles": {
"default": "basic",
"profiles": {
"basic": ["BasicProfile"],
"research": ["BasicProfile", "RetainPatientChars"],
"internal": ["RetainUIDs", "RetainDeviceIdent"],
"clean": ["CleanGraph", "CleanDesc"],
"maximum": ["BasicProfile", "CleanGraph", "CleanDesc"]
}
}
}
Skab en konfigurationsklasse og opdater tjenesten til at læse fra indstillingerne:
public class AnonymizationProfileOptions
{
public string Default { get; set; } = "basic";
public Dictionary<string, string[]> Profiles { get; set; } = new();
}
// In Program.cs
builder.Services.Configure<AnonymizationProfileOptions>(
builder.Configuration.GetSection("AnonymizationProfiles"));
Beskyttelse af sikkerhedssikkerhed
Når du implementerer denne tjeneste, gennemfører du disse sikkerhedsforanstaltninger.
Anvend HTTPS for at sikre, at alle kommunikationer er krypteret i transit. Konfigurer TLS 1.2 eller højere og omdirigere hTTP til https.
Implementation autentisering ved hjælp af JWT tokens eller API-nøgler for at begrænse adgangen til autoriserede kunder:
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class AnonymizeController : ControllerBase
{
// Controller code...
}
** Undgå at opbevare originale filer** ikke krypteret på disken. behandle filerne i hukommelsen, når det er muligt, og hvis midlertidig lagring er nødvendigt, brug kryptede volumer.
Autoriserer revisionslogging til at spore alle anonymiseringsoperationer, herunder hvem der har anmodet om dem og når:
_logger.LogInformation(
"Anonymization completed - User: {User}, Profile: {Profile}, FileSize: {Size}",
User.Identity?.Name, profile, file.Length);
Optimering af ydeevne
Flere teknikker kan forbedre ydeevnen for high-throughput scenarier.
Anonymisering på stedet, når du ikke behøver at gemme de oprindelige data i hukommelsen:
anonymizer.AnonymizeInPlace(dcm);
Lad parallel behandling til batchoperationer:
[HttpPost("batch")]
public async Task<IActionResult> AnonymizeBatch(List<IFormFile> files)
{
var results = await Parallel.ForEachAsync(
files,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
async (file, ct) =>
{
using var stream = file.OpenReadStream();
return await _anonymizationService.AnonymizeAsync(stream);
});
// Return results...
}
Implementation forespørgsel om quuing for meget store partier ved hjælp af en besked quue som RabbitMQ eller Azure Service Bus til at håndtere lastspikes uden at overvælge tjenesten.
Konklusionen er
Du har nu en komplet planlægning for at opbygge en DICOM anonymisering mikroservice i ASP.NET Core. Tjenesten accepterer DIKOM-filer via HTTP, anvender konfigurable anonymiseringsprofiler ved hjælp af Aspose.Medical, og returnerer de-identificerede filer klar til forskning eller deling.
Nøgleforanstaltninger omfatter brug af lageret arkitektur for vedligeholdelse, implementering af konfigurable profiler for fleksibilitet, sikring af tjenesten med autentisering og kryptering og optimering af ydeevne med parallel behandling.
For den komplette kildekode og yderligere eksempler, besøg Medikamenter.Medicinsk dokumentationFor at prøve ilden, Få en gratis midlertidig licens.
More in this category
- Forberedelse af DICOM Datasets til AI og Machine Learning med Aspose.Medical
- Hvorfor DICOM-anonymisering er vigtig for HIPAA og GDPR i .NET Workflows
- Personlige fortrolighedsprofiler tilpasse DICOM-anonymisering til dine hospitalpolitikker
- Opbevaring af DICOM metadata i SQL og NoSQL-databaser med C#
- DICOM Anonymisering for Cloud PACS og Teleradiologi i C#