הגירה ל-.NET Standard 2.1

העברת יישום Doconut.NETStandard קיים מ-26.7.0 ל-26.8.0

ל‑Doconut יש שתי אינטגרציות נפרדות של .NET Standard. הן משתמשות באותו שם חבילה Doconut.NETStandard, ולכן יש לזהות את הדור לפי הגרסה וה‑API‑ים ביישום לפני שינוי חבילות, אתחול, רישיונות או משאבי דפדפן.

הגרסה היא הצומת בדרך

שתי הדורות מתפרסמים תחת זהה חבילה זהה. רק הגרסה מבחינה ביניהם:

גרסהיעדAPI
26.7.0 ומטהnetstandard2.0ה‑API הקודם
26.8.0 ומעלהnetstandard2.1ה‑API הנוכחי

העלאת מספר הגרסה היא השדרוג. אין חבילה נפרדת להתקנה ואין שכבת התאמה — 26.8.0 הוא משטח API שונה. צפו לשגיאות קומפילציה אחרי העלאה; שאר המדריך הוא רשימת השגיאות.

איזו אינטגרציה אתם משתמשים?

אם הפרויקט מכיל…דור
new Viewer(_cache, _accessor, ...)קודם
viewer.OpenDocument(...) (synchronous)קודם
viewer.InitCache()קודם
UseDoconut(new DoconutOptions { ... })קודם
UseDoconutWebFarm(...) / WebFarmOptionsקודם
Viewer.DoconutLicense(...) or Viewer.SetLicensePlugin(...)קודם
viewer.Converter.GetConverter()קודם
using Doconut.Configs; / using Doconut.Models;קודם
Manually copied docViewer.js, documentLinks.js, or docViewer.UI.jsקודם
builder.Services.AddDoconut(...)נוכחי
app.UseDoconutResources() plus app.UseDoconut() with no argumentsנוכחי
Viewer supplied by dependency injectionנוכחי
await viewer.OpenDocumentAsync(...)נוכחי

אם שני העמודות מופיעות באותו יישום, יש להתייחס למיגרציה כחסרה. אל תשלחו אסימון מסמך אחד דרך משאבים או middleware מהדור השני.

בדקו תחילה את מסגרת האחסון

זהו שער קשוח, לא העדפה. החבילה הנוכחית ממקדת netstandard2.1:

סביבהיכול לצרוך 26.8.0
.NET Core 3.0 ומעלה (כולל .NET 5/6/7/8)כן
.NET Framework, כל גרסהלא

.NET Framework אינו יכול להתייחס לספריית netstandard2.1. אם היישום רץ על .NET Framework, עצרו כאן והשתמשו בחבילה Doconut.NETFramework במקום; החל מ‑26.9.0 היא דורשת .NET Framework 4.7.2. שני יישומי ההפניה עבור גרסה זו ממקדים net8.0.

לפני המיגרציה

  1. צור סניף וגיבוי ניתנת לפריסה של היישום הקיים.
  2. תעד את גרסאות החבילות הליבה והתוספים המדויקות.
  3. ערוך רשימה של כל קריאת new Viewer(...), קריאת InitCache(), קריאת טעינת רישיון, מיפוי UseDoconutWebFarm, בקרת המרה, סקריפט Doconut שהועתק, פעולה מותאמת של סרגל כלים, קריאת חזרה של Viewer, ונקודת קצה של פתיחת מסמך.
  4. שמר את קבצי .lic הנוכחיים וסודות הפריסה מחוץ לבקרת גרסאות.
  5. אסוף סט מייצג של מסמכי PDF, Office, תמונות, CAD, אימייל, DICOM, ניתנים לחיפוש, מוגנים בסיסמה ומעוררים הערות.
  6. תעד את זמן קציית הסשן הקיים, התנהגות האבטחה, הגופנים והגדרות הפלטפורמה.

העבר סביבה אחת לפני שינוי הייצור. האינטגרציה הנוכחית משנה את חיי השירות, ניתוב הבקשות, בעלות הסשן, אספקת משאבי הלקוח, ו—אם אתם מריצים חווה—איך הדפים מגיעים לדפדפן בכלל.

1. מרחבי שמות: כמעט הכל הועבר לשורש

סוגי ההגדרה היו מפוזרים על פני ארבעה מרחבי שמות. כעת כולם נמצאים ב‑Doconut.

