บทแนะนำ: เปิดเอกสารด้วย Doconut Viewer ที่ฉีดเข้ามาใน .NET 8
← Back to Blog3 min read

บทแนะนำ: เปิดเอกสารด้วย Doconut Viewer ที่ฉีดเข้ามาใน .NET 8

บทนำ

ตัวอย่าง Doconut เก่าอาจสร้าง Viewer โดยตรงด้วยอาร์กิวเมนต์ cache, HTTP-context, และ license-path นั้นไม่ใช่โมเดลการบูรณาการ .NET 8 ปัจจุบัน AddDoconut() จะลงทะเบียน Viewer ด้วย dependency injection และ endpoint ของแอปพลิเคชันจะรับบริการแทนการเรียกคอนสตรัคเตอร์

ส่วนประกอบเซิร์ฟเวอร์แบบนามธรรมส่งโทเคนเซสชันที่ไม่เปิดเผยไปยังพื้นผิวการดูเอกสาร
ส่วนประกอบเซิร์ฟเวอร์แบบนามธรรมส่งโทเคนเซสชันที่ไม่เปิดเผยไปยังพื้นผิวการดูเอกสาร

บทแนะนำนี้จะตามขั้นตอนการร้องขอปัจจุบัน: ลงทะเบียนบริการและมิดเดิลแวร์, ส่งออกทรัพยากร viewer ที่ฝังไว้, เปิดเอกสารด้วย OpenDocumentAsync, ส่งคืนโทเคนที่ไม่เปิดเผย, และส่งโทเคนนั้นไปยังวิดเจ็ตในเบราว์เซอร์


1. ติดตั้งและลงทะเบียน Doconut

เพิ่มแพคเกจ .NET 8:

dotnet add package Doconut.NET8

ลงทะเบียน Doconut และบริการเซสชันของ ASP.NET:

builder.Services.AddDoconut(options =>
{
    options.LicensePath = "Doconut.Viewer.lic";
    options.MiddlewarePath = "/doconut";
    options.ResourcesPath = "/doconut-res";
    options.UnsafeMode = false;
});

builder.Services.AddSession();

เชื่อมต่อมิดเดิลแวร์ในลำดับที่จำเป็น มิดเดิลแวร์ทรัพยากรต้องทำงานก่อนมิดเดิลแวร์เอกสารขั้นสุดท้าย:

app.UseRouting();
app.UseSession();
app.UseDoconutResources();
app.Map("/doconut", branch => branch.UseDoconut());

MiddlewarePath ประสานการตั้งค่าแต่ไม่ได้สร้างสาขา ASP.NET ด้วยตัวเอง เส้นทาง /doconut ที่แมปต้องตรงกับ BasePath ของวิดเจ็ต

2. เพิ่มพื้นผิว viewer และทรัพยากร

Doconut browser viewer เป็นปลั๊กอิน jQuery ในหน้า Razor ให้ฉีด Viewer แล้วสั่งให้ส่งออกแท็กทรัพยากรตามลำดับ dependency:

@inject Doconut.Viewer Viewer

@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
    IncludeViewerCss = true
}))

@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery = true,
    IncludeViewerScripts = true
}))

<div id="divDocViewer">
    <div id="div_ctlDoc"></div>
</div>

เริ่มต้นวิดเจ็ตด้วยเส้นทางที่ตรงกับการลงทะเบียนบนเซิร์ฟเวอร์:

const objViewer = $('#div_ctlDoc').docViewer({
    showThumbs: true,
    autoLoad: false,
    pageZoom: 100,
    FitType: 'width',
    BasePath: '/doconut',
    ResPath: '/doconut-res/images',
    onError: function (message) {
        console.error('Doconut viewer error:', message);
    }
});

การตั้งค่าตัวอักษรมีความสำคัญ ใช้ชื่อที่แสดงโดยเวอร์ชันที่ติดตั้งอยู่แทนการทำให้เป็นรูปแบบเดียวกัน

3. ฉีด Viewer และเปิดเอกสาร

Viewer ถูกลงทะเบียนเป็นบริการแบบ transient ให้ดึงผ่านการฉีด endpoint, การฉีดคอนสตรัคเตอร์ หรือวิธีการเทียบเท่าในแอป ASP.NET Core ของคุณ

app.MapPost("/api/open", async (
    Viewer viewer,
    CancellationToken ct) =>
{
    string token = await viewer.OpenDocumentAsync(
        "wwwroot/files/Sample.pdf",
        ct: ct);

    return Results.Ok(new { token });
});

สำหรับการอัปโหลด ให้ส่งสตรีมและ FileInfo ที่ส่วนต่อท้ายไฟล์บ่งบอกรูปแบบต้นฉบับ:

