Kā izmantot Async DICOM JSON serializāciju ASP.NET Core Web API

Kā izmantot Async DICOM JSON serializāciju ASP.NET Core Web API

Šis apmācība parāda, kā izmantot async DICOM JSON serializāciju ASP.NET Core tīmekļa APIs. Asynk operācijas ir būtiski augstas izturības tīmeklī lietojumprogrammām, lai novērstu tīkla bloķēšanu un uzturētu atbildību slodzes laikā.

Kāpēc lietot Async serializāciju?

  • Šķīrējumi:- Neblokēšanas I/O ļauj apstrādāt vairāk vienlaicīgu pieprasījumu.

    • Atbildība uz jautājumu:- Tīmekļa serveris paliek atbildīgs lielās failu apstrādes laikā.
  • • Resursu efektivitāte:- Draudzes tiek atbrīvotas, gaidot I/O operācijas.

Priekšnoteikumi: Vides sagatavošana

  • Iestatīt Visual Studio vai jebkuru saderīgu .NET IDE.
  • Izveidojiet jaunu ASP.NET Core Web API projektu, kura mērķis ir .NET 8.
  • Instalējiet Aspose.Medical no NuGet Package Manager.

Lēciens pa solim ceļvedis uz Async DICOM JSON serializāciju

1. solis: instalēt Aspose.Medical

Pievienojiet Aspose.Medicīnas bibliotēku savam projektam, izmantojot NuGet.

Install-Package Aspose.Medical

2. solis: Iekļaut nepieciešamos nosaukuma telpas

Pievienojiet atsauces uz nepieciešamajiem nosaukuma telpām jūsu kontrolierī.

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

3. solis: izveidot Async Deserialization Endpoint

Izveidojiet galamērķi, kas dezerializē JSON no pieprasījuma struktūras.

[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. solis: izveidot Async serializācijas galamērķi

Izveidojiet galīgo punktu, kas atbildē serializē DICOM uz 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. solis: pārvaldīt atcelšanas tokenus

Pasāk atcelšanas tokenus pareizai pieprasījuma atsaukšanas apstrādei.

[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 piemēri

Šeit ir pilns kontrolieris, kas īsteno async DICOM JSON darbības:

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

Iestatīt pieprasījuma lieluma ierobežojumus

Lieliem DICOM failiem iestatīt pieprasījuma ierobežojumus 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();

Stream apstrādes piemērs

Process DICOM failus bez uzlādes pilnībā atmiņā:

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

Labākās kļūdu risināšanas prakses

Visaptveroša kļūdu apstrāde:

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

Papildu labākās prakses

Izmantojot paziņojumus par plūsmām

Vienmēr izmantojiet pareizus uzstādīšanas modeļus:

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

Timeout konfigurācija

Iestatīt piemērotus laika ierobežojumus ilgām darbībām:

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

Papildu informācija

  • Async metodes uzlabo skalabilitāti, bet ne vienmēr paātrina individuālus pieprasījumus.
  • Izmantojiet atcelšanas tokenus, lai pareizi tiktu galā ar klientu atdalījumiem.
  • Pārrauga atmiņas izmantošanu, apstrādājot lielus DICOM failus.

Conclusion

Šis apmācība ir parādījusi, kā īstenot asink DICOM JSON serializāciju ASP.NET Core tīmekļa APIs, izmantojot Aspose.Medical.Asink operācijas ir būtiski, lai izveidotu skalējamas veselības aprūpes API, kas efektīvi apstrādā lielus medicīnisko attēlu datus.

 Latviski