לפניעכשיו
using Doconut.Configs.View;using Doconut;
using Doconut.Models;using Doconut;
using Doconut.Configs;using Doconut;
using Doconut.Configs.Cloud;using Doconut.Clouds;
using Doconut.Configs.Conversion;לא השתנה
using Doconut.Middleware;לא השתנה

השמות הסוגים לא השתנו: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, CloudUploadConfig, AzureConfig, CDNConfig, FileShareConfig והיתר עדיין קיימים. ברוב הקבצים העריכה כולה היא מחיקת שתי שורות using.

Doconut.Configs.Editor (BaseConfigEditor, PdfConfigEditor) הוסר ואין לו החלפה בחבילה זו. אם היישום שלכם השתמש באותם סוגים, תכננו חלק זה בנפרד ואל תחשבו זאת כחלק מהמיגרציה.

2. התאמת חבילה ורישיון

החלף או עדכן את חבילת הליבה במכוון; אל תסתמך על מזהה החבילה המזהה לבחירת ה‑API החדש. הפקודה המוגדרת כברירת מחדל מתקינה את הגרסה היציבה האחרונה:

bash
dotnet add package Doconut.NETStandard

להגירה ניתנת לשחזור לגרסה שנבדקה על‑ידי מדריך זה, העבר את הגרסה כאופציה נפרדת:

bash
dotnet add package Doconut.NETStandard --version 26.8.0

שמור שכל תוסף של Doconut באותה גרסה כמו חבילת הליבה — Doconut.NETStandard.Converter ו‑Doconut.NETStandard.Dicom. האינטגרציה הנוכחית טוענת רישיונות פעם אחת במהלך AddDoconut(), תוך שימוש בסדר עדיפויות זה:

text
LicenseStream > LicenseContent > LicensePath > automatic discovery

גילוי אוטומטי מחפש קבצים Doconut.Viewer.lic ו‑Doconut.Viewer.<Capability>.lic. הקריאות הסטטיות הקודמות Viewer.DoconutLicense(...) ו‑Viewer.SetLicensePlugin(...) אינן מנגנון אתחול נוכחי, וגם רשימת List<string> של נתיבי רישיון שהקונסטרוקטור הישן של Viewer קיבל אינה רלוונטית. העבר את הרישיון ל‑DoconutOptions, שמור קבצים נלווים יחד כאשר משתמשים בגילוי אוטומטי, הפעל מחדש לאחר שינוי רישיון, ואמת יכולות דרך IDoconutLicenseService.

אל תניח שהימצאות רישיון תוסף ישן מוכיחה זכאות לבנייה נוכחית של התוסף. בדוק את Viewer, Search, Annotation, Converter, ו‑DICOM בנפרד עם artefacts המהדורה המאושרת.

3. אתחול והזרקת תלויות

לפני כן הצופה נבנה לכל בקשה והאפשרויות הועברו ל‑middleware:

csharp
// אינטגרציה קודמת — רק ניגוד; אל תקומפל זאת נגד ה‑SDK הנוכחי.
var viewer = new Viewer(_cache, _accessor);
// …
appBranch.UseDoconut(new DoconutOptions { UnSafeMode = false, ShowDoconutInfo = false });

האינטגרציה הנוכחית רושמת את Doconut פעם אחת ומקבלת Viewer מהזרקת תלויות:

