Kaip naudoti Async DICOM JSON Serialization ASP.NET Core Web API

Kaip naudoti Async DICOM JSON Serialization ASP.NET Core Web API

Šis mokymas rodo, kaip naudoti async DICOM JSON serijalizavimą ASP.NET branduolinėse žiniatinklio API. Asynco operacijos yra būtinos aukštos įtakos interneto programoms, siekiant užkirsti kelią spindulių blokavimui ir palaikyti atsakingumą.

Kodėl verta naudoti Async serialization?

  • Skaičiuojamumas:- Neblokavimas I/O leidžia tvarkyti daugiau bendrų prašymų.

  • Atsakomybė ir atsakomybė:- Interneto serveris išlieka atsakingas didelių failų apdorojimo metu.

  • • Išteklių efektyvumas:- Grėsmės išleidžiamos laukiant I/O operacijų.

Žymos archyvas: paruošti aplinką

  • Įdiegti „Visual Studio“ arba bet kokį suderinamą .NET IDE.
  • Sukurkite naują ASP.NET Core Web API projektą, skirtą .NET 8.
  • Įdiegti Aspose.Medical iš NuGet paketų valdytojo.

Žingsnis po žingsnio Async DICOM JSON serializavimo vadovas

1 žingsnis: įdiegti Aspose.Medical

Pridėti Aspose.Medicinos biblioteką į savo projektą naudojant NuGet.

Install-Package Aspose.Medical

2 žingsnis: įtraukti reikiamus pavadinimų erdves

Įveskite nuorodas į reikalingą vardų erdvę jūsų kontrolieriuje.

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

3 žingsnis: sukurkite Async Deserialization Endpoint

Sukurkite galutinę tašką, kuri dezerializuoja JSON iš prašymo organo.

[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 žingsnis: Async serializavimo galutinis taškas

Sukurkite galutinį tašką, kuris serijalizuoja DICOM į JSON atsakyme.

[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 žingsnis: tvarkykite atšaukimo tokenus

Pasirašykite atšaukimo žymenis, kad būtų tinkamai tvarkomi prašymai.

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

Išsamus ASP.NET Core Controller pavyzdys

Štai visiškas valdytojas, įgyvendinantis async DICOM JSON operacijas:

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

Paraiškos dydžio apribojimai

Dideliems DICOM failams nustatykite prašymo ribas 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 apdorojimo pavyzdys

Procesuoti DICOM failus be įkrovimo visiškai į atmintį:

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

Geriausios klaidų tvarkymo praktikos

Išsamus klaidų tvarkymas:

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

Papildomos geriausios praktikos

Naudojant pranešimus apie srautus

Visada naudokite tinkamus skirstymo modelius:

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

Timeout konfigūracija

Nustatykite tinkamus laikotarpius ilgoms operacijoms:

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

Papildoma informacija

  • Async metodai pagerina skalavimą, bet nebūtinai pagreitina individualius prašymus.
  • Naudokite atšaukimo tokenus, kad tinkamai tvarkytumėte kliento nesusijimus.
  • Stebėkite atminties naudojimą, kai apdorojate didelius DICOM failus.

Conclusion

Šis mokymas parodė, kaip įgyvendinti async DICOM JSON serijalizavimą ASP.NET branduolinėse žiniatinklio API naudojant Aspose.Medical. Asynco operacijos yra būtinos skalavimui sveikatos priežiūros API, kurios veiksmingai tvarko didelius medicinos vaizdo duomenis.

 Lietuvių