Les organisations de santé ont de plus en plus besoin de solutions automatisées pour détecter les données d’imagerie médicale. Dans ce guide, vous apprendrez comment construire un microservice d’anonymisation DICOM dans ASP.NET Core** qui reçoit les fichiers DIKOM via HTTP, les anonymise en utilisant des profils configurables et retourne les résultats déidentifiés.
Table des contenus
- L’architecture de l’ensemble
- Mettre en place le projet
- La mise en œuvre de la couche de service
- Construire le contrôleur API
- Configurer des profils
- Considérations de sécurité
- Ottimizzazione delle Prestazioni
- Conclusion
Vue de l’architecture
Le microservice suit une architecture couverte avec une séparation claire des inquiétudes. La couche API gère les demandes et les réponses HTTP par l’intermédiaire de contrôleurs ASP.NET Core. la couille de service contient la logique des affaires en utilisant l’Aspose.Médical Anonymizer.La coupe de configuration gène les paramètres de profil et des options d’application. Les composants facultatifs comprennent le stockage pour le logement et le quoi pour la transformation de pièces.
Cette architecture permet une échelle horizontale, un test facile et une intégration simple avec les systèmes d’information hospitalière et les serveurs PACS.
Démarrer le projet
Commencez par la création d’un nouveau projet ASP.NET Core Web API et l’installation du package requis:
dotnet new webapi -n DicomAnonymizationService
cd DicomAnonymizationService
dotnet add package Aspose.Medical
Configurez le projet pour de grands fichiers téléchargés dans 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();
Implémentation de la couche de service
Créer une interface et une mise en œuvre pour le service d’anonymisation :
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);
}
}
Construire le contrôleur API
Créez un contrôleur qui gère les téléchargements de fichiers et retourne les données DICOM anonymisées :
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);
}
}
Profils configurables
Permet de configurer des profils via appsettings.json:
{
"AnonymizationProfiles": {
"default": "basic",
"profiles": {
"basic": ["BasicProfile"],
"research": ["BasicProfile", "RetainPatientChars"],
"internal": ["RetainUIDs", "RetainDeviceIdent"],
"clean": ["CleanGraph", "CleanDesc"],
"maximum": ["BasicProfile", "CleanGraph", "CleanDesc"]
}
}
}
Créer une classe de configuration et mettre à jour le service pour lire des paramètres :
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"));
Considérations en matière de sécurité
Lors de la mise en œuvre de ce service, appliquez ces mesures de sécurité.
Activer HTTPS pour s’assurer que toutes les communications sont cryptées dans le transit. Configurez TLS 1.2 ou supérieur et redirigez l’HTTP vers Https.
Authentification d’implémentation en utilisant les tokens JWT ou les clés API pour limiter l’accès aux clients autorisés:
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class AnonymizeController : ControllerBase
{
// Controller code...
}
** Évitez de stocker des fichiers originaux** non cryptés sur le disque. Traiter les ficher dans la mémoire lorsque cela est possible, et si un stockage temporaire est nécessaire, utilisez des volumes chiffrés.
Activer l’enregistrement d’audit pour suivre toutes les opérations d’anonymisation, y compris qui les a demandées et quand:
_logger.LogInformation(
"Anonymization completed - User: {User}, Profile: {Profile}, FileSize: {Size}",
User.Identity?.Name, profile, file.Length);
L’optimisation des performances
Plusieurs techniques peuvent améliorer les performances pour les scénarios de haute performance.
Utilisez l’anonymisation sur place lorsque vous n’avez pas besoin de conserver les données d’origine dans la mémoire:
anonymizer.AnonymizeInPlace(dcm);
Activer le traitement parallèle pour les opérations 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...
}
Exécution de la demande de quoi pour les lots très grands en utilisant un message quo comme RabbitMQ ou Azure Service Bus pour gérer les pics de chargement sans surcharger le service.
La conclusion (conclusion)
Vous avez maintenant un plan complet pour construire un microservice d’anonymisation DICOM dans ASP.NET Core**. Le service accepte les fichiers DIKOM via HTTP, applique des profils d’anonimisation configurables en utilisant Aspose.Medical, et retourne des dossiers désidentifiés prêts pour la recherche ou le partage.
Les principes clés comprennent l’utilisation d’architecture couverte pour la maintenance, la mise en œuvre de profils configurables pour une flexibilité, le renforcement du service avec authentication et chiffrement, et l’optimisation des performances avec un traitement parallèle.
Pour le code source complet et d’exemples supplémentaires, visitez le Aspose.Documentation médicalePour essayer la flamme, obtenir une licence temporaire gratuite.
More in this category
- Pourquoi l'anonymisation DICOM est importante pour HIPAA et GDPR dans les flux de travail .NET
- Préparation de DICOM Datasets pour l'AI et le Machine Learning avec Aspose.Medical
- Profils de confidentialité personnalisés adaptant l'anonymisation DICOM à vos politiques hospitalières
- Stockage des métadonnées DICOM dans les bases de données SQL et NoSQL avec C#
- DICOM Anonymisation pour Cloud PACS et Teleradiology dans C#