Com utilitzar Async DICOM JSON Serialització en ASP.NET Core Web APIs
Aquest tutorial demostra com utilitzar la serialització async DICOM JSON en les APIs web ASP.NET Core. Les operacions d’asynx són essencials per a les aplicacions web de gran rendiment per evitar el bloqueig de fil i mantenir la resposta sota la càrrega.
Per què s’utilitza la serialització Async?
Escal·labilitat:- No bloquejar I/O permet tractar sol·licituds més concurrents.
• Responsabilitat *:- El servidor web segueix responent durant el processament de fitxers grans.
- Eficiència de recursos *:- Les amenaces són alliberades mentre esperen les operacions I/O.
Previsió: Preparar el medi ambient
- Instal·lació de Visual Studio o qualsevol compatible .NET IDE.
- Creació d’un nou projecte ASP.NET Core Web API amb l’objectiu de .NET 8.
- Instal·la Aspose.Medical des del NuGet Package Manager.
Guia de pas a pas per a la serialització Async DICOM JSON
Pas 1: Instal·lació Aspose.Medical
Afegeix la biblioteca d’Aspose.Medical al teu projecte utilitzant NuGet.
Install-Package Aspose.MedicalPas 2: Incloure els espais de nom necessaris
Afegir referències als espais de nom requerits en el seu controlador.
using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Serialization;
using Microsoft.AspNetCore.Mvc;Pas 3: Crear el punt final de deserialització d’Async
Crea un punt final que deserialitza JSON del cos de sol·licitud.
[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");
}Pas 4: Crear el punt final de serialització d’Async
Crear un punt final que serialitzi DICOM a JSON en la resposta.
[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);
}Pas 5: Gestionar els tokens de cancel·lació
Passar el token d’anul·lació per al correcte tractament de la sol·licitud.
[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();
}Instal·lació d’un controlador ASP.NET Core
Aquí teniu un controlador complet que implementa les operacions d’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}");
}
}
}Configuració de límits de mida de sol·licitud
Per a grans arxius DICOM, configurar límits de sol·licitud en 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();Exemple de processament de flux
Processar els arxius DICOM sense carregar-los completament a la memòria:
[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
);
}Les millors pràctiques de gestió d’errors
Implementar el tractament d’errors complets:
[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 });
}
}Més millors pràctiques
Utilitzar declaracions per a fluxos
Sempre utilitzeu els patrons de disposició adequats:
using (FileStream fs = System.IO.File.OpenRead(filepath))
{
// Process stream
}Configuració Timeout
Configureu els temps adequats per a operacions llargues:
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(2);
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(5);
});Informació addicional
- Els mètodes Async milloren l’escalabilitat però no necessàriament acceleren les sol·licituds individuals.
- Utilitzeu el token d’anul·lació per gestionar correctament les desconnectes del client.
- Monitorar l’ús de la memòria en el processament de grans fitxers DICOM.
Conclusió
Aquest tutorial ha demostrat com implementar la serialització d’async DICOM JSON en les APIs web de base ASP.NET utilitzant Aspose.Medical. Les operacions d’asínc són essencials per a la construcció de l’aplicació sanitària escalable que gestioni de manera eficient les grans dades de la imatge mèdica.