افزونه مبدل
سندها را به ۲۴ قالب هدف تبدیل کنید
افزونه مبدل Doconut را به یک سرویس تبدیل سند تبدیل میکند. این افزونه موتور پشت واسط عمومی DocumentConverter را فراهم میکند و — به صورت اختیاری — یک ویجت آماده با قرارداد HTTP خود دارد، به طوری که میتوانید اسناد را از C#، از ویجت، یا از یک فرانتاند که خودتان مینویسید، تبدیل کنید.
نصب بسته
آخرین نسخه پایدار افزونه مبدل را نصب کنید:
dotnet add package Doconut.NET8.Converterبرای قفل کردن افزونه به نسخه جاری ۲۶.۷.۰، نسخه را بهصورت جداگانه پاس دهید:
dotnet add package Doconut.NET8.Converter --version 26.7.0بسته مبدل را با همان نسخهی Doconut.NET8 نگه دارید. شناسه بسته
Doconut.NET8.Converter است؛ .26.7.0 فقط در نام فایل دانلود شدهی .nupkg ظاهر میشود.
ثبت افزونه
هیچ روش AddConverter() وجود ندارد — مدل افزونههای Doconut یکنواخت است. هر افزونهای، از جمله مبدل، به همان روش ثبت میشود: داخل AddDoconut()، AddPlugin<TPlugin>() را فراخوانی کنید. ConverterPlugin در بسته NuGet خود، Doconut.NET8.Converter، همراه با بسته پایهی نمایشگر نصب میشود.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});این فراخوانی در زمان راهاندازی به دلیل عدم وجود لایسنس، فایل قدیمی
TRIAL، یا لایسنس غیر موقت که قابلیتConverterرا اعطا نمیکند، خطا میاندازد — یکInvalidOperationExceptionکه از داخلAddDoconut()ایجاد میشود، قبل از این که برنامه درخواستها را سرویس دهد. ثبتنامهای موقت Demo/NFR پذیرفته میشوند؛ پس از انقضای تقویمی آنها، تبدیل همچنان با خروجی دارای واترمارک در دسترس است. هیچ لایه رایگان ساکتی وجود ندارد. برای نحوه بارگذاری لایسنسها، به License Setup مراجعه کنید.
تبدیل از C#
هر تبدیل یک MemoryStream قابل جستجو که در موقعیت ۰ قرار دارد، برمیگرداند که بلافاصله آماده خواندن یا کپی شدن است. DocumentConverter را از DI در هر جایی که نیاز دارید حل کنید — این شیء بهصورت بدون حالت طراحی شده است، بنابراین یک نمونهی واحد میتواند بهصورت ایمن در درخواستهای مختلف دوباره استفاده شود.
// DocumentConverter را تزریق کنید؛ سازندهٔ آن داخلی است، بنابراین هرگز `new` آن را انجام ندهید.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension شامل نقطهٔ پیشرو است. password برابر null است مگر اینکه سند محافظت شده باشد.
Stream png = await converter.ConvertAsync(upload, ".xlsx", ConversionTarget.Png, password: null, ct: ct);Stream html = await converter.WordToHtmlAsync("report.docx", ct);Stream docx = await converter.HtmlToWordAsync(html, ConversionTarget.Docx, ct);دو نکتهای که بهراحتی میتوان اشتباه کرد: sourceExtension در overload استریم باید نقطهی پیشرو را شامل شود (".xlsx"، نه "xlsx") — مبدل آن را با کاتالوگ فرمت مقایسه میکند و یک پسوند ساده حل نمیشود. و با وجود نامش، WordToHtmlAsync مقدار Task<Stream> را برمیگرداند، نه Task<string> — شما سند HTML (تصاویر بهصورت Base64 جاسازی شده) را بهعنوان یک استریم دریافت میکنید، همانند هر نتیجهی تبدیل دیگر.
قالبهای هدف
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webpهر منبع به هر هدف تبدیل نمیشود — افزونه خانوادهی فرمت هر منبع (Word، Excel، PowerPoint، PDF، CAD، Image، Email، Diagram، Project/Task، PSD، سند وب) را به مجموعه ثابت هدفهای مجاز خود نگاشت میکند. این enum را بهعنوان لیست هدفهای UI خود بهصورت ثابت کدنویسی نکنید: ?convert=open مقدار واقعی allowedTargets را برای فایلی که تازه بارگذاری شده است برمیگرداند و این باید منبع انتخابکننده باشد.
ویجت Drop‑in
نقطههای انتهایی ?convert=open|run|download ویجت بهصورت انتخابی هستند و بهطور پیشفرض غیرفعالاند — بهصورت پیشفرض ایمن. آنها را در سمت سرور فعال کنید، بههمراه ثبتنام افزونه:
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddConverterWidget(widget =>
{
widget.MaxUploadMb = 25;
});
});<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/doconut', resPath: '/doconut-res', maxUploadMb: 25 });
</script>بدون AddConverterWidget()، سه نقطهٔ انتهایی ?convert= پاسخ 404 میدهند — اما فایل JS خود همچنان سرو میشود (یک منبع ایستاتیک سادهٔ جاسازیشده؛ فقط نقطههای انتهایی که به آنها مراجعه میکند محدود شدهاند). AddConverterWidget() همچنان نیاز به ثبتنام افزونهٔ Converter و مجوزی که Converter را اعطا کند دارد — این مجوز بهتنهایی حق تبدیل را نمیدهد.
سفارشیسازی ویجت
گزینههای اولیهای که به Doconut.convert(selector, options) پاس داده میشوند:
| گزینه | نوع | پیشفرض | یادداشتها |
|---|---|---|---|
basePath | string | /doconut | مسیر پایه برای نقطههای انتهایی ?convert=؛ باید با شاخه ASP.NET که در آن UseDoconut() واقعاً سوار شده است مطابقت داشته باشد (معمولاً از طریق MiddlewarePath هماهنگ میشود) |
resPath | string | /doconut-res | برای سازگاری پیکربندی با سایر ویجتهای Doconut پذیرفته شده است؛ ویجت مبدل در حال حاضر هیچ URLای از آن نمیسازد |
maxUploadMb | number | 25 | فقط بررسی پیشنگار در سمت کلاینت — قبل از بارگذاری، فایل بزرگتری را رد میکند. سرور بهصورت مستقل سقف خود را اعمال میکند و اگر تجاوز شود، پاسخ 413 میدهد |
licenseUrl | string | null | null | هنگامی که تنظیم شود، اعلان واترمارک در صفحهٔ نتیجه را به لینکی به این URL تبدیل میکند |
labels | object | {} | هر زیرمجموعهای از رشتههای پیشفرض انگلیسی ویجت (متن کشیدن، دکمهها، اعلانهای aria‑live، پیامهای خطا) را بازنویسی میکند |
بازخوانیها:
| بازخوانی | زمان اجرا | داده |
|---|---|---|
onReady() | ویجت صفحهٔ بیکار/کشیدن خود را رندر کرده است | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open موفق میشود | توکن نشست منبع، تعداد صفحات، پسوند منبع (بدون نقطهٔ پیشرو)، لیست هدفهای مجاز |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run موفق میشود | همان فیلدها همانند پاسخ اجرا، بهاضافهٔ target درخواستشده |
onDownload({ downloadName, downloadToken }) | کاربر بر لینک دانلود کلیک میکند | بههمراه دانلود بومی مرورگر اجرا میشود — آن را رهگیری یا جایگزین نمیکند |
onError({ phase, message }) | یک درخواست باز یا اجرا شکست میخورد | phase برابر است با 'open' یا 'run'؛ message خطای سرور تمیزشده است (یا پیام سمت کلاینت برای بررسی پیشنگار اندازه بارگذاری) |
Doconut.convert() نمونهٔ ویجت را خود باز میگرداند — آن را نگه دارید تا ویجت را بهصورت برنامهنویسی کنترل کنید:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // بازگشت به صفحه idle/drop؛ onReady دوباره فراخوانی نمیشود
conv.loadFile(file); // جریان را با یک شیء File شروع میکند؛ no‑op مگر اینکه در حال حاضر idle باشد
conv.destroy(); // listenerها را حذف میکند، mount را خالی میکند؛ پس از این نمونه قابل استفاده نیستساخت رابط کاربری خودتان
ویجت صرفاً یک کلاینت برای این قرارداد HTTP است — میتوانید رابط کاربری خود را مستقیماً بر پایهٔ آن بسازید تا تجربهٔ کاربری متفاوتی داشته باشید. هر سه مسیر زیر شاخهٔ ASP.NET که در آن UseDoconut() سوار شده است (معمولاً /doconut) قرار دارند:
| مسیر | هدف | پاسخ موفقیت |
|---|---|---|
POST ?convert=open (multipart, field file) | بارگذاری و باز کردن یک سند منبع برای پیشنمایش | 200 — { token, pages, sourceExt, allowedTargets } |
POST ?token=<token>&convert=run&target=<ext> | تبدیل منبع ذخیرهشده به target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET ?convert=download&token=<downloadToken> | پخش فایل تبدیلشده | 200 — بایتهای فایل، Content-Disposition: attachment، Cache-Control: no-store |
بایتهای منبع بارگذاریشده بهصورت سروری با TTL 30 دقیقهای ذخیره میشوند؛ پس از پایان این بازه، run پاسخ 404 میدهد و فایل باید دوباره باز شود. نتیجهٔ تبدیلشده در همان مخزن زندگی میکند — downloadToken پس از تکمیل تبدیل، بازهٔ تازهٔ 30 دقیقهای خود را دریافت میکند — در حالی که resultToken یک توکن نشست معمولی ویور است که طول عمر آن مطابق کش نشست ویور است، مستقل از مخزن.
sourceExt در پاسخ open نقطهٔ پیشرو ندارد (مثلاً "docx") — بر خلاف قرارداد پارامتر sourceExtension در DocumentConverter.ConvertAsync که نیاز به نقطه دارد.
حالتهای شکست، گروهبندیشده بر حسب مسیر:
| مسیر | وضعیت | زمان | بدنه |
|---|---|---|---|
| هر | 404 | ویجت فعال نیست (AddConverterWidget() هرگز فراخوانی نشده است) — قبل از ارسال هر یک از سه مسیر بررسی میشود | فقط وضعیت |
| هر | 405 | روش HTTP نادرست (open/run به POST نیاز دارند؛ download به GET نیاز دارد) | فقط وضعیت |
open | 413 | فایل بارگذاریشده از MaxUploadMb تجاوز میکند | { "error": "File is too large." } |
open | 400 | بدنهٔ multipart وجود ندارد، فایل نیست، یا پسوند منبعی که قابل تبدیل نیست | { "error": "..." } |
run | 400 | توکن خراب (نه GUID)، یا target که به ConversionTarget تجزیه نمیشود | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | target در allowedTargets منبع وجود ندارد | { "error": "That target format is not available for this file." } |
run | 404 | بارگذاری ذخیرهشده منقضی شده است (TTL 30 دقیقه) یا توکن هرگز باز نشده است | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | پردازش بهصورت داخلی شکست خورده است | { "error": "<sanitized message>" } — به همان شیوه سایر مسیرهای خطای Doconut تمیز شده؛ هرگز نامهای داخلی موتور را فاش نمیکند |
download | 400 | توکن خراب (نه GUID) | فقط وضعیت |
download | 404 | توکن دانلود ناشناخته یا منقضی شده | فقط وضعیت |
مالکیت منبع
مبدل یک MemoryStream قابل جستجو که در صفر موقعیت دارد برمیگرداند. صدا کننده مالک این جریان است و باید پس از کپی یا بازگرداندن محتویات آن، آن را آزاد کند. سرویس DocumentConverter خود بدون حالت است و از تزریق وابستگی حل میشود؛ سرویس را بهصورت دستی ساخت یا آزاد نکنید.
برای ویجت وب، مخازن بارگذاری و دانلود TTLهای مستقل 30‑دقیقهای دارند. یک resultToken نمایشگر بهجای آن، طول عمر جلسه نمایشگر را دنبال میکند. بستن نتیجهٔ نمایشگر مخزن دانلود هنوز معتبر را حذف نمیکند، و بازنشانی ویجت مرورگر هیچیک از TTLها را تمدید نمیکند.
عیبیابی
| علائم | بررسی |
|---|---|
شکست در حل DocumentConverter | ثبت ConverterPlugin داخل AddDoconut() رخ داد |
| برنامه در هنگام راهاندازی شکست میخورد | مجوز بارگذاریشده Converter را اعطا میکند |
| تبدیل جریان میگوید قالب پشتیبانی نمیشود | sourceExtension شامل نقطهٔ پیشرو است |
| جاوااسکریپت ویجت بارگذاری میشود اما درخواستها 404 برمیگردانند | AddConverterWidget() فراخوانی نشد |
| درخواستهای ویجت از URL اشتباه استفاده میکنند | basePath با شاخهای که UseDoconut() در آن نگاشته شده مطابقت دارد |
| هدف موجود نیست | از allowedTargets که توسط convert=open برگردانده شده استفاده کنید؛ هر منبع همهٔ هدفهای enum را پشتیبانی نمیکند |
| دانلود منقضی شده | دوباره convert=open/convert=run را انجام دهید؛ توکنهای مخزن عمداً موقت هستند |
واترمارکگذاری
با ثبت ConverterPlugin، مجوز میزبان در یکی از سه وضعیت زیر است:
| وضعیت مجوز | دروازهٔ راهاندازی | خروجی تبدیل |
|---|---|---|
مجوز نمایشگر پرداختشده که Converter را اعطا میکند، در دورهٔ اعتبار خود | عبور میکند | تمیز — watermarked: false |
| مجوز ارزیابی فعال (دمو/NFR) | عبور میکند | با موفقیت تبدیل میشود، با واترمارک ارزیابی — watermarked: true مهر میشود |
بدون مجوز، فایل قدیمی TRIAL، یا مجوز غیر موقت که Converter را اعطا نمیکند | برنامه هرگز شروع نمیشود — دروازهٔ راهاندازی که در بالا توضیح داده شد استثنا میاندازد | — |
| مجوز موقت/دموی منقضیشده | ثبت پس از انقضا باقی میماند | با واترمارک ارزیابی تبدیل میشود — watermarked: true |
هر دو مسیر فراخوانی پرچم را از همان قانون محاسبه میکنند: واسط C# DocumentConverter آن را بهصورت داخلی از وضعیت IsViewerLicensed و IsTemporary مجوز استخراج میکند، و هندلر ?convert=run ویجت بررسی معادل (IsViewerLicensed && !IsTrial && !IsTemporary) را انجام میدهد تا فیلد watermarked را که برمیگرداند پر کند. یک یکپارچهسازی میتواند بر روی یک مجوز ارزیابی قبل از خرید ساخته و بهصورت سرتاسری تست شود — فقط بایتهای خروجی تغییر میکنند.
آیا این صفحه مفید بود؟