Organizațiile de asistență medicală au nevoie din ce în ce mai mult de soluții automatizate pentru dezidentificarea datelor cu imagini medicale.În acest ghid, veți învăța cum să construiți un microservice de anonimizare DICOM în ASP.NET Core** care primește fișierele DIKOM prin HTTP, le anonimizează folosind profiluri configurabile și returnează rezultatele de-identifice.
Tabelul conținutului
- Arhitectură de ansamblu
- Întâlnirea proiectului
- Implementarea Layerului de servicii
- Construcția controlorului API
- Profiluri configurabile
- Considerații de securitate
- Optimizarea performanței
- concluziile
Arhitectură de ansamblu
Microservice urmează o arhitectură stratată cu o separare clară a preocupărilor. stratul API gestionează solicitările și răspunsurile HTTP prin intermediul controlorilor de bază ASP.NET. Layerul de serviciu conține logica afacerii folosind Aspose.Medical Anonymizer. layer de configurare administrează setările de profil și opțiunile de aplicare. componentele opționale includ stocarea pentru înregistrare și chewing pentru prelucrarea batch-ului.
Această arhitectură permite scalarea orizontală, testarea ușoară și integrarea simplă cu sistemele de informare a spitalelor și cu serverele PACS.
Afișarea proiectului
Începeți prin crearea unui nou proiect ASP.NET Core Web API și instalarea pachetului necesar:
dotnet new webapi -n DicomAnonymizationService
cd DicomAnonymizationService
dotnet add package Aspose.Medical
Configurați proiectul pentru fișierele mari încărcate în 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();
Implementarea Layerului Serviciului
Creați o interfață și o implementare pentru serviciul de anonimizare:
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);
}
}
Construirea controlorului API
Creați un controlor care gestionează upload-urile de fișiere și returnează fișierele DICOM anonime:
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);
}
}
Profile configurabile
Permite ca profilurile să fie configurate prin appsettings.json:
{
"AnonymizationProfiles": {
"default": "basic",
"profiles": {
"basic": ["BasicProfile"],
"research": ["BasicProfile", "RetainPatientChars"],
"internal": ["RetainUIDs", "RetainDeviceIdent"],
"clean": ["CleanGraph", "CleanDesc"],
"maximum": ["BasicProfile", "CleanGraph", "CleanDesc"]
}
}
}
Creați o clasă de configurare și actualizați serviciul pentru a citi din setări:
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"));
Considerații de securitate
Atunci când implementați acest serviciu, puneți în aplicare aceste măsuri de securitate.
Activați HTTPS pentru a se asigura că toate comunicațiile sunt criptate în tranzit. Configurează TLS 1.2 sau mai mare și redirecționează http la http.
Autentificarea implementării folosind tokenele JWT sau cheile API pentru a restricționa accesul la clienții autorizați:
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class AnonymizeController : ControllerBase
{
// Controller code...
}
Să evitați stocarea fișierelor originale necryptate pe disc.File de procesare sunt în memorie atunci când este posibil și, dacă este necesar depozitarea temporară, utilizați volumele cifrate.
Să permită înregistrarea auditului pentru a urmări toate operațiunile de anonimizare, inclusiv cine le-a solicitat și când:
_logger.LogInformation(
"Anonymization completed - User: {User}, Profile: {Profile}, FileSize: {Size}",
User.Identity?.Name, profile, file.Length);
Optimizarea performanţelor
Mai multe tehnici pot îmbunătăți performanța pentru scenarii de înaltă performanță.
Utilizarea anonimizării în loc atunci când nu aveți nevoie să păstrați datele originale în memorie:
anonymizer.AnonymizeInPlace(dcm);
Activă prelucrarea paralelă pentru operațiunile de batch:
[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...
}
Implementarea cererii de chewing pentru batch-uri foarte mari folosind o cheie de mesaje cum ar fi RabbitMQ sau Azure Service Bus pentru a gestiona picăturile de încărcare fără a supraîncărca serviciul.
Concluziune #conclusie
Acum aveți un plan complet pentru a construi un microservice de anonimizare DICOM în ASP.NET Core**. Serviciul acceptă fișierele DIKOM prin intermediul HTTP, aplică profiluri de anonimizare configurabile folosind Aspose.Medical și returnează fișiere de-identificate pregătite pentru cercetare sau partajare.
Principiile cheie includ utilizarea arhitecturii stratate pentru întreținere, implementarea profilurilor configurabile pentru flexibilitate, asigurarea serviciului prin autentificare și criptare, precum și optimizarea performanței prin prelucrare paralelă.
Pentru codul sursă complet și exemple suplimentare, vizitați Aspose.Documentație medicalăPentru a încerca focul, Obțineți o licență temporară gratuită.
More in this category
- De ce anonimizarea DICOM este importantă pentru HIPAA și GDPR în fluxurile de lucru .NET
- Pregătirea seturilor de date DICOM pentru AI și Machine Learning cu Aspose.Medical
- Profiluri personalizate de confidențialitate care se potrivește cu anonimizarea DICOM la politicile dvs. de spitale
- Stocati metadata DICOM in bazele de date SQL si NoSQL cu C#
- Anonimizarea DICOM pentru Cloud PACS și Teleradiologie în C#