Πώς να χρησιμοποιήσετε Async DICOM JSON Serialization σε ASP.NET Core Web APIs

Πώς να χρησιμοποιήσετε Async DICOM JSON Serialization σε ASP.NET Core Web APIs

Αυτό το εγχειρίδιο δείχνει πώς να χρησιμοποιήσετε το Async DICOM JSON serialization σε ASP.NET Core web APIs. Οι λειτουργίες Asynec είναι απαραίτητες για εφαρμογές web υψηλής απόδοσης για την πρόληψη του μπλοκ και τη διατήρηση της αντίδρασης κάτω από το φορτίο.

Γιατί να χρησιμοποιήσετε το Async Serialization;

  • Αξιοπρέπεια:- Η μη μπλοκ I/O επιτρέπει την αντιμετώπιση περισσότερων συναφών αιτήσεων.

  • • Αντιδράσεις *:- Ο διακομιστής ιστού παραμένει αντιδραστικός κατά τη διάρκεια της επεξεργασίας μεγάλων αρχείων.

  • • Αποτελεσματικότητα των πόρων:- Οι απειλές απελευθερώνονται ενώ περιμένουν τις επιχειρήσεις I/O.

Προϋποθέσεις: Προετοιμασία του περιβάλλοντος

  • Εγκαταστήστε το Visual Studio ή οποιοδήποτε συμβατό .NET IDE.
  • Δημιουργήστε ένα νέο ASP.NET Core Web API project που στοχεύει στο .NET 8.
  • Εγκαταστήστε το Aspose.Medical από το NuGet Package Manager.

Βήμα προς βήμα Οδηγός για το Async DICOM JSON

Βήμα 1: Εγκατάσταση Aspose.Medical

Προσθήκη της βιβλιοθήκης Aspose.Medical στο έργο σας χρησιμοποιώντας το NuGet.

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 Serialization Endpoint

Δημιουργήστε ένα τελικό σημείο που θα σκηνοθετήσει το 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: Διαχειριστείτε τα tokens ακύρωσης

Διαβάστε τα tokens ακύρωσης για την ορθή επεξεργασία της αίτησης ακυρώσεως.

[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 Core Controller

Εδώ είναι ένας ολοκληρωμένος ελεγκτής που εφαρμόζει τις λειτουργίες 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
}

Ο χρόνος διαμόρφωσης

Προσαρμόστε τις κατάλληλες χρονοδιάγραμμα για μακροχρόνιες εργασίες:

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

Πρόσθετες πληροφορίες

  • Οι μέθοδοι Async βελτιώνουν την κλιμάκωση, αλλά δεν επιταχύνουν απαραίτητα τις μεμονωμένες αιτήσεις.
  • Χρησιμοποιήστε τα tokens ακύρωσης για να χειριστείτε σωστά τις διασυνδέσεις του πελάτη.
  • Παρακολούθηση της χρήσης μνήμης κατά την επεξεργασία μεγάλων αρχείων DICOM.

Συμπεράσματα

Αυτό το εγχειρίδιο έχει αποδείξει πώς να εφαρμόσει async DICOM JSON serialization σε ASP.NET Core web APIs χρησιμοποιώντας Aspose.Medical. Οι λειτουργίες Asynk είναι απαραίτητες για την οικοδόμηση κλιμακώδεις υγειονομικές API που χειρίζονται τα μεγάλα δεδομένα ιατρικής εικόνας αποτελεσματικά.

 Ελληνικά