สถาบันการดูแลสุขภาพต้องการโซลูชั่นอัตโนมัติมากขึ้นเพื่อลบการระบุข้อมูลภาพทางการแพทย์ ในคู่มือนี้คุณจะเรียนรู้วิธีการสร้างบริการไมโครซอฟต์แวร์การอ้างอิงของ DICOM ใน ASP.NET Core** ซึ่งจะรับไฟล์ DIKOM ผ่าน HTTP, anonimizes พวกเขาโดยใช้โปรไฟล์ที่กําหนดเองและคืนผลลัพธ์ที่ล้มเหลว ในที่สุดคุณจะมีสถาปัตยกรรมบริการพร้อมการผลิตพร้อมรหัสแหล่งตัวอย่าง
ตารางเนื้อหา
- ทบทวนการก่อสร้าง
- การตั้งค่าโครงการ
- การดําเนินงานของ Layer Service
- สร้างตัวควบคุม API
- โปรไฟล์ที่กําหนดเอง
- การพิจารณาความปลอดภัย
- การปรับแต่งประสิทธิภาพ
- ข้อสรุป
สถาปัตยกรรม Overview
ไมโครเซิร์ฟเวอร์ปฏิบัติตามโครงสร้างชั้นที่มีการแยกที่ชัดเจนของความกังวล ชั้น API จัดการคําขอและตอบสนอง HTTP ผ่านตัวควบคุมหลัก ASP.NET ชั้นบริการประกอบด้วยโลโก้ธุรกิจโดยใช้ Aspose.Medical Anonymizer ชั้นการกําหนดค่าจัดการการตั้งค่าโปรไฟล์และตัวเลือกการใช้งาน ส่วนประกอบทางเลือกรวมถึงการจัดเก็บข้อมูลสําหรับการเข้าสู่ระบบและสแกนสําหรับการประมวลผลแพทช์
อาคารนี้ช่วยให้การสแกนแนวนอนการทดสอบง่ายและการบูรณาการได้อย่างง่ายดายกับระบบข้อมูลโรงพยาบาลและเซิร์ฟเวอร์ PACS
การตั้งค่าโครงการ
เริ่มต้นโดยการสร้างโครงการ API Web Core ASP.NET ใหม่และติดตั้งแพคเกจที่ต้องการ:
dotnet new webapi -n DicomAnonymizationService
cd DicomAnonymizationService
dotnet add package Aspose.Medical
การตั้งค่าโครงการสําหรับการอัพโหลดไฟล์ขนาดใหญ่ใน 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();
การดําเนินงานของ Layer Service
สร้างอินเทอร์เฟซและการประยุกต์ใช้สําหรับบริการ匿名:
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);
}
}
สร้างตัวควบคุม API
สร้างตัวควบคุมที่จัดการอัปโหลดไฟล์และส่งกลับไฟล์ DICOM ที่ไม่ระบุชื่อ:
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);
}
}
โปรไฟล์ที่กําหนดเอง
อนุญาตให้โปรไฟล์ถูกกําหนดเองผ่าน appsettings.json:
{
"AnonymizationProfiles": {
"default": "basic",
"profiles": {
"basic": ["BasicProfile"],
"research": ["BasicProfile", "RetainPatientChars"],
"internal": ["RetainUIDs", "RetainDeviceIdent"],
"clean": ["CleanGraph", "CleanDesc"],
"maximum": ["BasicProfile", "CleanGraph", "CleanDesc"]
}
}
}
สร้างหมวดหมู่การกําหนดค่าและอัปเดตบริการเพื่ออ่านจากตั้งค่า:
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"));
ความคิดเห็นเกี่ยวกับความปลอดภัย
เมื่อใช้บริการนี้ใช้มาตรการรักษาความปลอดภัยเหล่านี้
เปิดใช้งาน HTTPS เพื่อให้แน่ใจว่าการสื่อสารทั้งหมดจะถูกเข้ารหัสผ่าน การตั้งค่า TLS 1.2 หรือสูงขึ้นและนําไปสู่ Http
การรับรองการดําเนินการ ใช้ tokens JWT หรือคีย์ API เพื่อ จํากัด การเข้าถึงลูกค้าที่ได้รับอนุญาต:
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class AnonymizeController : ControllerBase
{
// Controller code...
}
หลีกเลี่ยงการจัดเก็บไฟล์ต้นฉบับ ไม่เข้ารหัสบนไดรฟ์ การประมวลผลไฟล์ในหน่วยความจําเมื่อเป็นไปได้และหากจําเป็นต้องเก็บข้อมูลชั่วคราวใช้ปริมาณที่เข้ารับซ้อน
เปิดใช้งานการเข้าสู่ระบบการตรวจสอบ เพื่อติดตามการทําธุรกรรม匿名ทั้งหมดรวมถึงผู้ที่ร้องขอและเมื่อ:
_logger.LogInformation(
"Anonymization completed - User: {User}, Profile: {Profile}, FileSize: {Size}",
User.Identity?.Name, profile, file.Length);
การปรับปรุงประสิทธิภาพ
เทคนิคต่างๆสามารถปรับปรุงประสิทธิภาพสําหรับสถานการณ์ที่มีประสิทธิภาพสูง
ใช้การระบุชื่อในสถานที่ เมื่อคุณไม่จําเป็นต้องเก็บข้อมูลเดิมในหน่วยความจํา:
anonymizer.AnonymizeInPlace(dcm);
เปิดใช้งานการประมวลผลแบบสม่ําเสมอ สําหรับการดําเนินงานชุด:
[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...
}
การประมวลผลคําขอ quuing สําหรับแพทช์ขนาดใหญ่มากโดยใช้อัตราข้อความเช่น RabbitMQ หรือ Azure Service Bus เพื่อจัดการความเร็วในการโหลดโดยไม่ต้องเอาชนะบริการ
ข้อสรุป
ตอนนี้คุณมีแผนภาพที่สมบูรณ์สําหรับการสร้าง DICOM anonymization microservice ใน ASP.NET Core บริการนี้ยอมรับไฟล์ DICO via HTTP ใช้โปรไฟล์ anonymisation ที่กําหนดเองโดยใช้ Aspose.Medical และส่งไฟล์ที่ไม่ได้ระบุพร้อมสําหรับการวิจัยหรือแบ่งปัน
ข้อตกลงหลักรวมถึงการใช้โครงสร้างชั้นสําหรับการบํารุงรักษาการนําไปใช้โปรไฟล์ที่กําหนดเองเพื่อความยืดหยุ่นการรักษาบริการด้วยการรับรองและการเข้ารหัสและการเพิ่มประสิทธิภาพในการประมวลผลร่วมกัน
สําหรับรหัสแหล่งข้อมูลที่สมบูรณ์และตัวอย่างเพิ่มเติมเยี่ยมชม Aspose.Documentationทางการแพทย์เพื่อทดลองไฟ รับใบอนุญาตชั่วคราวฟร.
More in this category
- การเตรียม DICOM Datasets สําหรับ AI และ Machine Learning ด้วย Aspose.Medical
- ทําไม DICOM Anonymization เป็นสิ่งสําคัญสําหรับ HIPAA และ GDPR ใน .NET Workflows
- โปรไฟล์ความเป็นส่วนตัวที่กําหนดเองปรับแต่ง DICOM Anonymization เพื่อนโยบายโรงพยาบาลของคุณ
- การจัดเก็บข้อมูล DICOM ในฐานข้อมูล SQL และ NoSQL ด้วย C#
- DICOM Anonymization สําหรับ Cloud PACS และ Teleradiology ใน C#