چگونه از Async DICOM JSON Serialization در ASP.NET Core Web APIs استفاده کنیم

چگونه از Async DICOM JSON Serialization در ASP.NET Core Web APIs استفاده کنیم

این راهنمای نشان می دهد که چگونه برای استفاده از serialization async DICOM JSON در ASP.NET هسته وب APIs. عملیات Asynk برای برنامه های وب با نفوذ بالا برای جلوگیری از مسدود کردن نوار و حفظ پاسخگویی تحت بار ضروری است.

چرا از Async Serialization استفاده می کنیم؟

  • تغییرمسیر:- عدم مسدود کردن I/O اجازه می دهد تا درخواست های بیشتر همزمان را پردازش کند.

    • مسئولیت پذیری * :- سرور وب در طول پردازش فایل های بزرگ پاسخگو باقی می ماند.
  • استفاده از منابع :- تهدیدها در انتظار عملیات I/O آزاد می شوند.

برچسب ها: آماده سازی محیط زیست

  • Visual Studio یا هر IDE .NET سازگار را نصب کنید.
  • ایجاد یک پروژه جدید ASP.NET Core Web API با هدف .NET 8.
  • نصب Aspose.Medical از NuGet Package Manager.

راهنمای گام به گام برای سریال سازی Async DICOM JSON

مرحله اول: نصب Aspose.Medical

کتابخانه Aspose.Medical را به پروژه خود با استفاده از NuGet اضافه کنید.

Install-Package Aspose.Medical

مرحله دوم: فضای نام مورد نیاز را شامل کنید

ارجاعات را به فضاهای نام مورد نیاز در کنترلر خود اضافه کنید.

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

مرحله 3: ایجاد نقطه نهایی Deserialization Async

ایجاد یک نقطه نهایی که 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");
}

مرحله چهارم: ایجاد نقطه پایان سریال Async

یک نقطه نهایی ایجاد کنید که 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: مدیریت توکن های لغو

پاس توکن های لغو برای پاسخگویی به درخواست برای پردازش.

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

Timeout تنظیمات

تنظیم زمان مناسب برای عملیات های طولانی:

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

اطلاعات اضافی

  • روش های Async مقیاس پذیری را بهبود می بخشد اما لزوما تقاضای فردی را تسریع نمی کند.
  • از توکن های لغو برای مقابله با اختلالات مشتری به درستی استفاده کنید.
  • کنترل استفاده از حافظه در هنگام پردازش فایل های بزرگ DICOM.

نتیجه گیری

این آموزش نشان داده است که چگونه برای پیاده سازی serialization async DICOM JSON در ASP.NET هسته وب APIs با استفاده از Aspose.Medical.

 فارسی