app.MapPost("/api/open-upload", async (
    IFormFile file,
    Viewer viewer,
    CancellationToken ct) =>
{
    await using var stream = file.OpenReadStream();
    string token = await viewer.OpenDocumentAsync(
        stream,
        new FileInfo(file.FileName),
        ct: ct);

    return Results.Ok(new { token });
});

ตรวจสอบขนาดอัปโหลด, ส่วนต่อท้ายไฟล์, และการอนุญาตก่อนเปิดเนื้อหาที่ผู้ใช้ส่งมา อย่าแปลงชื่อไฟล์ที่ส่งเป็นเส้นทางบนเซิร์ฟเวอร์

4. ส่งโทเคนไปยังวิดเจ็ต

เรียก endpoint ที่เปิดเอกสารและส่งโทเคนที่ได้รับให้ objViewer.View:

fetch('/api/open', { method: 'POST' })
    .then(response => {
        if (!response.ok) throw new Error('The document could not be opened.');
        return response.json();
    })
    .then(data => objViewer.View(data.token))
    .catch(error => console.error(error));

ถือโทเคนเป็นข้อมูลรับรองแบบ bearer สำหรับเซสชันเอกสารสด:

  • อย่าเก็บบันทึกหรือบันทึกโทเคน
  • ส่งคืนให้กับไคลเอนต์ที่ได้รับอนุญาตเท่านั้น
  • อย่าเปิดเผยเส้นทางไฟล์ต้นฉบับ
  • เปิดเอกสารใหม่เมื่อเซสชันหมดอายุ
  • ปิดเซสชันเมื่อเอกสารไม่ต้องการใช้งานต่อ

5. ปิดเซสชันฝั่งเซิร์ฟเวอร์โดยเจตนา

โค้ดไคลเอนต์สามารถเรียก objViewer.Close() เมื่อผู้ใช้ออกจาก viewer ได้เช่นกัน เวิร์กโฟลว์บนเซิร์ฟเวอร์ก็สามารถเพิกถอนโทเคนที่รู้จักโดยชัดเจน:

app.MapPost("/api/close", (string token, Viewer viewer) =>
{
    viewer.CloseDocument(token);
    return Results.NoContent();
});

การปิดอย่างชัดเจนมีประโยชน์เป็นพิเศษกับเอกสารขนาดใหญ่ การหมดอายุของเซสชันยังคงเป็นวิธีสำรอง ไม่ใช่การทดแทนการจัดการวงจรชีวิตแอปพลิเคชันที่คาดเดาได้

6. เพิ่มโมดูลเสริมเฉพาะหลังจาก core ทำงานสำเร็จ

การค้นหาและการทำหมายเหตุจะผูกกับ viewer ที่เริ่มต้นแล้ว ให้เพิ่ม CSS, สคริปต์, การเมานท์, การตรวจสอบลิขสิทธิ์, และคอลแบ็กวงจรชีวิตเฉพาะหลังจาก flow พื้นฐานสำเร็จ:

AddDoconut + session services
    -> UseSession
    -> UseDoconutResources
    -> mapped UseDoconut branch
    -> viewer resources and mount
    -> initialize docViewer
    -> OpenDocumentAsync
    -> objViewer.View(token)

ลำดับนี้ทำให้ข้อผิดพลาดการเรนเดอร์ core แยกจากการกำหนดค่าโมดูลเสริมได้อย่างชัดเจน

ความผิดพลาดทั่วไปในการย้าย

รูปแบบเก่าหรือไม่ถูกต้องแนวทาง .NET 8 ปัจจุบัน
new Viewer(cache, accessor, licensePath)ฉีด Viewer หลัง AddDoconut()
การเรียกโหลดไลเซนส์แบบสแตติกในโค้ดร้องขอตั้งค่าไลเซนส์ใน AddDoconut()
ตัวอย่าง OpenDocument(...) แบบซิงโครนัสใช้ OpenDocumentAsync(...)
CDN viewer ภายนอกหรือที่สร้างขึ้นเองส่งออกทรัพยากรฝังด้วย ReferenceCss และ ReferenceScripts
API JavaScript init() ทั่วไปเริ่มต้นด้วย $('#div_ctlDoc').docViewer(...)
การเก็บโทเคน viewerเก็บ ID เอกสารของคุณ; ถือโทเคนเป็นชั่วคราว

ใช้ เอกสาร Doconut อย่างเป็นทางการ และตรวจสอบตัวอย่างกับเวอร์ชันแพคเกจที่ติดตั้งก่อนนำไปใช้ในโค้ดผลิตจริง.

#Doconut#.NET 8#Document Viewer#ASP.NET Core#JavaScript#ตัวดูเอกสาร