csharp
builder.Services.AddDoconut(options =>
{
    options.UnsafeMode      = false;   // שים לב לשינוי האיות: UnSafeMode → UnsafeMode
    options.ShowDoconutInfo = false;
    options.LicensePath     = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // מצבי סשן דורשים מטמון (MVC/Razor Pages כבר מוסיפים אחד)
builder.Services.AddSession();

app.UseSession();
app.UseDoconutResources();
app.UseDoconut();

Viewer הוא שירות זמני. מנהל סשן המסמכים והמטמון שלו מחזיקים את מצב המסמך בעל החיים הארוך יותר, ולא את המופע המוזרק של Viewer.

שלושה דברים שיש להעביר:

  • new Viewer(cache, accessor) נעלם. הזרק Doconut.Viewer לבקר שלך, או השתמש ב‑@inject Doconut.Viewer Viewer בתצוגת Razor.
  • UseDoconutResources() מחליף חיבור ידני של app.UseMiddleware<EmbeddedResourceMiddleware>(), וחייב לרוץ לפני הענף של המסמך.
  • UnSafeMode → UnsafeMode. שינוי של תו אחד שהקומפיילר יתפוס.

כאשר UnsafeMode הוא false ה‑SDK מאמת את אסימון הסשן מול הבקשה המקורית, ולכן AddSession() / UseSession() חייבים עדיין להיות בצינור, UseSession() לפני הענף.

שיטות שכבר אינן קיימות

לפניכעת
viewer.OpenDocument(path, config, options)await viewer.OpenDocumentAsync(path, config, options)
viewer.InitCache()הוסר — אין שום דבר לחמם ידנית; מחק את הקריאה וכל דגל "האם כבר אתחולתי?" סביבו
viewer.ExportToPng(sharedPath)ראה §7
viewer.ExportToCloud(cloudConfig)ראה §7
using var v = new Viewer(...); v.CloseDocument(t)viewer.CloseDocument(token) על המופע המוזרק

4. Middleware וניתוב משאבים

UseDoconut() אינו מקבל כעת ארגומנטים. צורת הענף MapWhen עצמה אינה צריכה שינוי — רק ה‑middleware בתוכו:

csharp
app.UseDoconutResources();   // לפני הענף

app.MapWhen(
    ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
    branch => branch.UseDoconut());

בצינור הנוכחי:

  1. קרא UseSession() לפני Doconut כאשר אבטחת הסשן מופעלת;
  2. קרא UseDoconutResources() לפני UseDoconut();
  3. שמור ResourcesPath, כתובות ה‑URL של המשאבים שנוצרו, ו‑ResPath של הלקוח מתואמים;
  4. שמור את הענף שאתה ממפה ואת BasePath של הלקוח מתואמים.

MiddlewarePath הוא תצורת אימות; הוא אינו יוצר ענף של ASP.NET Core בעצמו.

5. בניית מציג ותוחלת חיים

הסירו מטמוני יישום של אובייקטי Viewer. אין מה לשמור ב‑Viewer: הוא אינו נושא מצב מסמך, ומטמון הסשן מחזיק בכל מה שממשיך אחרי בקשה. הזריקו אותו לנקודת קצה, דף Razor, בקר, או שירות יישום בעל תחום:

csharp
app.MapPost("/api/open", async (Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
    return Results.Ok(new { token });
});

הטוקן שהוחזר מזהה סשן מסמך בצד השרת. התייחסו אליו כאל אישור נושא: אל תתעדו אותו, אל תשמרו אותו, ואל תציבו אותו בניתוחים.

6. פתיחה וסגירת מסמכים

החליפו את OpenDocument(...) הסינכרוני ב‑OpenDocumentAsync(...):

csharp
// אינטגרציה נוכחית: Viewer מגיע מ‑DI ופתיחת המסמך היא אסינכרונית.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

הגרסאות הנוכחיות מקבלות נתיב קובץ או זרם, תצורת פורמט אופציונלית, DocOptions אופציונלי, וטוקן ביטול. סגרו את סשן השרת במפורש כאשר הדפדפן אינו זקוק לו יותר:

csharp
viewer.CloseDocument(token);

מחקו כל קריאה ל‑InitCache() ואת הדגל המגן עליו — אין מה לחמם ידנית. אל תשתמשו מחדש בטוקן שנוצר על‑ידי הספרייה הקודמת לאחר המעבר: פתחו כל מסמך מחדש דרך ה‑API הנוכחי.

7. Web farm → distributed: השינוי הגדול ביותר

UseDoconutWebFarm ו‑WebFarmOptions אינם קיימים יותר. אם האפליקציה שלכם קוראת להם, סעיף זה הוא השדרוג שלכם; אם לא, דלגו ל‑§8.

בעבר middleware אחד עשה את כל העבודה: הוא שירת תמונות קודמות שנוצרו מתיקייה משותפת, ו‑סקר בזמן שמ node אחר עדיין כתב אותן.

csharp
// אינטגרציה קודמת — קריאה אחת, תיאום בלתי מפורש דרך מערכת הקבצים.
appBranch.UseDoconutWebFarm(new WebFarmOptions
{
    Path                = Path.Combine(env.WebRootPath, "webfarm"),
    PageWaitTimeSeconds = 180,
    StartWaitFromPage   = 5,
});

העבודה אותה היום מחולקת לשניים מפורשים. צד הכתיבה — ה‑node שפותח את המסמך מפרסם את כל קבוצת הארטיפקטים (דפים, מידע על המסמך, אינדקס חיפוש, מטא‑דטה) לשיתוף:

csharp
var result = await _publisher.PublishAsync(          // DistributedDocumentPublisher, מוזרק מ‑DI
    pathToFile,
    new FileShareConfig
    {
        Location              = CloudLocation.FileShare,
        RootPath              = @"\\fileserver\doconut",   // אותה תיקייה שאתה משתמש בה היום
        UsePerTokenSubfolders = true,
    },
    config,
    documentOptions,
    new DistributedDocumentPublishOptions
    {
        CleanUpStagingDirectory = true,
        FirstPagePriority       = true,
    });

return Content(result.Token);

צד הקריאה — כל node משמש מהשיתוף:

csharp
app.MapWhen(
    ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
    branch => branch.UseDoconutCloud<FileShareCloudHandler>(options =>
    {
        options.Location          = CloudLocation.FileShare;
        options.CloudUploadConfig = /* אותו FileShareConfig כמו למעלה */;
    }, "/"));
לפניעכשיו
WebFarmOptions.PathFileShareConfig.RootPath
PageWaitTimeSeconds / StartWaitFromPageהוסר — מוחלף ב‑FirstPagePriority בצד הכתיבה ועוד FileShareConfig.ReadReadyPollMs בצד הקריאה
viewer.OpenDocument(...) ואז viewer.ExportToPng(share)קריאה אחת ל‑PublishAsync(...)
DocOptions.IsWebfarm / WebfarmPathעדיין קיים, כתוב IsWebFarm / WebFarmPath — אך אינו נדרש בנתיב הפרסום

הטופולוגיה שלכם אינה משתנה. הפנו את RootPath לאותו שיתוף UNC וכל node ממשיך לעבוד כפי שהוא היום. מה שמשתנה הוא שהפרסום הוא פעולה שאתם קוראים לה, במקום להיות תופעת לוואי של רינדור.

שני החצאים חייבים להסכים. אם RootPath או UsePerTokenSubfolders שונים בין המפרסם למטפל, ה‑node השני יחזיר 404. בנו את ההגדרה בעוזר אחד וקראו לה משני הצדדים.

PageWaitTimeSeconds = 180 משמעותו "חסימה עד שלוש דקות בתקווה שהדף יופיע". ההחלפה היא מפורשת: עם FirstPagePriority = true, דף 1 ניתן לשירות מיידית והדפים הבאים משיבים HTTP 202 Accepted עד שהם נכתבים. המציג המשולב מנסה מחדש אוטומטית כאשר retryOn409 מוגדר. לקוח שאינו מנסה מחדש יציג אריחים שבורים עבור דפים שעדיין מתרנדים.

הסידור המלא, כולל פרסום ברקע וכרטיסי גישה, נמצא ב‑פריסות מבוזרות.

8. המרה היא תוסף, וקטנה הרבה יותר

רשום את התוסף, ואז הזרק את המעטפת DocumentConverter:

csharp
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());
csharp
// אינטגרציה קודמת
var converter = viewer.Converter.GetConverter();
var config    = new WordConfigConverter { TargetFormat = WordConfigConverter.EnTargetFormat.PDF };
var result    = converter.Convert(stream, SourceFormatConverter.DOCX, config);

// אינטגרציה נוכחית
var result = await _converter.ConvertAsync(stream, ".docx", ConversionTarget.Pdf, null, ct);

מה זה מחליף:

  • SourceFormatConverter — הוסר. העבר את סיומת הקובץ כמחרוזת, כולל הנקודה.
  • סוגי *ConfigConverter לכל משפחה (WordConfigConverter, ExcelConfigConverter, …), שכל אחד כולל EnTargetFormat פנימי — הוסר. כעת יש Enum יחיד ConversionTarget לכל משפחה.
  • viewer.Converter.GetConverter() — הוסר. הזרק Doconut.DocumentConverter.

ConvertAsync מחזיר זרם שניתן לחיפוש, ולכן return File(result, mime, name) עובד ישירות — העתקת MemoryStream שהקוד הישן דרש אינה נדרשת. בדוגמה המשולבת זה מחק החלפה של 68 מקרים של סיומות ועשר בקרים כמעט זהים.

ראו את תוסף הממיר לקבלת המידע המלא.

9. ספקי ענן

UseDoconutCloud הפך לגנרי. הספק הוא ארגומנט הסוג במקום ערך Location שמוחלף בתוך ה‑middleware:

csharp
// אינטגרציה קודמת
appBranch.UseDoconutCloud(new CloudOptions { Location = CloudLocation.CDN, ... });

// אינטגרציה נוכחית
branch.UseDoconutCloud<CDNCloudHandler>(options =>
{
    options.Location          = CloudLocation.CDN;
    options.CloudUploadConfig = new CDNConfig { DoconutCdnUrl = "..." };
}, "/");

מחלקות הקונפיגורציה נשארות ללא שינוי פרט למרחב השמות (Doconut.Configs.Cloud → Doconut.Clouds): AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig, וכן FileShareConfig החדש. המטפלים נקראים <Provider>CloudHandler.

מטפל ה‑CDN הוא קריאה‑לקריאה בלבד — הוא מגיש את מה שכבר נמצא ב‑CDN; הוא אינו מעלה קבצים.

10. אובייקטי תצורה ששונו שם

לפניעכשיו
DoconutOptions.UnSafeModeUnsafeMode
DocOptions.IsWebfarmIsWebFarm
DocOptions.WebfarmPathWebFarmPath
DocOptions.ImageResolutionעדיין קיים אך מיושן — קבע רזולוציה בתצורת הפורמט במקום

DocOptions גם מקבל IsSecured.

ה‑API הנוכחי גם מפריד תחומי אחריות בצורה קפדנית יותר מהקודם, ולכן יש לוודא שכל הגדרה נמצאת באובייקט שכעת בעליה:

נושאסוג נוכחי
נתיבי Middleware, רישוי, רישום תוספיםDoconutOptions
סיסמה, זמן קצוב, אבטחה, סימן מיםDocOptions
רינדור פורמט ו‑DPIPdfConfig, WordConfig, ExcelConfig, וסוגי BaseConfig אחרים
ברירות מחדל של וידג'ט הדפדפןViewerConfig או אפשרויות JavaScript המקבילות
CSS ו‑scripts שנוצרוCssConfig ו‑ScriptConfig
אחסון משותף וספקי ענןFileShareConfig והקונפיגורציות האחרות של Doconut.Clouds

אל תעבירו את DocOptions.ImageResolution כהגדרת רינדור. הוא מיושן; קבעו BaseConfig.ImageResolution בתצורת הפורמט הספציפית. עברו על כל ברירות המחדל במקום להניח שהקונפיגורציה הקודמת מתנהגת זהה.

11. מציג צד‑לקוח — שני שינויים שנכשלים בשקט

שניהם משאירים את השרת פועל בצורה מושלמת. המסמך שלכם מוצג, הדף נראה נכון, ולא מופיע דבר בקונסול הדפדפן. קראו סעיף זה גם אם הקומפילציה של C# מצליחה בפעם הראשונה.

קריאות חזרה של מציג הן אפשרויות כעת, ולא פונקציות גלובליות

המציג הקודם קרא למטפלים שלכם בשם, וגזר את שם הפונקציה הגלובלית ממזהה המכולה. הצהרת function ctlDoc_OnViewerReady() בעמוד עם <div id="div_ctlDoc"> הייתה מספיקה. המציג הנוכחי מקבל קריאות חזרה מפורשות באובייקט האפשרויות ואינו מחפש יותר את הפונקציות הגלובליות:

javascript
objctlDoc = $("#div_ctlDoc").docViewer({
    // ... your existing options ...
    onViewerBusy:     ctlDoc_OnViewerBusy,      // was found by name
    onViewerReady:    ctlDoc_OnViewerReady,     // was found by name
    onCopy:           ctlDoc_Copy,              // was ctlDoc_Copy(text)
    onAutoLoadStatus: ctlDoc_AutoLoadStatus     // was ctlDoc_AutoLoadStatus(page)
});

למה זה בעייתי: הקריאה הישנה הייתה עטופה ב‑catch ריק, שספג את כל השגיאות. עכשיו הפונקציות שלכם פשוט אינן רצות ולא מדווחת שום שגיאה. התסמין הרגיל הוא ספינר עסוק שלעולם לא מפסיק — מכיוון שהפונקציה שהסתירה אותו הייתה ctlDoc_OnViewerReady. המסמך שמאחוריו תקין.

רשימת האפשרויות המלאה היא onPageLoading, onPageLoaded, onThumbnailClicked, onPageClicked, onDoubleClick, onViewerBusy, onViewerReady, onViewerError, onCopy, onAnnSaved, onAnnSaveError, onAnnLoaded, onAnnClosed, onAutoLoadStatus, onThumbsShown, ו‑onError. אין קריאת חזרה ללחיצה על קישור: טיפול בקישורים היפר-טקסט מובנה, מנוהל על‑ידי showHyperlinks.

ResPath חייב להצביע על קידומת המשאבים

javascript
ResPath: '',                      // BEFORE — לפני — המשאבים הגיעו משורש האפליקציה
ResPath: 'doconut-res/images',    // NOW    — עכשיו — הקידומת שמרכיבה UseDoconutResources()

אם שינית את הקידומת דרך DoconutOptions.ResourcesPath, השתמש בערך הזה במקום זאת.

12. סרגל כלים של Viewer, חיפוש והערות

אל תבצע מיגרציה של הסקריפטים הישנים אחד אחרי השני. היישומים הרפרנסיים הנוכחיים מרכיבים חבילה של דף שלם:

  1. לשחרר CSS של Viewer ו‑CSS מורשה של Search/Annotation באמצעות ReferenceCss;
  2. להציג את סרגל הכלים של Viewer שבבעלות האפליקציה;
  3. להציג את searchBarMount, annBarMount, ואת הרכיב הנדרש של Viewer;
  4. לשחרר סקריפטים של Viewer ומודולים מורשים באמצעות ReferenceScripts;
  5. לטעון את סקריפט העזר של סרגל הכלים של האפליקציה;
  6. לאתחל מופע אחד של objViewer;
  7. לאתחל את רצועות ה‑Search וה‑Annotation המורשות;
  8. להזמין attach(objViewer) על כל רצועה;
  9. לפתוח את המסמך ולהזמין objViewer.View(token).

Search ו‑Annotation הם מודולים המחוברים לאותו Viewer, ולא סרגלי כלים נפרדים. סרגל הכלים הראשי שייך לאפליקציית המארח; רצועות ה‑Search וה‑Annotation משולבות, ומשאבים המוגבלים לפי יכולות.

הסר קבצים שהועתקו ידנית כגון documentLinks.js ו‑docViewer.UI.js רק לאחר שהדף הנוכחי פועל עם המשאבים המשוחררים על‑ידי ReferenceCss ו‑ReferenceScripts.

13. רישום תוספים

שיטות רישוי תוסף סטטיות אינן רושמות תוספים נוכחיים. התקן ורשום כל חבילה משוחררת במפורש:

csharp
builder.Services.AddDoconut(options =>
{
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
    options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});

AddDoconut() מאמתת את יכולות התוספים הרשומות בעת האתחול. Converter ו‑DICOM הם התוספים המשוחררים של .NET Standard. Search ו‑Annotation הרגילים הם תכונות מורשות מובנות, ולא חבילות AddPlugin<TPlugin>().

14. אבטחת סשן ומסמך

האינטגרציה הנוכחית קושרת מסמכים לטוקנים בלתי נראים ולסשנים במטמון. עם UnsafeMode = false כברירת מחדל, UseDoconut() מוסיף אבטחת גישה למסמך והמאחסן צריך להגדיר סשן של ASP.NET:

csharp
builder.Services.AddDistributedMemoryCache(); // מצב הסשן דורש מטמון (MVC/Razor Pages already add one)
builder.Services.AddSession();
app.UseSession();

השאר DocOptions.IsSecured = true אלא אם תכנון שנבדק דורש אחרת. לעולם אל תשתמש ב‑UnsafeMode = true כקיצור מיגרציה על צומת יחיד. בדוק בקשות ללא טוקן, טוקן פגום, טוקן שפג תוקפו, וטוקן ממושב דפדפן שונה.

ב‑farm הבקשה לדף יכולה להגיע לצומת שמעולם לא ראה את הבקשה הפתיחה, ולכן בדיקת הפר‑סשן תדחה אותה. זה המקרה היחיד שבו UnsafeMode = true נכון — והוא חייב להיות משולב עם כרטיסי גישה חתומים דרך AddDoconutDistributedDocumentSecurity, ולא משוחרר לבד. ראה פריסות מבוזרות.

הערת שם

בכל המסגרות המחלקה היא Viewer. אם אתה מוצא DocumentViewer בקטעי קוד ישנים או במאמרים של צד שלישי, סוג זה מעולם לא היה קיים ב‑SDK.

15. סדר עבודה מומלץ

  1. אשר שהמסגרת המארחת יכולה לצרוך netstandard2.1. אם לא, עצור.
  2. העלה את החבילה ל‑26.8.0 ובנה. עבוד דרך שגיאות הקומפילציה — רובן הן שורות using בסעיף §1.
  3. הזז את האתחול ל‑AddDoconut() ואת קריאות ה‑middleware לסדר החדש שלהם (§3, §4).
  4. הזרק Viewer במקום שבו בנית אותו, הפוך את OpenDocument ל‑async, ומחק את InitCache() (§5, §6).
  5. אם אתה משתמש ב‑web farm, בצע §7 — החלק היחיד שהוא עיצוב מחדש ולא שינוי שם.
  6. אם אתה ממיר מסמכים, בצע §8.
  7. בצע §11 — השינויים בצד הלקוח. אלה הם אלו שלא יכריזו על עצמם.
  8. פתח מסמך אמיתי בדפדפן, וצפה במסתובב העמוס. בנייה ירוקה לא מוכיחה דבר כאן: רישוי, רישום תוספים, נתיב המשאבים, והקולבקים של ה‑viewer נכשלים רק בזמן ריצה. עבור farm, אמת שמסמך שפורסם מצומת אחד מוגש מצומת אחר.

בדיקת ההגירה

לפחות, יש לאמת:

  • הפעלת היישום עם רישיון הייצור וכל תוסף רשום;
  • קבצי CSS/סקריפטים של Viewer וכל בקשות תמונת‑דף בנתיבים שנבחרו;
  • פתיחת מסמך, ניווט, זום, תמונות ממוזערות, הדפסה וסגירה מפורשת;
  • חיפוש במסמך שמכיל טקסט והמצב הלא‑ניתן לחיפוש של קובץ שמורכב רק מתמונות;
  • טעינת, שמירת, ייצוא והגבלת תכונות של אנוטציות;
  • גילוי יעד הממיר, פלט, הורדה ומצב סימן מים;
  • דפי DICOM, פריימים ואנימציה; מטא‑נתונים טכניים אינם זמינים בחבילה זו;
  • מסמכים מוגנים בסיסמה, גופנים מותאמים, טקסט לא‑לטיני וזמני קצוב שהוגדרו;
  • דחיית אסימון בין‑הפעלות והתנהגות של הפעלה שפגה;
  • למערכת חוות: לפרסם על צומת אחת, לבקש דף מאוחר מצומת אחרת, ולאשר שה‑Viewer מנסה שוב תגובות 202 במקום להציג אריחים פגומים;
  • נייד, מצב כהה, ונתיב ה‑reverse‑proxy של הייצור.

תוכנית שחזור

יש לשמור את ארטיפקט הפריסה הקודם, החבילות המתאימות, קבצי הרישיון ומשאבי הדפדפן שהועתקו יחד. שחזור בטוח מחליף את כל דור היישום; הוא אינו מערבב שרת מדור קודם עם סקריפטים נוכחיים, או שרת נוכחי עם מקומות קריאה של new Viewer(...).

לפני המעבר, יש לתעד:

  • את משבצת הפריסה או הארטיפקט המשמשים לשחזור;
  • את השפעת האחסון המשותף, אם קיימת — ארטיפקטים שפורסמו ב‑26.8.0 אינם נצרכים על ידי תשתית ה‑web‑farm הקודמת;
  • כיצד הפעלות המסמך הפעילות יבוטלו;
  • את בדיקת הבריאות והמסמך המהיר המשמשים להחלטת שחזור;
  • מי יכול לשחזר את קבוצת החבילות והקונפיגורציה הקודמות.

תיעוד היסטורי

המדריך הקודם המתורגם עדיין זמין ב‑הגדרת .NET Standard הישנה. ה‑שער אינטגרציה קודם מסביר את אותות הזיהוי זהים ומקשר חזרה למדריך ההגירה הזה.

יש לשמור את כתובת ה‑URL ההיסטורית במועדפים ובכרטיסי התמיכה כל עוד התקנות netstandard2.0 קיימות. היא מתעדת דור שונה ולא מופנית ל‑API הנוכחי.

האם דף זה היה מועיל?