Bagaimana untuk menggunakan Async DICOM JSON Serialisasi dalam ASP.NET Core Web APIs

Bagaimana untuk menggunakan Async DICOM JSON Serialisasi dalam ASP.NET Core Web APIs

Tutorial ini menunjukkan bagaimana untuk menggunakan serialisasi async DICOM JSON dalam APIs web ASP.NET Core. operasi asynec adalah penting untuk aplikasi web berprestasi tinggi untuk mengelakkan penghalang thread dan mengekalkan responsiveness di bawah beban.

Mengapa menggunakan Async Serialization?

  • Kadar pengeluaran:- Non-blocking I/O membolehkan menangani permintaan yang lebih serentak.

    • Perbezaan antara tanggungjawab :- Pelayan web kekal responsif semasa pemprosesan fail yang besar.
  • *Keselamatan dan keberkesanan sumber :- Ancaman dibebaskan semasa menunggu operasi I/O.

Tag: persiapan persekitaran

  • Menyediakan Visual Studio atau mana-mana .NET IDE yang kompatibel.
  • Mencipta projek baru ASP.NET Core Web API yang menargetkan .NET 8.
  • Instal Aspose.Medical daripada NuGet Package Manager.

Panduan Langkah-Langkah untuk Async DICOM JSON Serialisasi

Langkah 1: Instal Aspose.Medical

Tambah perpustakaan Aspose.Medical kepada projek anda menggunakan NuGet.

Install-Package Aspose.Medical

Langkah 2: Masukkan ruang nama yang diperlukan

Tambah rujukan kepada ruang nama yang diperlukan dalam kawalan anda.

using Aspose.Medical.Dicom;
using Aspose.Medical.Dicom.Serialization;
using Microsoft.AspNetCore.Mvc;

Langkah 3: Mencipta titik akhir deserialisasi Async

Mencipta titik akhir yang memusnahkan JSON daripada badan permintaan.

[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");
}

Langkah 4: Mencipta titik akhir seri Async

Mencipta titik akhir yang serialisasi DICOM kepada JSON dalam jawapan.

[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);
}

Langkah 5: Mengendalikan token pembatalan

Lulus token pembatalan untuk pemprosesan permohonan yang betul.

[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();
}

Penggunaan ASP.NET Core Controller

Berikut adalah kawalan lengkap yang melaksanakan operasi 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}");
        }
    }
}

Menentukan batasan saiz permintaan

Untuk fail DICOM yang besar, tetapkan had permintaan dalam 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();

Contoh pemprosesan aliran

Memproses fail DICOM tanpa memuatkan sepenuhnya ke dalam memori:

[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
    );
}

Kesilapan Pengurusan Amalan Terbaik

Pengurusan Kesilapan Komprehensif :

[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 });
    }
}

Amalan-amalan terbaik tambahan

Menggunakan Pernyataan untuk Streams

Sentiasa gunakan corak penyelesaian yang betul:

using (FileStream fs = System.IO.File.OpenRead(filepath))
{
    // Process stream
}

Konfigurasi Timeout

Menetapkan masa yang sesuai untuk operasi yang panjang:

builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(2);
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(5);
});

Maklumat tambahan

  • Kaedah async meningkatkan skalabiliti tetapi tidak semestinya mempercepatkan permintaan individu.
  • Gunakan token pembatalan untuk mengendalikan penyelewengan klien dengan betul.
  • Memantau penggunaan memori apabila memproses fail DICOM yang besar.

Conclusion

Tutorial ini telah membuktikan bagaimana untuk melaksanakan async DICOM JSON serialisasi dalam ASP.NET Core web APIs menggunakan Aspose.Medical. operasi Asynk adalah penting untuk membina API penjagaan kesihatan yang boleh diukur yang mengendalikan data imej perubatan yang besar dengan cekap.

 Melayu