ASP.NET 코어 웹 애플리케이션에서 Async DICOM JSON 시리즈를 사용하는 방법
ASP.NET 코어 웹 애플리케이션에서 Async DICOM JSON 시리즈를 사용하는 방법
이 튜토리얼은 ASP.NET 코어 웹 APIs에서 async DICOM JSON 시리화를 사용하는 방법을 보여줍니다.Asynk 작업은 흐름 차단을 방지하고 충전 중 응답성을 유지하기 위해 고성능 웹 응용 프로그램에 필수적입니다.
왜 Async Serialization을 사용합니까?
스케일링 가능성:- I/O를 차단하지 않는 것은 더 많은 동일한 요청을 처리 할 수 있습니다.
- 응답성 * :- 웹 서버는 큰 파일 처리 중에 응답적으로 유지됩니다.
- 자원 효율성* :- 위협은 I/O 작업을 기다리는 동안 풀려납니다.
원제 : Environment Preparation
- Visual Studio 또는 모든 호환되는 .NET IDE를 설정합니다.
- .NET 8을 대상으로 하는 새로운 ASP.NET Core Web API 프로젝트를 만드십시오.
- NuGet 패키지 관리자에서 Aspose.Medical을 설치합니다.
Async DICOM JSON 시리즈에 대한 단계별 가이드
단계 1 : Aspose.Medical 설치
NuGet을 사용하여 프로젝트에 Aspose.Medical 도서관을 추가합니다.
Install-Package Aspose.Medical단계 2 : 필요한 이름 공간을 포함
컨트롤러에 필요한 이름 공간에 참조를 추가합니다.
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Serialization;
using Microsoft.AspNetCore.Mvc;3단계: Async Deserialization Endpoint 만들기
요청 기관에서 JSON을 제거하는 최종 포인트를 만듭니다.
[HttpPost("import")]
public async Task<IActionResult> ImportDicomJson()
{
Dataset? dataset = await DicomJsonSerializer.DeserializeAsync(Request.Body);
if (dataset == null)
return BadRequest("Invalid DICOM JSON");
return Ok("DICOM data imported successfully");
}4단계: Async 시리얼링 엔드포인트 만들기
응답에서 DICOM을 JSON로 시리즈화하는 최종 포인트를 만듭니다.
[HttpGet("export/{filename}")]
public async Task ExportDicomJson(string filename)
{
DicomFile dcm = DicomFile.Open($"storage/{filename}");
Response.ContentType = "application/json";
await DicomJsonSerializer.SerializeAsync(Response.Body, dcm.Dataset);
}단계 5 : 취소 토큰을 처리
적절한 요청 취소 처리에 대 한 거부 토큰을 통과.
[HttpPost("process")]
public async Task<IActionResult> ProcessDicomAsync(CancellationToken cancellationToken)
{
Dataset? dataset = await DicomJsonSerializer.DeserializeAsync(
Request.Body,
cancellationToken
);
if (cancellationToken.IsCancellationRequested)
return StatusCode(499, "Client Closed Request");
// Process dataset...
return Ok();
}ASP.NET 코어 컨트롤러
다음은 async DICOM JSON 작업을 구현하는 완전한 컨트롤러입니다 :
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Serialization;
using Microsoft.AspNetCore.Mvc;
namespace DicomApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class DicomController : ControllerBase
{
private readonly string _storagePath = "dicom_storage";
public DicomController()
{
Directory.CreateDirectory(_storagePath);
}
/// <summary>
/// Import DICOM JSON and save as DICOM file
/// </summary>
[HttpPost("import")]
public async Task<IActionResult> ImportDicomJson(CancellationToken cancellationToken)
{
try
{
Dataset? dataset = await DicomJsonSerializer.DeserializeAsync(
Request.Body,
cancellationToken
);
if (dataset == null)
return BadRequest("Failed to deserialize DICOM JSON");
// Generate unique filename
string filename = $"{Guid.NewGuid()}.dcm";
string filepath = Path.Combine(_storagePath, filename);
// Save as DICOM file
DicomFile dcm = new DicomFile(dataset);
dcm.Save(filepath);
return Ok(new { message = "DICOM imported successfully", filename });
}
catch (OperationCanceledException)
{
return StatusCode(499, "Request cancelled");
}
catch (Exception ex)
{
return BadRequest($"Import failed: {ex.Message}");
}
}
/// <summary>
/// Export DICOM file as JSON stream
/// </summary>
[HttpGet("export/{filename}")]
public async Task ExportDicomJson(string filename, CancellationToken cancellationToken)
{
string filepath = Path.Combine(_storagePath, filename);
if (!System.IO.File.Exists(filepath))
{
Response.StatusCode = 404;
await Response.WriteAsync("File not found");
return;
}
try
{
DicomFile dcm = DicomFile.Open(filepath);
Response.ContentType = "application/json";
Response.Headers["Content-Disposition"] = $"attachment; filename=\"{filename}.json\"";
await DicomJsonSerializer.SerializeAsync(
Response.Body,
dcm.Dataset,
writeIndented: true
);
}
catch (OperationCanceledException)
{
// Client disconnected
}
catch (Exception ex)
{
Response.StatusCode = 500;
await Response.WriteAsync($"Export failed: {ex.Message}");
}
}
/// <summary>
/// Convert uploaded DICOM file to JSON
/// </summary>
[HttpPost("convert")]
[RequestSizeLimit(100_000_000)] // 100MB limit
public async Task ConvertDicomToJson(IFormFile file, CancellationToken cancellationToken)
{
if (file == null || file.Length == 0)
{
Response.StatusCode = 400;
await Response.WriteAsync("No file uploaded");
return;
}
try
{
// Save uploaded file temporarily
string tempPath = Path.GetTempFileName();
using (var stream = System.IO.File.Create(tempPath))
{
await file.CopyToAsync(stream, cancellationToken);
}
// Load and convert
DicomFile dcm = DicomFile.Open(tempPath);
Response.ContentType = "application/json";
await DicomJsonSerializer.SerializeAsync(
Response.Body,
dcm.Dataset,
writeIndented: true
);
// Cleanup temp file
System.IO.File.Delete(tempPath);
}
catch (OperationCanceledException)
{
// Client disconnected
}
catch (Exception ex)
{
Response.StatusCode = 500;
await Response.WriteAsync($"Conversion failed: {ex.Message}");
}
}
}요청 크기 제한 설정
큰 DICOM 파일의 경우 요청 제한을 설정합니다. Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Configure Kestrel for large uploads
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 500_000_000; // 500MB
});
// Configure form options
builder.Services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 500_000_000;
});
var app = builder.Build();흐름 처리 예제
메모리에 완전히 충전하지 않고 DICOM 파일을 처리 :
[HttpPost("stream-process")]
public async Task StreamProcessDicom(CancellationToken cancellationToken)
{
// Read JSON from request body stream
using var reader = new StreamReader(Request.Body);
string json = await reader.ReadToEndAsync(cancellationToken);
// Deserialize
Dataset? dataset = DicomJsonSerializer.Deserialize(json);
if (dataset == null)
{
Response.StatusCode = 400;
await Response.WriteAsync("Invalid JSON");
return;
}
// Process and stream response
Response.ContentType = "application/json";
await DicomJsonSerializer.SerializeAsync(
Response.Body,
dataset,
writeIndented: true
);
}실수 처리 최상의 관행
포괄적 인 오류 처리 실행 :
[HttpPost("safe-import")]
public async Task<IActionResult> SafeImportDicomJson(CancellationToken cancellationToken)
{
try
{
Dataset? dataset = await DicomJsonSerializer.DeserializeAsync(
Request.Body,
cancellationToken
);
if (dataset == null)
return BadRequest(new { error = "Invalid DICOM JSON format" });
// Process dataset...
return Ok(new { success = true });
}
catch (OperationCanceledException)
{
return StatusCode(499, new { error = "Request cancelled by client" });
}
catch (JsonException ex)
{
return BadRequest(new { error = "JSON parsing error", details = ex.Message });
}
catch (OutOfMemoryException)
{
return StatusCode(507, new { error = "File too large to process" });
}
catch (Exception ex)
{
return StatusCode(500, new { error = "Internal server error", details = ex.Message });
}
}추가 최고의 관행
흐름에 대한 진술을 사용하여
항상 적절한 배치 패턴을 사용하십시오 :
using (FileStream fs = System.IO.File.OpenRead(filepath))
{
// Process stream
}Timeout 설정
긴 작업을위한 적절한 시간을 설정하십시오 :
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(2);
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(5);
});추가 정보
- Async 방법은 확장 가능성을 향상시키지만 개별 요청을 가속화 할 필요는 없습니다.
- 취소 토큰을 사용하여 클라이언트 분리 사항을 적절하게 처리합니다.
- 큰 DICOM 파일을 처리할 때 메모리 사용을 모니터링합니다.
결론
이 튜토리얼은 Aspose.Medical을 사용하여 ASP.NET 코어 웹 APIs에서 async DICOM JSON 시리화를 구현하는 방법을 보여주었습니다.