«... مدتی است یک سرویس مبتنی بر هوش مصنوعی تازه به نام NotebookLM توسط گوگل در اختیار کاربران قرار گرفته که کاربردهای متعددی دارد. یکی از مهمترین کاربردهای آن، برای افرادی است که با منابع علمی و پژوهشی متعدد سر و کار دارند. شما میتوانید کتابها و فایلهای پی دی اف خودتان را در NotebookLM آپلود کنید. سپس هر پرسشی که داشتید، مطرح کنید تا بر اساس منابع آپلود شدهی خودتان به آنها پاسخ داده شود...»
نظرات مطالب
دریافت کتاب از Google books
اگر خواستید قسمتی از کتاب را از گوگل دریافت کنید و یا فصلی از کتاب و یا همه آن،راه حل ساده آن اینست که وارد temporary مرورگر شود(جایی که اطلاعات کش مرورگر ذخیره میشود و بعد از مدتی پاک می شود).و آن را در قالب تصویر دریافت کنید.
تازه می توانید کیفیت کتاب را هم مشخص کنید،به این دلیل که زوم کتاب سمت سرور می باشد،کیفت و حجم آن هم قابل تنظیم می باشد.
در ضمن در یاد داشته باشید که هر فایلی که بخواهد در مرورگر به نمایش در بیاید،قابل ذخیره کردن است D:
تازه می توانید کیفیت کتاب را هم مشخص کنید،به این دلیل که زوم کتاب سمت سرور می باشد،کیفت و حجم آن هم قابل تنظیم می باشد.
در ضمن در یاد داشته باشید که هر فایلی که بخواهد در مرورگر به نمایش در بیاید،قابل ذخیره کردن است D:
همانطور که در مطلب قبلی گفتم، در این مطلب قرار است به WAS بپردازیم؛ در دنباله متن قبلی گفتیم که دومین وظیفه WWW Service این است: موقعیکه یک درخواست جدید در صف درخواستها وارد شد، به اطلاع WAS برساند.
WAS یا Windows Process Activation Service
در نسخه 7 به بعد، WAS مدیریت پیکربندی application pool و پروسههای کارگر را به جای WWW Service به عهده گرفته است. این مورد شما را قادر میسازد تا همان پیکربندی که برای Http در نظر گرفتهاید، بر روی درخواست هایی که Http نیستند هم اعمال کنید. همچنین موقعی که سایت شما نیازی به درخواستهای Http ندارد میتوانید WAS را بدون WWW Service راه اندازی کنید. به عنوان یک مثال فرض کنید شما یک وب سرویس WCF را از طریق WCF Listener Adapter مدیریت میکنید و احتیاجی به درخواستهای نوع Http listener ندارید و http.sys کاری برای انجام ندارد پس نیازی هم به راه اندازی www service نیست.
پیکربندی مدیریتی در WAS
در زمان شروع کار IIS، سرویس WAS اطلاعاتی را از فایل ApplicationHost.config میخواند و آنها را به دست listener adapterهای مربوطه میرساند و lsitener adapterها ارتباط بین WAS و listenerهای مختلف را در IIS، برقرار میکنند. آداپتورها اطلاعات لازم را از WAS میگیرند و به listenerهای مربوطه انتقال میدهند تا listenerها بر اساس آن تنظیمات یا پیکربرندیها، به درخواستها گوش فرا دهند.
در مورد WCF ، ابتدا WAS تنظیمات را برای آداپتور WCF که NetTcpActivator نام دارد ارسال کرده و این آداپتور بر اساس آن listener مربوطه را پیکربندی کرده تا به درخواست هایی که از طریق پروتوکل net.tcp میرسد گوش فرا دهد.
لیست زیر تعدادی از اطلاعاتی را که از فایل پیکربندی میخواند و ارسال میکند را بیان کرده است:
- Global configuration information
- Protocol configuration information for both HTTP and non-HTTP protocols
- Application pool configuration, such as the process account information
- Site configuration, such as bindings and applications
- Application configuration, such as the enabled protocols and the application pools to which the applications belong
نکته پایانی اینکه اگر فایل ApplicationHost.config تغییری کند، WAS یک اعلان دریافت کرده و اطلاعات آداپتورها را به روز میکند.
مدیریت پروسهها Process Managment
گفتیم که مدیریت پول و پروسههای کارگر جزء وظایف این سرویس به شمار میرود. موقعی که یک protocol listener درخواستی را دریافت میکند، WAS چک میکند که آیا یک پروسه کارگر در حال اجراست یا خیر. اگر application pool پروسهای داشته باشد که در حال سرویس دهی به درخواست هاست، آداپتور درخواست را به پروسه کارگر ارسال میکند. در صورتی که پروسهای در application pool در حال اجرا نباشد، WAS یک پروسه جدید را آغاز میکند و آداپتور درخواست را به آن پاس میکند.
نکته: از آنجایی که WAS هم پروسههای http و هم non-http را مدیریت میکند، پس میتوانید از یک applicatio pool برای چندین protocol استفاده کنید. به عنوان مثال شما یکی سرویس XML دارید که میتوانید از آن برای سرویس دهی به پروتوکلهای Http و net.tcp بهره بگیرید.
ماژولها در IIS
قبلا مقاله ای در مورد moduleها با نام "کمی در مورد httpmoduleها" قرار داده بودیم که بهتر است برای آشنایی بیشتر، به آن رجوع کنید. به غیر از وب کانفیگ که برای معرفی ماژولها استفاده میکردیم ، میتوانید به صورت گرافیکی و دستی هم این کار را انجام بدهید. ابتدا یک پروژه class library ایجاد کرده و ماژول خود را بنویسید و سپس آن را به یک dll تبدیل کنید و dll را در شاخه bin که این شاخه در ریشه وب سایتتان قرار دارد کپی کنید. سپس در IIS قسمت module گزینه Add را انتخاب کنید و در قسمت اول نامی برای آن و در قسمت بعدی دقیقا همان قوانین type که در وب کانفیگ مشخص میکردید را مشخص کنید: Namespace.ClassName
گزینه invoke only for requests to asp.net and manage handlers را هم تیک بزنید. کار تمام است.
ماژولهای کد ماشین یا native
این ماژولها به صورت پیش فرض به سیستم اضافه شدهاند و در صورتی که میخواهید جایگزینی به منظور خصوصی سازی انجام دهید آنها را پاک کنید و ماژول جدید را اضافه کنید.
جدول ماژولهای HTTP
نام ماژول | توضیحات | نام فایل منبع |
CustomErrorModule | موقعی که هنگام response، کد خطایی تولید میگردد، پیام خطا را پیکربندی و سپس ارسال میکند. | Inetsrv\Custerr.dll |
HttpRedirectionModule | تنظمیات redirection برای درخواستهای http را در دسترس قرار میدهد. | Inetsrv\Redirect.dll |
ProtocolSupportModule | انجام عملیات مربوط به پروتوکلها بر عهده این ماژول است؛ مثل تنظیم کردن قسمت هدر برای response. | Inetsrv\Protsup.dll |
RequestFilteringModule | این ماژول از IIS 7.5 به بعد اضافه شد. درخواستها را فیلتر میکند تا پروتوکل و رفتار محتوا را کنترل کند. | Inetsrv\modrqflt.dll |
WebDAVModule | این ماژول از IIS 7.5 به بعد اضافه شد. امنیت بیشتر در هنگام انتشار محتوا روی HTTP SSL | Inetsrv\WebDAV.dll |
ماژولهای امنیتی
نام ماژول | توضیحات | نام فایل منبع |
AnonymousAuthenticationModule | موقعی که هیچ کدام از عملیات authentication با موفقیت روبرو نشود، عملیات Anonymous authentication انجام میشود. | Inetsrv\Authanon.dll |
BasicAuthenticationModule | عمل ساده و اساسی authentication را انجام میدهد. | Inetsrv\Authbas.dll |
CertificateMappingAuthenticationModule | انجام عمل Certificate Mapping authentication در Active Directory | Inetsrv\Authcert.dll |
DigestAuthenticationModule | Digest authentication | Inetsrv\Authmd5.dll |
IISCertificateMappingAuthenticationModule | همان Certificate Mapping authentication ولی اینبار با IIS Certificate . | Inetsrv\Authmap.dll |
RequestFilteringModule | عملیات اسکن URL از قبیل نام صفحات و دایرکتوریها ، توع verb و یا کاراکترهای مشکوک و خطرآفرین | Inetsrv\Modrqflt.dll |
UrlAuthorizationModule | عمل URL authorization | Inetsrv\Urlauthz.dll |
WindowsAuthenticationModule | عمل NTLM integrated authentication | Inetsrv\Authsspi.dll |
IpRestrictionModule | محدود کردن IPهای نسخه 4 لیست شده در IP Security در قسمت پیکربندی | Inetsrv\iprestr.dll |
ماژولهای محتوا
نام ماژول | توضیحات | نام فایل منبع |
CgiModule | ایجاد پردازشهای (Common Gateway Interface (CGI به منظور ایجاد خروجی response | Inetsrv\Cgi.dll |
DefaultDocumentModule | تلاش برای ساخت یک سند پیش فرض برای درخواست هایی که دایرکتوری والد ارسال میشود | Inetsrv\Defdoc.dll |
DirectoryListingModule | لیست کردن محتوای یک دایرکتوری | Inetsrv\dirlist.dll |
IsapiModule | میزبانی فایل های ISAPI | Inetsrv\Isapi.dll |
IsapiFilterModule | پشتیبانی از فیلتر های ISAPI | Inetsrv\Filter.dll |
ServerSideIncludeModule | پردازش کدهای include شده سمت سرور | Inetsrv\Iis_ssi.dll |
StaticFileModule | ارائه فایلهای ایستا | Inetsrv\Static.dll |
FastCgiModule | پشتبانی از CGI | Inetsrv\iisfcgi.dll |
ماژولهای فشرده سازی
DynamicCompressionModule | فشرده سازی پاسخ response با gzip | Inetsrv\Compdyn.dll |
StaticCompressionModule | فشرده سازی محتوای ایستا | Inetsrv\Compstat.dll |
ماژولهای کش کردن
FileCacheModule | تهیه کش در مد کاربری برای فایلها. | Inetsrv\Cachfile.dll |
HTTPCacheModule | تهیه کش مد کاربری و مد کرنل برای http.sys | Inetsrv\Cachhttp.dll |
TokenCacheModule | تهیه کش مد کاربری بر اساس جفت نام کاربری و یک token که توسط Windows user principals تولید شده است. | Inetsrv\Cachtokn.dll |
UriCacheModule | تهیه یک کش مد کاربری از اطلاعات URL | Inetsrv\Cachuri.dll |
ماژولهای عیب یابی و لاگ کردن
CustomLoggingModule | بارگزاری ماژولهای خصوصی سازی شده جهت لاگ کردن | Inetsrv\Logcust.dll |
FailedRequestsTracingModule | برای ردیابی درخواستهای ناموفق | Inetsrv\Iisfreb.dll |
HttpLoggingModule | دریافت اطلاعات و پردازش وضعیت http.sys برای لاگ کردن | Inetsrv\Loghttp.dll |
RequestMonitorModule | ردیابی درخواست هایی که در حال حاضر در پروسههای کارگر در حال اجرا هستند و گزارش اطلاعاتی در مورد وضعیت اجرا و کنترل رابط برنامه نویسی کاربردی. | Inetsrv\Iisreqs.dll |
TracingModule | گزارش رخدادهای Microsoft Event Tracing for Windows یا به اختصار ETW | Inetsrv\Iisetw.dll |
ماژولهای مدیریتی و نظارتی بر کل ماژولها
ManagedEngine | مدیرتی بر ماژولهای غیر native که در پایین قرار دارند. | Microsoft.NET\Framework\v2.0.50727\webengine.dll |
ConfigurationValidationModule | اعتبارسنجی خطاها، مثل موقعی که برنامه در حالت integrated اجرا شده و ماژولها یا هندلرها در system.web تعریف شدهاند. | Inetsrv\validcfg.dll |
به علاوه ماژولهای native بالا، IIS این امکان را فراهم میآورند تا از ماژولهای کد مدیریت شده (یعنی CLR) برای توسعه توابع و کارکرد IIS بهره مند شوید:
ماژول | توضیحات | منبع |
AnonymousIdentification | مدیریت منابع تعیین هویت برای کاربران ناشناس مانند asp.net profile | System.Web.Security.AnonymousIdentificationModule |
DefaultAuthentication | اطمینان از وجود شی Authentication در context مربوطه | System.Web.Security.DefaultAuthenticationModule |
FileAuthorization | تایید هویت کاربر برای دسترسی به فایل درخواست | System.Web.Security.FileAuthorizationModule |
FormsAuthentication | با این قسمت که باید کاملا آشنا باشید؛ برای تایید هویت کاربر | System.Web.Security.FormsAuthenticationModule |
OutputCache | مدیریت کش | System.Web.Caching.OutputCacheModule |
Profile | مدیریت پروفایل کاربران که تنظیماتش را در یک منبع دادهای چون دیتابیس ذخیره و بازیابی میکند. | System.Web.Profile.ProfileModule |
RoleManager | مدیریت نقش و سمت کاربران | System.Web.Security.RoleManagerModule |
Session | مدیریت session ها | System.Web.SessionState.SessionStateModule |
UrlAuthorization | آیا کاربر جاری حق دسترسی به URL درخواست را دارد؟ | System.Web.Security.UrlAuthorizationModule |
UrlMappingsModule | تبدیل یک Url واقعی به یک Url کاربرپسند | System.Web.UrlMappingsModule |
WindowsAuthentication | شناسایی و تایید و هویت یک کاربر بر اساس لاگین او به ویندوز | System.Web.Security.WindowsAuthenticationModule |
- UserManager برای ذخیره سازی اطلاعات از UserStore استفاده میکند.
- تمام اینترفیسهای Identity دارای پیاده سازیهای پیش فرضی هم هستند که امکان سفارشی سازی آنها در لایه سرویس برنامه جاری پیش بینی شدهاست.
- تمام اینترفیسهای Identity دارای پیاده سازیهای پیش فرضی هم هستند که امکان سفارشی سازی آنها در لایه سرویس برنامه جاری پیش بینی شدهاست.
- اضافه کردن max-age به header فایلهای استاتیک | tostring.blogfa.com
- ویژگی Name در عناصر Html هنوز مهم است. - بازار آی تی | itbazaar.persianblog.ir
- Desktop Google Reader | desktopgooglereader.codeplex.com
- SharpCompress - a fully native C# library for RAR, 7Zip, Zip, Tar, GZip, BZip2 | sharpcompress.codeplex.com
- The 101 Best Chrome Extensions | www.makeuseof.com
- WPF Converters | wpfconverters.codeplex.com
- استفاده از OpenCV در دات نت | www.codeproject.com
- انتخاب زبان برنامه نویسی مناسب برای دانشجویان کامپیوتر | www.banaie.ir
- ویدیوهای رایگان کلاسهای computer-science از دانشگاه هاروارد | www.extension.harvard.edu
نظرات اشتراکها
Google Reader تیرماه سال بعد تعطیل خواهد شد
بحث تعطیلی گوگل ریدر مقارن شد با ارائه گوگل پلاس. اون موقع خیلیها اعتراض کردند و گوگل به ظاهر عقب نشینی کرد. اما بالاخره کار خودش رو قراره انجام بده!
نظرات مطالب
بررسی علت CPU Usage بالای برنامه در حال اجرا
با سلام خدمت آقای نصیری
چند وقتی است روی یکی از سرورهی ما مش out of memory به وجود آمده
مشخصات سرور ویندوز 2003 سی دو بیتی رم بالای 4 گیگابایت که با سویچ /PAE در فایل بوت ... این حافظه به ویندوز معرفی شده در
ضمن اینکه Lock Page in memory برای یوزری که سرویس IIS را Start کرده تنظیم شده در این حالت باز ما خطا را میگیرم
چیزی که به ذخن من میرسه ما در برنامه از کریستال ریپورت استفاده کردیم که داخل اون یک library ار نوع com وجود داره که کار
تبدیل تاریخ میلادی به شمسی رو انجام میده فکر میکنم به خاطر اینکه این کتابخانه به شکل unmanage code است
سوالی که دارم اینه
چه طور می توانم مطمئن بشم مشکل از این کتابخانه است و یا خیر
لازم میدونم اشاره کنم تعداد کاربرای سایت بالا و همچنین این سرور مختص iis است و به هیچ عنوان SQL روی اون نصب نمی باشد
چند وقتی است روی یکی از سرورهی ما مش out of memory به وجود آمده
مشخصات سرور ویندوز 2003 سی دو بیتی رم بالای 4 گیگابایت که با سویچ /PAE در فایل بوت ... این حافظه به ویندوز معرفی شده در
ضمن اینکه Lock Page in memory برای یوزری که سرویس IIS را Start کرده تنظیم شده در این حالت باز ما خطا را میگیرم
چیزی که به ذخن من میرسه ما در برنامه از کریستال ریپورت استفاده کردیم که داخل اون یک library ار نوع com وجود داره که کار
تبدیل تاریخ میلادی به شمسی رو انجام میده فکر میکنم به خاطر اینکه این کتابخانه به شکل unmanage code است
سوالی که دارم اینه
چه طور می توانم مطمئن بشم مشکل از این کتابخانه است و یا خیر
لازم میدونم اشاره کنم تعداد کاربرای سایت بالا و همچنین این سرور مختص iis است و به هیچ عنوان SQL روی اون نصب نمی باشد
در قسمت قبل راجع به مدل پیشفرض پرووایدر منابع در ASP.NET بحث نسبتا مفصلی شد. در این قسمت تولید یک پرووایدر سفارشی برای استفاده از دیتابیس به جای فایلهای resx. به عنوان منبع نگهداری دادهها بحث میشود.
قبلا هم اشاره شده بود که در پروژههای بزرگ ذخیره تمام ورودیهای منابع درون فایلهای resx. بازدهی مناسبی نخواهد داشت. همچنین به مرور زمان و با افزایش تعداد این فایلها، کار مدیریت آنها بسیار دشوار و طاقتفرسا خواهد شد. درضمن بهدلیل رفتار سیستم کشینگ این منابع در ASP.NET، که محتویات کل یک فایل را بلافاصله پس از اولین درخواست یکی از ورودیهای آن در حافظه سرور کش میکند، در صورت وجود تعداد زیادی فایل منبع و با ورودیهای بسیار، با گذشت زمان بازدهی کلی سایت به شدت تحت تاثیر قرار خواهد گرفت.
بنابراین استفاده از یک منبع مثل دیتابیس برای چنین شرایطی و نیز کنترل مدیریت دسترسی به ورودیهای آن به صورت سفارشی، میتواند به بازدهی بهتر برنامه کمک زیادی کند. درضمن فرایند بهروزرسانی مقادیر این ورودیها در صورت استفاده از یک دیتابیس میتواند سادهتر از حالت استفاده از فایلهای resx. انجام شود.
تولید یک پرووایدر منابع دیتابیسی - بخش اول
در بخش اول این مطلب با نحوه پیادهسازی کلاسهای اصلی و اولیه موردنیاز آشنا خواهیم شد. مفاهیم پیشرفتهتر (مثل کشکردن ورودیها و عملیات fallback) و نیز ساختار مناسب جدول یا جداول موردنیاز در دیتابیس و نحوه ذخیره ورودیها برای انواع منابع در دیتابیس در مطلب بعدی آورده میشود.
با توجه به توضیحاتی که در قسمت قبل داده شد، میتوان از طرح اولیهای به صورت زیر برای سفارشیسازی یک پرووایدر منابع دیتابیسی استفاده کرد:
اگر مطالب قسمت قبل را خوب مطالعه کرده باشید، پیاده سازی اولیه طرح بالا نباید کار سختی باشد. در ادامه یک نمونه از پیادهسازیهای ممکن نشان داده شده است.
برای آغاز کار ابتدا یک پروژه ClassLibrary جدید مثلا با نام DbResourceProvider ایجاد کنید و ریفرنسی از اسمبلی System.Web به این پروژه اضافه کنید. سپس کلاسهایی که در ادامه شرح داده شدهاند را به آن اضافه کنید.
کلاس DbResourceProviderFactory
همه چیز از یک ResourceProviderFactory شروع میشود. نسخه سفارشی نشان داده شده در زیر برای منابع محلی و کلی از کلاسهای پرووایدر سفارشی استفاده میکند که در ادامه آورده شدهاند.
using System.Web.Compilation; namespace DbResourceProvider { public class DbResourceProviderFactory : ResourceProviderFactory { #region Overrides of ResourceProviderFactory public override IResourceProvider CreateGlobalResourceProvider(string classKey) { return new GlobalDbResourceProvider(classKey); } public override IResourceProvider CreateLocalResourceProvider(string virtualPath) { return new LocalDbResourceProvider(virtualPath); } #endregion } }
درباره اعضای کلاس ResourceProviderFactory در قسمت قبل توضیحاتی داده شد. در نمونه سفارشی بالا دو متد این کلاس برای برگرداندن پرووایدرهای سفارشی منابع محلی و کلی بازنویسی شدهاند. سعی شده است تا نمونههای سفارشی در اینجا رفتاری همانند نمونههای پیشفرض در ASP.NET داشته باشند، بنابراین برای پرووایدر منابع کلی (GlobalDbResourceProvider) نام منبع درخواستی (className) و برای پرووایدر منابع محلی (LocalDbResourceProvider) مسیر مجازی درخواستی (virtualPath) به عنوان پارامتر کانستراکتور ارسال میشود.
نکته: برای استفاده از این کلاس به جای کلاس پیشفرض ASP.NET باید یکسری تنظیمات در فایل کانفیگ برنامه مقصد اعمال کرد که در ادامه آورده شده است.
کلاس BaseDbResourceProvider
برای پیادهسازی راحتتر کلاسهای موردنظر، بخشهای مشترک بین دو پرووایدر محلی و کلی در یک کلاس پایه به صورت زیر قرار داده شده است. این طرح دقیقا مشابه نمونه پیشفرض ASP.NET است.
using System.Globalization; using System.Resources; using System.Web.Compilation; namespace DbResourceProvider { public abstract class BaseDbResourceProvider : IResourceProvider { private DbResourceManager _resourceManager; protected abstract DbResourceManager CreateResourceManager(); private void EnsureResourceManager() { if (_resourceManager != null) return; _resourceManager = CreateResourceManager(); } #region Implementation of IResourceProvider public object GetObject(string resourceKey, CultureInfo culture) { EnsureResourceManager(); if (_resourceManager == null) return null; if (culture == null) culture = CultureInfo.CurrentUICulture; return _resourceManager.GetObject(resourceKey, culture); } public virtual IResourceReader ResourceReader { get { return null; } } #endregion } }
کلاس بالا چون یک کلاس صرفا پایه است بنابراین به صورت abstract تعریف شده است. در این کلاس، از نمونه سفارشی DbResourceManager برای بازیابی دادهها از دیتابیس استفاده شده است که در ادامه شرح داده شده است.
در اینجا، از متد CreateResourceManager برای تولید نمونه مناسب از کلاس DbResourceManager استفاده میشود. این متد به صورت abstract و protected تعریف شده است بنابراین پیادهسازی آن باید در کلاسهای مشتق شده که در ادامه آورده شدهاند انجام شود.
در متد EnsureResourceManager کار بررسی نال نبودن resouceManager_ انجام میشود تا درصورت نال بودن آن، بلافاصله نمونهای تولید شود.
نکته: ازآنجاکه نقطه آغازین فرایند یعنی تولید نمونهای از کلاس DbResourceProviderFactory توسط خود ASP.NET انجام خواهد شد، بنابراین مدیریت تمام نمونههای ساخته شده از کلاسهایی که در این مطلب شرح داده میشوند درنهایت عملا برعهده ASP.NET است. در ASP.NET درطول عمر یک برنامه تنها یک نمونه از کلاس Factory تولید خواهد شد، و متدهای موجود در آن در حالت عادی تنها یکبار به ازای هر منبع درخواستی (کلی یا محلی) فراخوانی میشوند. درنتیجه به ازای هر منبع درخواستی (کلی یا محلی) هر یک از کلاسهای پرووایدر منابع تنها یکبار نمونهسازی خواهد شد. بنابراین بررسی نال نبودن این متغیر و تولید نمونهای جدید تنها در صورت نال بودن آن، کاری منطقی است. این نمونه بعدا توسط ASP.NET به ازای هر منبع یا صفحه درخواستی کش میشود تا در درخواستهای بعدی تنها از این نسخه کششده استفاده شود.
در متد GetObject نیز کار استخراج ورودی منابع انجام میشود. ابتدا با استفاده از متد EnsureResourceManager از وجود نمونهای از کلاس DbResourceManager اطمینان حاصل میشود. سپس درصورتیکه مقدار این کلاس همچنان نال باشد مقدار نال برگشت داده میشود. این حالت وقتی پیش میآید که نتوان با استفاده از دادههای موجود نمونهای مناسب از کلاس DbResourceManager تولید کرد.
سپس مقدار کالچر ورودی بررسی میشود و درصورتیکه نال باشد مقدار کالچر UI ثرد جاری که در CultureInfo.CurrentUICulture قرار دارد برای آن درنظر گرفته میشود. درنهایت با فراخوانی متد GetObject از DbResourceManager تولیدی برای کلید و کالچر مربوطه کار استخراج ورودی درخواستی پایان میپذیرد.
پراپرتی ResourceReader در این کلاس به صورت virtual تعریف شده است تا بتوان پیادهسازی مناسب آن را در هر یک از کلاسهای مشتقشده اعمال کرد. فعلا برای این کلاس پایه مقدار نال برگشت داده میشود.
کلاس GlobalDbResourceProvider
برای پرووایدر منابع کلی از این کلاس استفاده میشود. نحوه پیادهسازی آن نیز دقیقا همانند طرح نمونه پیشفرض ASP.NET است.
using System; using System.Resources; namespace DbResourceProvider { public class GlobalDbResourceProvider : BaseDbResourceProvider { private readonly string _classKey; public GlobalDbResourceProvider(string classKey) { _classKey = classKey; } #region Implementation of BaseDbResourceProvider protected override DbResourceManager CreateResourceManager() { return new DbResourceManager(_classKey); } public override IResourceReader ResourceReader { get { throw new NotSupportedException(); } } #endregion } }
GlobalDbResourceProvider از کلاس پایهای که در بالا شرح داده شد مشتق شده است. بنابراین تنها بخشهای موردنیاز یعنی متد CreateResourceManager و پراپرتی ResourceReader در این کلاس پیادهسازی شده است.
در اینجا نمونه مخصوص کلاس ResourceManager (همان DbResourceManager) با توجه به نام فایل مربوط به منبع کلی تولید میشود. نام فایل در اینجا همان چیزی است که در دیتابیس برای نام منبع مربوطه ذخیره میشود. ساختار آن بعدا بحث میشود.
همانطور که میبینید برای پراپرتی ResourceReader خطای عدم پشتیبانی صادر میشود. دلیل آن در قسمت قبل و نیز بهصورت کمی دقیقتر در ادامه آورده شده است.
کلاس LocalDbResourceProvider
برای منابع محلی نیز از طرحی مشابه نمونه پیشفرض ASP.NET که در قسمت قبل نشان داده شد، استفاده شده است.
using System.Resources; namespace DbResourceProvider { public class LocalDbResourceProvider : BaseDbResourceProvider { private readonly string _virtualPath; public LocalDbResourceProvider(string virtualPath) { _virtualPath = virtualPath; } #region Implementation of BaseDbResourceProvider protected override DbResourceManager CreateResourceManager() { return new DbResourceManager(_virtualPath); } public override IResourceReader ResourceReader { get { return new DbResourceReader(_virtualPath); } } #endregion } }
این کلاس نیز از کلاس پایهای BaseDbResourceProvider مشتق شده و پیادهسازیهای مخصوص منابع محلی برای متد CreateResourceManager و پراپرتی ResourceReader در آن انجام شده است.
در متد CreateResourceManager کار تولید نمونهای از DbResourceManager با استفاده از مسیر مجازی صفحه درخواستی انجام میشود. این فرایند شبیه به پیادهسازی پیشفرض ASP.NET است. در واقع در پیادهسازی جاری، نام منابع محلی همنام با مسیر مجازی متناظر آنها در دیتابیس ذخیره میشود. درباره ساختار جدول دیتابیس بعدا بحث میشود.
در این کلاس کار بازخوانی کلیدهای موجود برای پراپرتیهای موجود در یک صفحه از طریق نمونهای از کلاس DbResourceReader انجام شده است. شرح این کلاس در ادامه آمده است.
نکته: همانطور که در قسمت قبل هم اشاره کوتاهی شده بود، از خاصیت ResourceReader در پرووایدر منابع برای تعیین تمام پراپرتیهای موجود در منبع استفاده میشود تا کار جستجوی کلیدهای موردنیاز در عبارات بومیسازی ضمنی برای رندر صفحه وب راحتتر انجام شود. بنابراین از این پراپرتی تنها در پرووایدر منابع محلی استفاده میشود. ازآنجاکه در عبارات بومیسازی ضمنی تنها قسمت اول نام کلید ورودی منبع آورده میشود، بنابراین قسمت دوم (و یا قسمتهای بعدی) کلید موردنظر که همان نام پراپرتی کنترل متناظر است از جستجو میان ورودیهای یافته شده توسط این پراپرتی بدست میآید تا ASP.NET بداند که برای رندر صفحه چه پراپرتیهایی نیاز به رجوع به پرووایدر منبع محلی مربوطه دارد (برای آشنایی بیشتر با عبارت بومیسازی ضمنی رجوع شود به قسمت قبل).
نکته: دقت کنید که پس از اولین درخواست، خروجی حاصل از enumerator این ResourceReader کش میشود تا در درخواستهای بعدی از آن استفاده شود. بنابراین در حالت عادی، به ازای هر صفحه تنها یکبار این پراپرتی فراخوانده میشود. درباره این enumerator در ادامه بحث شده است.
کلاس DbResourceManager
کار اصلی مدیریت و بازیابی ورودیهای منابع از دیتابیس از طریق کلاس DbResourceManager انجام میشود. نمونهای بسیار ساده و اولیه از این کلاس را در زیر مشاهده میکنید:
using System.Globalization; using DbResourceProvider.Data; namespace DbResourceProvider { public class DbResourceManager { private readonly string _resourceName; public DbResourceManager(string resourceName) { _resourceName = resourceName; } public object GetObject(string resourceKey, CultureInfo culture) { var data = new ResourceData(); return data.GetResource(_resourceName, resourceKey, culture.Name).Value; } } }
کار استخراج ورودیهای منابع با استفاده از نام منبع درخواستی در این کلاس مدیریت خواهد شد. این کلاس با استفاده نام منیع درخواستی به عنوان پارامتر کانستراکتور ساخته میشود. با استفاده از متد GetObject که نام کلید ورودی موردنظر و کالچر مربوطه را به عنوان پارامتر ورودی دریافت میکند فرایند استخراج انجام میشود.
برای کپسولهسازی عملیات از کلاس جداگانهای (ResourceData) برای تبادل با دیتابیس استفاده شده است. شرح بیشتر درباره این کلاس و نیز پیاده سازی کاملتر کلاس DbResourceManager به همراه مدیریت کش ورودیهای منابع و نیز عملیات fallback در مطلب بعدی آورده میشود.کلاس DbResourceReader
این کلاس که درواقع پیادهسازی اینترفیس IResourceReader است برای یافتن تمام کلیدهای تعریف شده برای یک منبع بهکار میرود، پیادهسازی آن نیز به صورت زیر است:
using System.Collections; using System.Resources; using System.Security; using DbResourceProvider.Data; namespace DbResourceProvider { public class DbResourceReader : IResourceReader { private readonly string _resourceName; private readonly string _culture; public DbResourceReader(string resourceName, string culture = "") { _resourceName = resourceName; _culture = culture; } #region Implementation of IResourceReader public void Close() { } public IDictionaryEnumerator GetEnumerator() { return new DbResourceEnumerator(new ResourceData().GetResources(_resourceName, _culture)); } #endregion #region Implementation of IEnumerable IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region Implementation of IDisposable public void Dispose() { Close(); } #endregion } }
این کلاس تنها با استفاده از نام منبع و عنوان کالچر موردنظر کار بازخوانی ورودیهای موجود را انجام میدهد.
تنها نکته مهم در کد بالا متد GetEnumerator است که نمونهای از اینترفیس IDictionaryEnumerator را برمیگرداند. در اینجا از کلاس DbResourceEnumerator که برای کار با دیتابیس طراحی شده، استفاده شده است. همانطور که قبلا هم اشاره شده بود، هر یک از اعضای این enumerator از نوع DictionaryEntry هستند که یک struct است. این کلاس در ادامه شرح داده شده است.
متد Close برای بستن و از بین بردن منابعی است که در تهیه enumerator موردبحث نقش داشتهاند. مثل منایع شبکهای یا فایلی که باید قبل از اتمام کار با این کلاس به صورت کامل بسته شوند. هرچند در نمونه جاری چنین موردی وجود ندارد و بنابراین این متد بلااستفاده است.
در کلاس فوق نیز برای دریافت اطلاعات از ResourceData استفاده شده است که بعدا به همراه ساختار مناسب جدول دیتابیس شرح داده میشود.نکته: دقت کنید که در پیادهسازی نشان داده شده برای کلاس LocalDbResourceProvider برای یافتن ورودیهای موجود از مقدار پیشفرض (یعنی رشته خالی) برای کالچر استفاده شده است تا از ورودیهای پیشفرض که در حالت عادی باید شامل تمام موارد تعریف شده موجود هستند استفاده شود (قبلا هم شرح داده شد که منبع اصلی و پیشفرض یعنی همانی که برای زبان پیشفرض برنامه درنظر گرفته میشود و بدون نام کالچر مربوطه است، باید شامل حداکثر ورودیهای تعریف شده باشد. منابع مربوطه به سایر کالچرها میتوانند همه این ورودیهای تعریفشده در منبع اصلی و یا قسمتی از آن را شامل شوند. عملیات fallback تضمین میدهد که درنهایت نزدیکترین گزینه متناظر با درخواست جاری را برگشت دهد).
کلاس DbResourceEnumerator
کلاس دیگری که در اینجا استفاده شده است، DbResourceEnumerator است. این کلاس در واقع پیاده سازی اینترفیس IDictionaryEnumerator است. محتوای این کلاس در زیر آورده شده است:
using System.Collections; using System.Collections.Generic; using DbResourceProvider.Models; namespace DbResourceProvider { public sealed class DbResourceEnumerator : IDictionaryEnumerator { private readonly List<Resource> _resources; private int _dataPosition; public DbResourceEnumerator(List<Resource> resources) { _resources = resources; Reset(); } public DictionaryEntry Entry { get { var resource = _resources[_dataPosition]; return new DictionaryEntry(resource.Key, resource.Value); } } public object Key { get { return Entry.Key; } } public object Value { get { return Entry.Value; } } public object Current { get { return Entry; } } public bool MoveNext() { if (_dataPosition >= _resources.Count - 1) return false; ++_dataPosition; return true; } public void Reset() { _dataPosition = -1; } } }
تفاوت این اینترفیس با اینترفیس IEnumerable در سه عضو اضافی است که برای استفاده در سیستم مدیریت منابع ASP.NET نیاز است. همانطور که در کد بالا مشاهده میکنید این سه عضو عبارتند از پراپرتیهای Entry و Key و Value. پراپرتی Entry که ورودی جاری در enumerator را مشخص میکند از نوع DictionaryEntry است. پراپرتیهای Key و Value هم که از نوع object تعریف شدهاند برای کلید و مقدار ورودی جاری استفاده میشوند.
این کلاس لیستی از Resource به عنوان پارامتر کانستراکتور برای تولید enumerator دریافت میکند. کلاس Resource مدل تولیدی از ساختار جدول دیتابیس برای ذخیره ورودیهای منابع است که در مطلب بعدی شرح داده میشود. بقیه قسمتهای کد فوق هم پیادهسازی معمولی یک enumerator است.
تنظیمات فایل کانفیگ
برای اجبار کردن ASP.NET به استفاده از Factory موردنظر باید تنظیمات زیر را در فایل web.config اعمال کرد:
<system.web> ... <globalization resourceProviderFactoryType=" نام کامل اسمبلی مربوطه ,نام پرووایدر فکتوری به همراه فضای نام آن " /> ... </system.web>
روش نشان داده شده در بالا حالت کلی تعریف و تنظیم یک نوع داده در فایل کانفیگ را نشان میدهد. درباره نام کامل اسمبلی در اینجا شرح داده شده است.
مثلا برای پیادهسازی نشان داده شده در این مطلب خواهیم داشت:<globalization resourceProviderFactoryType="DbResourceProvider.DbResourceProviderFactory, DbResourceProvider" />
در مطلب بعدی درباره ساختار مناسب جدول یا جداول دیتابیس برای ذخیره ورودهای منابع و نیز پیادهسازی کاملتر کلاسهای مورداستفاده بحث خواهد شد.
منابع:
نظرات مطالب
باگ Directory Traversal در سایت
بله در فضاهایی همچون Azure محدودیت هایی بر روی اندازه پایگاه داده و ... وجود دارد. ولی نه در هر نوع محیط ابری.
در ضمن الان شما برای جلوگیری از خیلی مسائل مجبور شدید یک Handler جهت پراکسی اطلاعات (چه ارسالی و چه دریافتی) ایجاد کنید که از خیلی لحاظ مشابه ذخیره فایلها در پایگاه داده باشه.
در ضمن مگه اندازه فایلهای ارسالی و ... چقدر است که نیازمند مقدار زیادی پردازش باشه. استفاده از مکانیزمهای Cache موجود در asp.net هم میتونه کمک کنه.
حرف شما از خیلی لحاظ صحیحه و شکی در اون نیست ولی میشه به راه حلهای دیگری هم فکر کرد.
نظرات مطالب