ممنون از اطلاعات مفید شما .
من در یک پروژه تحت وب از طریق فایل اکسل اطلاعات را از کاربر دریافت میکنم و نیاز دارم این اطلاعات را در داخل دیتابیس ذخیره کنم از آنجا که تعداد رکوردهای فایل اکسل نامشخص است به چه صورت باید این کد را بنویسم
ممنون
هر متغیر استاتیک تنها دارای یک مقدار، در یک AppDomain مشخص است (مگر اینکه با ویژگی ThreadStatic مزین شود). هر برنامهی ASP.NET هم AppDomain جداگانه و منحصر به خود را دارا است. بنابراین تعریف یک متغیر استاتیک در یک برنامهی ASP.NET به معنای به اشتراک گذاری آن در بین تمامی درخواستهای رسیده به سرور است. بنابراین عموما استفاده از متغیرهای استاتیک در برنامههای چند کاربره ASP.NET یک اشتباه بزرگ است و در صورت استفاده از آن باید منتظر تخریب اطلاعات یا دریافت نتایج غیرمنتظرهای باشید (مگر اینکه واقعا میدانید دارید چکار میکنید، برای مثال کش کردن نگاشتهای NHibernate به این صورت و استفاده از الگوی singleton یا روشهای مشابه که باید بین تمام کاربران به یک صورت و یک شکل به اشتراک گذاشه شود و در حین اجرای برنامه تغییری در آن حاصل نمیشود). برای مثال اگر کاربر یک، در صفحهی یک، متغیر استاتیکی را مقدار دهی کند، کاربر 2 نیز با مقدار به روز شدهی کاربر یک کار خواهد کرد که به طور قطع این مورد مد نظر شما نیست (چون به احتمال زیاد طراحی شما بر اساس کار کاربر در یک Session است و نه یک مقدار برای تمام سشنهای موجود در سایت) و همچنین باید دقت داشت که امنیت سیستم نیز در این حالت زیر سؤال است (زیرا در این حالت تمامی کاربران، صرفنظر از سطوح دسترسی تعریف شده برای آنها، دسترسی به اطلاعاتی خواهند داشت که نباید داشته باشند).
نکتهی دیگری را هم که باید در مورد ASP.NET به خاطر داشت این است که ویژگی ThreadStatic نیز در اینجا کمکی نمیکند؛ زیرا مطابق طراحی آن از تردها استفادهی مجدد میگردد.به عبارت دیگر در ASP.NET الزامی ندارد که آغاز یک درخواست جدید حتما به همراه ایجاد یک ترد جدید باشد.
طول عمر این نوع متغیرها هم تا زمانی است که وب سرور یا برنامه ری استارت شوند. فقط در این حالت است که نمونهی موجود تخریب شده و سپس با اجرای مجدد برنامه، بازسازی خواهند شد.
بنابراین متغیرهای استاتیک در ASP.NET همانند شیء Application عمل میکنند و از آن سریعتر هستند زیرا زمانیکه به آنها ارجاع میشود نیازی به جستجو در یک جدول و یافتن آنها نیست (برخلاف شیء Application) و همچنین در اینجا نیازی هم به عملیات تبدیل نوع دادهای وجود ندارد (برخلاف نوع شیء Application که به صورت Object تعریف شده است). وجود اشیاء Application در ASP.NET فقط به جهت حفظ سازگاری آن با ASP کلاسیک است و توصیه شده است در ASP.NET به دلایلی که ذکر شد، اگر و تنها اگر نیاز به اشیایی در سطح برنامه داشتید از متغیرهای استاتیک استفاده کنید. شیء Cache نیز در ASP.NET همین کاربرد را دارد با این تفاوت که میتوان برای آن مدت زمان منقضی شدن تعریف کرد یا اینکه وب سرور بسته به حق تقدم و اهمیتی که برای آن تعریف شده است، مجاز به حذف کردن آن در زمانی است که با کمبود منابع مواجه میشود. همچنین باید دقت داشت که تنها مکان ذخیره سازی متغیرهای استاتیک حافظه است اما امکان دخیره سازی کش بر روی فایل سیستم تا بانک اطلاعاتی و غیره نیز مهیا است.
سؤال: آیا تعریف SqlConnection به صورت استاتیک جزو مواردی است که "مگر واقعا میدانید دارید چکار میکنید؟" ؟
پاسخ: خیر. در اینجا هم واقعا این شخص نمیداند که دارد چکار میکند! یعنی در مورد سازوکار درونی ADO.NET اطلاعاتی ندارد. باز کردن یک کانکشن در ADO.NET به معنای مراجعه به استخر (pool) کانکشنها و بازکردن یکی از آنها و در مقابل، بستن یک کانکشن هم به معنای علامتگذاری یک کانکشن به صورت غیرفعال است و آماده سازی آن برای استفاده در درخواست بعدی. به معنای دیگر این عملیات سربار آنچنانی ندارد که بخواهید آنرا استاتیک تعریف کنید.
همچنین مورد دیگری را هم که این برنامه نویس نمیداند این است که متغیرهای استاتیک thread safe نیستند. به عبارتی حین استفاده از آنها در یک برنامهی چندکاربرهی ASP.NET حتما باید مکانیزمهای قفلگذاری بر روی این نوع متغیرها و اشیاء اعمال شود (که این هم خود یک سربار اضافی است در مقیاس چند 10 یا چند 100 کاربر همزمان). این مشکلات همزمانی به چه معنا است؟ فرض کنید کاربر یک، شیء استاتیک SqlConnection ایی را باز کرده است و با آن مشغول کوئری گرفتن است. کاربر 2 نیز همزمان شروع به استفاده از این کانکشن باز در حال استفاده میکند (SqlConnection استاتیک یعنی استفادهی تمام کاربران فقط و فقط از یک کانکشن باز شده)، نتیجه این خواهد بود که برای مثال پیغام خطایی را دریافت میکند مانند: فیلد مورد نظر در جدول موجود نیست! چرا؟ چون روی شیء استاتیک SqlConnection تعریف شده قفل گذاری صورت نگرفته است و در حین استفاده از آن هر کاربری در سایت نیز همان را استفاده خواهد کرد یا از آن بدتر ممکن است یک کاربر زودتر از کاربر دیگری آنرا ببندد! کاربر سوم در وسط کار با پیغام غیرمعتبر بودن کانکشن مواجه میشود، یا اینکه به صورت پیش فرض یک datareader را بیشتر نمیتوان بر روی یک کانکشن باز شده اعمال کرد. کاربر 4 مشغول خواندن اطلاعات است، کاربر 5 ، پیغام غیرمعتبر بودن کوئری را دریافت میکند.
در این قسمت بیشتر یک سری از ماژولها را به شما در قالب جداول گروه بندی شده معرفی خواهیم کرد :
همانطور که در قسمتهای قبلی گفتیم سرور IIS آماده خصوصی سازی و کار بر اساس علائق شماست؛ ولی توجه داشته باشید حذف تمامی ماژولها ممکن است اثرات جانبی هم داشته باشد. در اینجا ما ماژول هایی را به شما معرفی میکنیم که بدانید کار هر ماژول چیست تا مثلا با حذف ماژولی، امنیت وب سایت خود را به خطر نیندازید :
ماژولهای سودمند یا utility
نام ماژول: | UriCacheModule |
توضیح: | این ماژول نوعی کش برای URLها به شمار میرود. موقعی که url درخواست میشود، اطلاعات در اولین درخواست خوانده شده و کش میشود و اگر دوباره همان url درخواست شود، بدون خواندن تنظیمات و بر اساس تنظیمات قبلی، کار url مربوطه را انجام میدهد تا اطلاعات پیکربندی تغییر کند و بر اساس اطلاعات جدید، خود را به روز کند. |
تگ قابل پیکربندی: | لازم ندارد |
وابستگی: | ندارد |
اثرات حذف آن: | کارایی سیستم کاهش مییابد و سیستم مجبور است برای هر درخواست فایل پیکربندی را بخواند. |
نام ماژول : | FileCacheModule |
توضیح : | فایل هندلِ فایلهایی که قبلا در سرور باز شدهاند را کش میکند تا در صورت نیاز در دفعات بعدی سریعتر عمل کند. |
تگ قابل پیکربندی : | لازم ندارد . |
وابستگی : | ندارد. |
اثرات حذف آن : | کارایی سیستم کاهش مییابد. سیستم در هر اجرای دستور مربوط به فایلها باید فایل هندل را به دست آورد. |
نام ماژول : | TokenCacheModule |
توضیح : | توکنهای امنیتی ویندوز که پسوردهایی بر اساس authentication schemes هستند را کش میکند (anonymous authentication, basic authentication, IIS client certificate authentication ) |
تگ قابل پیکربندی : | لازم ندارد |
وابستگی : | ندارد |
اثرات حذف آن : | کارایی سیستم به شدت پایین میآید. کاربر باید با هر درخواستی لاگین کند. یکی از اصلیترین ضربهها با حذف این ماژول این است که اگر مثلا یک پسورد از یک فایل html محافظت میکند و این صفحه به 50 تصویر ارجاع دارد، 51 بار باید درخواست لاگین اجرا گردد یا شاید هم بدتر |
MANAGED ENGINE: ASP.NET INTEGRATION
نام ماژول : | ManagedEngine |
توضیح : | مدیریت ماژولهای native و مدیریت شده |
تگ قابل پیکربندی : | |
وابستگی : | ندارد |
اثرات حذف آن : | مشخصا غیرفعال شدن asp.net integrated و غیر فعال شدن تمامی ماژولها و هندلرهای تگ وب کانفیگ یا داخل فایل کانفیگ IIS که در مقالات قبلی به تفصیل بیان کردهایم. |
IIS 7 NATIVE MODULES
نام ماژول : | HttpCacheModule |
توضیح : | مدیریت کش خروجی در htttp.sys بر اساس پیکربندی مثل تعریف سایز کش و ... |
تگ قابل پیکربندی : | System.webServer/caching |
وابستگی : | ندارد. |
اثرات حذف آن : | محتوا دیگر به صورت کرنل مد، کش نمیشود و کش پروفایل هم ندید گرفته میشود و احتمالا بر کارآیی و استفاده از منابع هم اثر میگذارد. |
نام ماژول : | DynamicCompressionModule |
توضیح : | پیاده سازی in-memory compression در محتوای پویا |
تگ قابل پیکربندی : | system.webServer/httpCompression and system.webServer/urlCompression. |
وابستگی : | وابستگی ندارد چرا که به طور پیش فرض غیرفعال است. |
نام ماژول : | StaticCompressionModule |
توضیح : | پیادسازی فشرده سازی در محتوای ایستا و برای فایلهای سیستمی از نوع in memory |
تگ قابل پیکربندی : | system.webServer/httpCompression and system.webServer/urlCompression |
وابستگی : | ندارد. |
اثرات حذف آن : | در صورت عدم فشرده سازی بر مصرف ترافیک تاثیر گذار است. |
نام ماژول : | DefaultDocumentModule |
توضیح : | پیاده سازی یک لیست سند پیش فرض. درخواستها مدام پشت سر هم میآیند و این درخواستهای پشت سرهم، به سند پیش فرض هدایت میشوند. همان پنجره ای که شما به ترتیب فایلهای index.htm,index.asp,default.aspx و... را تعیین میکنید. |
تگ قابل پیکربندی : | system.webServer/defaultDocument |
وابستگی : | ندارد. |
اثرات حذف آن : | درخواست را به ریشه هدایت میکند. مثلا برای localhost صفحه 404 باز میگرداند و اگر directoryBrowsing فعال باشد لیستی از دایرکتوری ریشه را باز میگرداند. |
نام ماژول : | DirectoryListingModule |
توضیح : | پیادی سازی لیستی از محتویات یک دایرکتوری |
تگ قابل پیکربندی : | system.webServer/directoryBrowse |
وابستگی : | ندارد. |
اثرات حذف آن : | اگر این ماژول و ماژول قبلی غیرفعال باشند response نهایی خالی است. |
نام ماژول : | ProtocolSupportModule |
توضیح : | پیاده سازی اختصاصی از response header پیاده سازی تنظیمات trace و HTTP verbs. پیاده سازی تنظیمات مربوطه به keep-alive بر اساس پیکربندی |
تگ قابل پیکربندی : | system.webServer/httpProtocol |
وابستگی : | ندارد. |
اثرات حذف آن : | بازگرداندن پیام خطای "405 Method not allowed". |
نام ماژول : | HttpRedirectionModule |
توضیح : | پیاده سازی عملیات انتقال یا redirect |
تگ قابل پیکربندی : | system.webServer/httpRedirect |
وابستگی : | ندارد. |
اثرات حذف آن : | خطر امنیتی: اگر منابعی با redirect کردن محافظت میشوند، از این پس در دسترسند. |
نام ماژول : | ServerSideIncludeModule |
توضیح : | حمایت از فایل shtm یا shtml و ... |
تگ قابل پیکربندی : | system.webServer/serverSideInclude |
وابستگی : | ندارد. |
اثرات حذف آن : | این فایلها به صورت متنی نمایش داده میشوند |
نام ماژول : | StaticFileModule |
توضیح : | فایلهای ایستا را به همراه پسوند ارسال میکند. مثل jpg,html و نوع محتوا را بر اساس staticContent/mimeMap پیکربندی میکند. |
تگ قابل پیکربندی : | system.webServer/staticContent |
وابستگی : | ندارد. |
اثرات حذف آن : | فایلهای ایستا دیگر ارائه نشده و به جای آن خطای 404 بازگشت داده میشود. |
نام ماژول : | AnonymousAuthenticationModule |
توضیح : | پیاده سازی سیستم شناسایی افراد ناشناس. همانطور که میدانید در یک وب سایت حداقل محتوایی برای افرادی بدون داشتن اکانت هم وجود دارد. برای اینکار یک شیء httpuser ایجاد میکند. |
تگ قابل پیکربندی : | system.webServer/security/authentication/anonymousAuthentication |
وابستگی : | ندارد. |
اثرات حذف آن : | حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده ای در IIS میباشد و در صورت نبودن هیچ سیستم شناسایی وجود نداشته و در نبود شیء httpuser سیستم خطای 401.2 را تولید میکند. |
نام ماژول : | CertificateMappingAuthenticationModule |
توضیح : | مجوز SSL را به Active Directory نگاشت میکند. |
تگ قابل پیکربندی : | system.webServer/security/authentication/clientCertificateMappingAuthentication |
وابستگی : | برای اینکه این ماژول وظیفه خود را انجام دهد باید تنظیمات SSL انجام شود و همچنین سیستم IIS جزئی از دامنه Active directory باشد |
اثرات حذف آن : | درخواستها، نرمال رسیدگی میشوند انگار SSL وجود ندارد. |
نام ماژول : | BasicAuthenticationModule |
توضیح : | پیاده سازی پایهای و روتین شناسایی کاربران بر اساس آن چیزی که در استانداد زیر آمده است |
تگ قابل پیکربندی : | system.webServer/security/authentication/basicAuthentication |
وابستگی : | None. |
اثرات حذف آن : | حداقل باید یک سیستم امنیتی برای شناساسایی یا authenticate وجود داشته باشد. httpuser یک ساختار دادهای در IIS میباشد و در صورت نبود، هیچ سیستم شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید میکند. |
نام ماژول : | WindowsAuthenticationModule |
توضیح : | ((windows Authentication (NTLM or Negotiate (Kerberos |
تگ قابل پیکربندی : | system.webServer/security/authentication/windowsAuthentication |
وابستگی : | ندارد. |
اثرات حذف آن : | حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده ای در IIS میباشد و در صورت نبود، هیچ سیستم شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید میکند. |
نام ماژول : | DigestAuthenticationModule |
توضیح : | پیاده سازی سیستم شناسایی دیاجست بر اساس RFC 2617 . |
تگ قابل پیکربندی : | system.webServer/security/authentication/digestAuthentication |
وابستگی : | IIS باید بخشی از دامنه Active Directory باشد. |
اثرات حذف آن : | حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد.
httpuser یک ساختار داده ای در IIS میباشد و در صورت نبود، هیچ سیستم
شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید
میکند. |
نام ماژول : | IISCertificateMappingAuthenticationModule |
توضیح : | پیاده سازی نگاشت مجوزهای IIS، نگهداری و ذخیره اطلاعات همه نگاشتها و مجوزهای کاربری چون SSL client certificates |
تگ قابل پیکربندی : | system.webServer/iisClientCertificateMappingAuthentication |
وابستگی : | اطلاعات SSL به همراه دریافت client certificates جهت پیکربندی این ماژول |
اثرات حذف آن : | حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد.
httpuser یک ساختار داده ای در IIS میباشد و در صورت نبود، هیچ سیستم
شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید
میکند. |
نام ماژول : | UrlAuthorizationModule |
توضیح : | پیاده سازی authorization بر اساس قوانین پیکربندی شده |
تگ قابل پیکربندی : | system.webServer/security/authorization |
وابستگی : | ندارد. |
اثرات حذف آن : | محتواهای محافظت شده توسط authorization دیگر محافظت نمیشوند. |
نام ماژول : | IsapiModule |
توضیح : | پیاده سازی ISAPI Extension |
تگ قابل پیکربندی : | system.webServer/isapiCgiRestriction |
وابستگی : | ندارد. |
اثرات حذف آن : | هندلرهای معرفی شده در بخش IsapiModule و تگ handlers دیگر اجرا نمیشوند |
نام ماژول : | IsapiFilterModule |
توضیح : | پیاده سازی ISAPI filter |
تگ قابل پیکربندی : | system.webServer/isapiFilters |
وابستگی : | ندارد. |
اثرات حذف آن : | اگر برنامه ای از ISAPI filter استفاده میکند، در اجرا دچار مشکل خواهد شد. |
نام ماژول : | IpRestrictionModule |
توضیح : | یک سیستم تشخیص دسترسی بر اساس آی پیهای ورژن4 |
تگ قابل پیکربندی : | system.webServer/security/ipSecurity |
وابستگی : | IPv4 stack باید نصب شود. |
اثرات حذف آن : | کلاینت هایی که IP هایشان در IPsecurity لیست شدهاند ندید گرفته میشوند |
نام ماژول : | RequestFilteringModule |
توضیح : | پیاده سازی یک مجموعه قدرتمند از قوانین امنیتی که درخواستهای مشکوک را پس میزند. |
تگ قابل پیکربندی : | system.webServer/security/requestFiltering |
وابستگی : | ندارد. |
اثرات حذف آن : | دیگر قوانین امنیتی اجرا نخواهند شد و سبب وجود مشکلات امنیتی میشود. |
نام ماژول : | CustomLoggingModule |
توضیح : | پیاده سازی اینترفیس ILogPlugin در سمت IIS، به مشتریان اجازه میدهد تا لاگهای خود را توسعه دهند. هر چند این روش توصیه نمیشود و توصیه کارشناس مایکروسافت استفاده از یک ماژول دست نویس از نوع RQ_LOG_REQUEST می باشد. Implements the ILogPlugin interface on top of IIS. ILogPlugin is a previous COM implementation that allowed customers to extend IIS logging. We do not not recommend extending IIS using this interface. Instead, customers should write a module and subscribe to the RQ_LOG_REQUEST notification. |
تگ قابل پیکربندی : | system.webServer/httpLogging and system.applicationhost/sites/site/logFile/customLogPluginClsid |
وابستگی : | ندارد. |
اثرات حذف آن : | مسلما پلاگینهایهای این اینترفیس از کار میافتند که سیستم ODBC Logging هم جز آن است. |
نام ماژول : | CustomErrorModule |
توضیح : | پیاده سازی مدیریت خطاهای ویژه |
تگ قابل پیکبرندی : | system.webServer/httpErrors |
وابستگی : | None. |
اثرات حذف آن : | در صورتی که خطایی از هسته باشد، نتیجه یک صفحه، با توضیح مختصری از خطا خواهد بود. در غیر این صورت اگر خطا از برنامه یا کامپوننتی باشد جزئیات خطا فاش خواهد شد |
نام ماژول : | HttpLoggingModule |
توضیح : | پیاده سازی سیستم logging استاندارد http.sys |
تگ قابل پیکربندی : | system.applicationHost/log and system.webServer/httpLogging |
وابستگی : | ندارد. |
اثرات حذف آن : | از کار افتادن سیستم لاگ |
نام ماژول : | FailedRequestsTracingModule |
توضیح : | پیاده سازی سیستم ردیابی درخواستهای ناموفق و اجرای قوانین، طبق پیکربندی |
تگ قابل پیکربندی : | system.webServer/tracing and system.webServer/httpTracing |
وابستگی : | ندارد. |
اثرات حذف آن : | Tracing http requests will no longer work. |
نام ماژول : | RequestMonitorModule |
توضیح : | پیاده سازی IIS Run-time State and Control Interface یا به اختصار RSCA . به کاربران اجازه میدهد از اطلاعات، حین اجرا، کوئری بگیرند. مثل درخواست درحال اجرای جاری، آغاز به کار یا توقف وب سایت و دامنههای اپلیکیشن در حال اجرای جاری |
تگ قابل پیکربندی : | ندارد. |
وابستگی : | ندارد. |
اثرات حذف آن : | ابزارهای مرتبط با این موضوع از کار میافتند |
نام ماژول : | CgiModule |
توضیح : | پیاده سازی CGI در سمت IIS |
تگ قابل پیکبرندی : | system.webServer/cgi and system.webServer/isapiCgiRestriction |
وابستگی : | ندارد. |
اثرات حذف آن : | برنامههای CGI متوقف میشوند |
نام ماژول : | TracingModule |
توضیح : | پیاده سازی سیستم ردیابی ETW |
تگ قابل پیکربندی : | system.webServer/httpTracing |
وابستگی : | ندارد. |
اثرات حذف آن : | باعث از کار افتادن سیستم مربوطه میشود |
نام ماژول : | ConfigurationValidationModule |
توضیح : | اعتبارسنجی تنظیمات برنامه ASP.Net که به حالت integrate انتقال یافته است |
تگ قابل پیکربندی : | system.webServer/Validation |
وابستگی : | ندارد. |
اثرات حذف آن : | عدم اعتبارسنجی و در نتیجه عدم نمایش خطاها |
MANAGED MODULES:
نام ماژول : | OutputCache |
توضیح : | پیاده سازی output caching |
تگ قابل پیکربندی : | system.web/caching/outputCache |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | عدم اجرای output cache |
نام ماژول : | Session |
توضیح : | مدیریت سشن ها |
تگ قابل پیکربندی : | system.web/sessionState |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | سشنها از دسترس خارج میشوند. |
نام ماژول : | WindowsAuthentication |
توضیح : | |
تگ قابل پیکربندی : | system.web/authentication |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | این حالت قابل اجرا نخواهد بود |
نام ماژول : | FormsAuthentication |
توضیح : | |
تگ قابل پیکربندی : | system.web/authentication |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | این حالت قابل اجرا نیست و کاربران مجوز دار هم نمیتوانند به منابع محافظت شده دسترسی داشته باشند. |
نام ماژول : | DefaultAuthentication |
توضیح : | اطمینان از وجود شی Authentication در context مربوطه |
تگ قابل پیکربندی : | system.web/authentication |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | اگر مد Forms authentication انتخاب شده باشد بر روی بعضی از کاربران ناشناس کار نخواهد کرد و رویداد DefaultAuthentication.OnAuthenticate اجرا نخواهد شد. |
نام ماژول : | RoleManager |
توضیح : | |
تگ قابل پیکربندی : | |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | این قابلیت در دسترس نمیباشد |
نام ماژول : | UrlAuthorization |
توضیح : | |
تگ قابل پیکربندی : | system.web/authorization. |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | باعث از کار افتادن asp.net authorization و فاش شدن بعضی اطلاعات و همچنین دیگر تهدیدات امنیتی |
نام ماژول : | AnonymousIdentification |
توضیح : | |
تگ قابل پیکربندی : | |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | The anonymous identification feature used by the ASP.NET Profile will not work. |
نام ماژول : | Profile |
توضیح : | |
تگ قابل پیکربندی : | |
وابستگی : | ManagedEngine module must be installed. |
اثرات حذف آن : | ASP.Net Profile از کار خواهد افتاد |
نام ماژول : | UrlMappingsModule |
توضیح : | تبدیل یک Url واقعی به یک Url کاربرپسند |
تگ قابل پیکبرندی : | |
وابستگی : | نیاز به ManagedEngine . |
اثرات حذف آن : | نگاشت Urlها صورت نمیگیرد |
استفاده از LINQ جهت انجام کوئریها توسط NHibernate
نگارش نهایی 1.0 کتابخانهی LINQ to NHibernate اخیرا (حدود سه ماه قبل) منتشر شده است. در این قسمت قصد داریم با کمک این کتابخانه، اعمال متداول انجام کوئریها را بر روی دیتابیس قسمت قبل انجام دهیم.
توسط این نگارش ارائه شده، کلیه اعمال قابل انجام با criteria API این فریم ورک را میتوان از طریق LINQ نیز انجام داد (NHibernate برای کار با دادهها و جستجوهای پیشرفته بر روی آنها، HQL : Hibernate Query Language و Criteria API را سالها قبل توسعه داده است).
جهت دریافت پروایدر LINQ مخصوص NHibernate به آدرس زیر مراجعه نمائید:
پس از دریافت آن، به همان برنامه کنسول قسمت قبل، دو ارجاع را باید افزود:
الف) ارجاعی به اسمبلی NHibernate.Linq.dll
ب) ارجاعی به اسمبلی استاندارد System.Data.Services.dll دات نت فریم ورک سه و نیم
در ابتدای متد Main برنامه قصد داریم تعدادی مشتری را به دیتابیس اضافه نمائیم. به همین منظور متد AddNewCustomers را به کلاس CDbOperations برنامه کنسول قسمت قبل اضافه نمائید. این متد لیستی از مشتریها را دریافت کرده و آنها را در طی یک تراکنش به دیتابیس اضافه میکند:
public void AddNewCustomers(params Customer[] customers)
{
using (ISession session = _factory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
foreach (var data in customers)
session.Save(data);
session.Flush();
transaction.Commit();
}
}
}
پس از افزودن این ارجاعات، کلاس جدیدی را به نام CLinqTest به برنامه کنسول اضافه نمائید. ساختار کلی این کلاس که قصد استفاده از پروایدر LINQ مخصوص NHibernate را دارد باید به شکل زیر باشد (به کلاس پایه NHibernateContext دقت نمائید):
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Linq;
using NHSample1.Domain;
namespace ConsoleTestApplication
{
class CLinqTest : NHibernateContext
{ }
}
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Linq;
using NHSample1.Domain;
namespace ConsoleTestApplication
{
class CLinqTest : NHibernateContext
{
ISessionFactory _factory;
public CLinqTest(ISessionFactory factory)
{
_factory = factory;
}
public List<Customer> GetAllCustomers()
{
using (ISession session = _factory.OpenSession())
{
var query = from x in session.Linq<Customer>() select x;
return query.ToList();
}
}
}
}
در این کوئری، لیست تمامی مشتریها بازگشت داده میشود.
سپس جهت استفاده و بررسی آن در متد Main برنامه خواهیم داشت:
static void Main(string[] args)
{
using (ISessionFactory session = Config.CreateSessionFactory(
MsSqlConfiguration
.MsSql2008
.ConnectionString("Data Source=(local);Initial Catalog=HelloNHibernate;Integrated Security = true")
.ShowSql()
))
{
var customer1 = new Customer()
{
FirstName = "Vahid",
LastName = "Nasiri",
AddressLine1 = "Addr1",
AddressLine2 = "Addr2",
PostalCode = "1234",
City = "Tehran",
CountryCode = "IR"
};
var customer2 = new Customer()
{
FirstName = "Ali",
LastName = "Hasani",
AddressLine1 = "Addr..1",
AddressLine2 = "Addr..2",
PostalCode = "4321",
City = "Shiraz",
CountryCode = "IR"
};
var customer3 = new Customer()
{
FirstName = "Mohsen",
LastName = "Shams",
AddressLine1 = "Addr...1",
AddressLine2 = "Addr...2",
PostalCode = "5678",
City = "Ahwaz",
CountryCode = "IR"
};
CDbOperations db = new CDbOperations(session);
db.AddNewCustomers(customer1, customer2, customer3);
CLinqTest lt = new CLinqTest(session);
foreach (Customer customer in lt.GetAllCustomers())
{
Console.WriteLine("Customer: LastName = {0}", customer.LastName);
}
}
Console.WriteLine("Press a key...");
Console.ReadKey();
}
مهمترین مزیت استفاده از LINQ در این نوع کوئریها نسبت به روشهای دیگر، استفاده از کدهای strongly typed دات نتی تحت نظر کامپایلر است، نسبت به رشتههای معمولی SQL که کامپایلر کنترلی را بر روی آنها نمیتواند داشته باشد (برای مثال اگر نوع یک ستون تغییر کند یا نام آن، در حالت استفاده از LINQ بلافاصله یک خطا را از کامپایلر جهت تصحیح مشکلات دریافت خواهیم کرد که این مورد در زمان استفاده از یک رشته معمولی صادق نیست). همچنین مزیت فراهم بودن Intellisense را حین نوشتن کوئریهایی از این دست نیز نمیتوان ندید گرفت.
مثالی دیگر:
لیست تمام مشتریهای شیرازی را نمایش دهید:
ابتدا متد GetCustomersByCity را به کلاس CLinqTest فوق اضافه میکنیم:
public List<Customer> GetCustomersByCity(string city)
{
using (ISession session = _factory.OpenSession())
{
var query = from x in session.Linq<Customer>()
where x.City == city
select x;
return query.ToList();
}
}
foreach (Customer customer in lt.GetCustomersByCity("Shiraz"))
{
Console.WriteLine("Customer: LastName = {0}", customer.LastName);
}
لیست کامل دیتابیسهای پشتیبانی شده توسط NHibernate را در این آدرس میتوانید مشاهده نمائید. (البته به نظر لیست آن، آنچنان هم به روز نیست؛ چون در نگارش آخر NHibernate ، پشتیبانی از اس کیوال سرور 2008 هم اضافه شده است)
نکته:
در کوئریهای مثالهای فوق همواره باید session.Linq<T> را ذکر کرد. اگر علاقمند بودید شبیه به روشی که در LINQ to SQL موجود است مثلا db.TableName بجای session.Linq<T> در کوئریها ذکر گردد، میتوان اصلاحاتی را به صورت زیر اعمال کرد:
یک کلاس جدید را به نام SampleContext به برنامه کنسول جاری با محتویات زیر اضافه نمائید:
using System.Linq;
using NHibernate;
using NHibernate.Linq;
using NHSample1.Domain;
namespace ConsoleTestApplication
{
class SampleContext : NHibernateContext
{
public SampleContext(ISession session)
: base(session)
{ }
public IOrderedQueryable<Customer> Customers
{
get { return Session.Linq<Customer>(); }
}
public IOrderedQueryable<Employee> Employees
{
get { return Session.Linq<Employee>(); }
}
public IOrderedQueryable<Order> Orders
{
get { return Session.Linq<Order>(); }
}
public IOrderedQueryable<OrderItem> OrderItems
{
get { return Session.Linq<OrderItem>(); }
}
public IOrderedQueryable<Product> Products
{
get { return Session.Linq<Product>(); }
}
}
}
سپس بازنویسی متد GetCustomersByCity بر اساس SampleContext فوق به صورت زیر خواهد بود که به کوئریهای LINQ to SQL بسیار شبیه است:
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHSample1.Domain;
namespace ConsoleTestApplication
{
class CSampleContextTest
{
ISessionFactory _factory;
public CSampleContextTest(ISessionFactory factory)
{
_factory = factory;
}
public List<Customer> GetCustomersByCity(string city)
{
using (ISession session = _factory.OpenSession())
{
using (SampleContext db = new SampleContext(session))
{
var query = from x in db.Customers
where x.City == city
select x;
return query.ToList();
}
}
}
}
}
و در تکمیل این بحث، میتوان به لیستی از 101 مثال LINQ ارائه شده در MSDN اشاره کرد که یکی از بهترین و سریع ترین مراجع یادگیری مبحث LINQ است.
ادامه دارد ...
وبلاگها و سایتهای ایرانی
- قسمت دوم مروری بر GDI+ (این دوستان هم تاریخ RSS اشان شمسی است)
Visual Studio
ASP. Net
طراحی وب
اسکیوال سرور
به روز رسانیها
سیشارپ
عمومی دات نت
PHP
ویندوز
گوگل
متفرقه
یک اپلیکیشن با SQL Membership بسازید
حال با استفاده از ابزار ASP.NET Configuration دو کاربر جدید بسازید: oldAdminUser و oldUser.
نقش جدیدی با نام Admin بسازید و کاربر oldAdminUser را به آن اضافه کنید.
بخش جدیدی با نام Admin در سایت خود بسازید و فرمی بنام Default.aspx به آن اضافه کنید. همچنین فایل web.config این قسمت را طوری پیکربندی کنید تا تنها کاربرانی که در نقش Admin هستند به آن دسترسی داشته باشند. برای اطلاعات بیشتر به این لینک مراجعه کنید.
پنجره Server Explorer را باز کنید و جداول ساخته شده توسط SQL Membership را بررسی کنید. اطلاعات اصلی کاربران که برای ورود به سایت استفاده میشوند، در جداول aspnet_Users و aspnet_Membership ذخیره میشوند. دادههای مربوط به نقشها نیز در جدول aspnet_Roles ذخیره خواهند شد. رابطه بین کاربران و نقشها نیز در جدول aspnet_UsersInRoles ذخیره میشود، یعنی اینکه هر کاربری به چه نقش هایی تعلق دارد.
برای مدیریت اساسی سیستم عضویت، مهاجرت جداول ذکر شده به سیستم جدید ASP.NET Identity کفایت میکند.
مهاجرت به Visual Studio 2013
- برای شروع ابتدا Visual Studio Express 2013 for Web یا Visual Studio 2013 را نصب کنید.
- حال پروژه ایجاد شده را در نسخه جدید ویژوال استودیو باز کنید. اگر نسخه ای از SQL Server Express را روی سیستم خود نصب نکرده باشید، هنگام باز کردن پروژه پیغامی به شما نشان داده میشود. دلیل آن وجود رشته اتصالی است که از SQL Server Express استفاده میکند. برای رفع این مساله میتوانید SQL Express را نصب کنید، و یا رشته اتصال را طوری تغییر دهید که از LocalDB استفاده کند.
- فایل web.config را باز کرده و رشته اتصال را مانند تصویر زیر ویرایش کنید.
- پنجره Server Explorer را باز کنید و مطمئن شوید که الگوی جداول و دادهها قابل رویت هستند.
- سیستم ASP.NET Identity با نسخه 4.5 دات نت فریم ورک و بالاتر سازگار است. پس نسخه فریم ورک پروژه را به آخرین نسخه (4.5.1) تغییر دهید.
پروژه را Build کنید تا مطمئن شوید هیچ خطایی وجود ندارد.
نصب پکیجهای NuGet
- Microsoft.AspNet.Identity.Owin
- Microsoft.Owin.Host.SystemWeb
- Microsoft.Owin.Security.Facebook
- Microsoft.Owin.Security.Google
- Microsoft.Owin.Security.MicrosoftAccount
- Microsoft.Owin.Security.Twitter
مهاجرت دیتابیس فعلی به سیستم ASP.NET Identity
در پنجره کوئری باز شده، تمام محتویات فایل Migrations.sql را کپی کنید. سپس اسکریپت را با کلیک کردن دکمه Execute اجرا کنید.
ممکن است با اخطاری مواجه شوید مبنی بر آنکه امکان حذف (drop) بعضی از جداول وجود نداشت. دلیلش آن است که چهار عبارت اولیه در این اسکریپت، تمام جداول مربوط به Identity را در صورت وجود حذف میکنند. از آنجا که با اجرای اولیه این اسکریپت چنین جداولی وجود ندارند، میتوانیم این خطاها را نادیده بگیریم. حال پنجره Server Explorer را تازه (refresh) کنید و خواهید دید که پنج جدول جدید ساخته شده اند.
لیست زیر نحوه Map کردن اطلاعات از جداول SQL Membership به سیستم Identity را نشان میدهد.
- aspnet_Roles --> AspNetRoles
- aspnet_Users, aspnet_Membership --> AspNetUsers
- aspnet_UsersInRoles --> AspNetUserRoles
ساختن مدلها و صفحات عضویت
کلاس User باید کلاس IdentityUser را که در اسمبلی Microsoft.AspNet.Identity.EntityFramework وجود دارد گسترش دهد. خاصیت هایی را تعریف کنید که نماینده الگوی جدول AspNetUser هستند. خواص ID, Username, PasswordHash و SecurityStamp در کلاس IdentityUser تعریف شده اند، بنابراین این خواص را در لیست زیر نمیبینید.
public class User : IdentityUser { public User() { CreateDate = DateTime.Now; IsApproved = false; LastLoginDate = DateTime.Now; LastActivityDate = DateTime.Now; LastPasswordChangedDate = DateTime.Now; LastLockoutDate = DateTime.Parse("1/1/1754"); FailedPasswordAnswerAttemptWindowStart = DateTime.Parse("1/1/1754"); FailedPasswordAttemptWindowStart = DateTime.Parse("1/1/1754"); } public System.Guid ApplicationId { get; set; } public string MobileAlias { get; set; } public bool IsAnonymous { get; set; } public System.DateTime LastActivityDate { get; set; } public string MobilePIN { get; set; } public string Email { get; set; } public string LoweredEmail { get; set; } public string LoweredUserName { get; set; } public string PasswordQuestion { get; set; } public string PasswordAnswer { get; set; } public bool IsApproved { get; set; } public bool IsLockedOut { get; set; } public System.DateTime CreateDate { get; set; } public System.DateTime LastLoginDate { get; set; } public System.DateTime LastPasswordChangedDate { get; set; } public System.DateTime LastLockoutDate { get; set; } public int FailedPasswordAttemptCount { get; set; } public System.DateTime FailedPasswordAttemptWindowStart { get; set; } public int FailedPasswordAnswerAttemptCount { get; set; } public System.DateTime FailedPasswordAnswerAttemptWindowStart { get; set; } public string Comment { get; set; } }
حال برای دسترسی به دیتابیس مورد نظر، نیاز به یک DbContext داریم. اسمبلی Microsoft.AspNet.Identity.EntityFramework کلاسی با نام IdentityDbContext دارد که پیاده سازی پیش فرض برای دسترسی به دیتابیس ASP.NET Identity است. نکته قابل توجه این است که IdentityDbContext آبجکتی از نوع TUser را میپذیرد. TUser میتواند هر کلاسی باشد که از IdentityUser ارث بری کرده و آن را گسترش میدهد.
در پوشه Models کلاس جدیدی با نام ApplicationDbContext بسازید که از IdentityDbContext ارث بری کرده و از کلاس User استفاده میکند.
public class ApplicationDbContext : IdentityDbContext<User> { }
مدیریت کاربران در ASP.NET Identity توسط کلاسی با نام UserManager انجام میشود که در اسمبلی Microsoft.AspNet.Identity.EntityFramework قرار دارد. چیزی که ما در این مرحله نیاز داریم، کلاسی است که از UserManager ارث بری میکند و آن را طوری توسعه میدهد که از کلاس User استفاده کند.
در پوشه Models کلاس جدیدی با نام UserManager بسازید.
public class UserManager : UserManager<User> { }
کلمه عبور کاربران بصورت رمز نگاری شده در دیتابیس ذخیره میشوند. الگوریتم رمز نگاری SQL Membership با سیستم ASP.NET Identity تفاوت دارد. هنگامی که کاربران قدیمی به سایت وارد میشوند، کلمه عبورشان را توسط الگوریتمهای قدیمی SQL Membership رمزگشایی میکنیم، اما کاربران جدید از الگوریتمهای ASP.NET Identity استفاده خواهند کرد.
کلاس UserManager خاصیتی با نام PasswordHasher دارد. این خاصیت نمونه ای از یک کلاس را ذخیره میکند، که اینترفیس IPasswordHasher را پیاده سازی کرده است. این کلاس هنگام تراکنشهای احراز هویت کاربران استفاده میشود تا کلمههای عبور را رمزنگاری/رمزگشایی شوند. در کلاس UserManager کلاس جدیدی بنام SQLPasswordHasher بسازید. کد کامل را در لیست زیر مشاهده میکنید.
public class SQLPasswordHasher : PasswordHasher { public override string HashPassword(string password) { return base.HashPassword(password); } public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) { string[] passwordProperties = hashedPassword.Split('|'); if (passwordProperties.Length != 3) { return base.VerifyHashedPassword(hashedPassword, providedPassword); } else { string passwordHash = passwordProperties[0]; int passwordformat = 1; string salt = passwordProperties[2]; if (String.Equals(EncryptPassword(providedPassword, passwordformat, salt), passwordHash, StringComparison.CurrentCultureIgnoreCase)) { return PasswordVerificationResult.SuccessRehashNeeded; } else { return PasswordVerificationResult.Failed; } } } //This is copied from the existing SQL providers and is provided only for back-compat. private string EncryptPassword(string pass, int passwordFormat, string salt) { if (passwordFormat == 0) // MembershipPasswordFormat.Clear return pass; byte[] bIn = Encoding.Unicode.GetBytes(pass); byte[] bSalt = Convert.FromBase64String(salt); byte[] bRet = null; if (passwordFormat == 1) { // MembershipPasswordFormat.Hashed HashAlgorithm hm = HashAlgorithm.Create("SHA1"); if (hm is KeyedHashAlgorithm) { KeyedHashAlgorithm kha = (KeyedHashAlgorithm)hm; if (kha.Key.Length == bSalt.Length) { kha.Key = bSalt; } else if (kha.Key.Length < bSalt.Length) { byte[] bKey = new byte[kha.Key.Length]; Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length); kha.Key = bKey; } else { byte[] bKey = new byte[kha.Key.Length]; for (int iter = 0; iter < bKey.Length; ) { int len = Math.Min(bSalt.Length, bKey.Length - iter); Buffer.BlockCopy(bSalt, 0, bKey, iter, len); iter += len; } kha.Key = bKey; } bRet = kha.ComputeHash(bIn); } else { byte[] bAll = new byte[bSalt.Length + bIn.Length]; Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); bRet = hm.ComputeHash(bAll); } } return Convert.ToBase64String(bRet); } }
دقت کنید تا فضاهای نام System.Text و System.Security.Cryptography را وارد کرده باشید.
متد EncodePassword کلمه عبور را بر اساس پیاده سازی پیش فرض SQL Membership رمزنگاری میکند. این الگوریتم از System.Web گرفته میشود. اگر اپلیکیشن قدیمی شما از الگوریتم خاصی استفاده میکرده است، همینجا باید آن را منعکس کنید. دو متد دیگر نیز بنامهای HashPassword و VerifyHashedPassword نیاز داریم. این متدها از EncodePassword برای رمزنگاری کلمههای عبور و تایید آنها در دیتابیس استفاده میکنند.
سیستم SQL Membership برای رمزنگاری (Hash) کلمههای عبور هنگام ثبت نام و تغییر آنها توسط کاربران، از PasswordHash, PasswordSalt و PasswordFormat استفاده میکرد. در روند مهاجرت، این سه فیلد در ستون PasswordHash جدول AspNetUsers ذخیره شده و با کاراکتر '|' جدا شده اند. هنگام ورود کاربری به سایت، اگر کله عبور شامل این فیلدها باشد از الگوریتم SQL Membership برای بررسی آن استفاده میکنیم. در غیر اینصورت از پیاده سازی پیش فرض ASP.NET Identity استفاده خواهد شد. با این روش، کاربران قدیمی لازم نیست کلمههای عبور خود را صرفا بدلیل مهاجرت اپلیکیشن ما تغییر دهند.
کلاس UserManager را مانند قطعه کد زیر بروز رسانی کنید.
public UserManager() : base(new UserStore<User>(new ApplicationDbContext())) { this.PasswordHasher = new SQLPasswordHasher(); }
ایجاد صفحات جدید مدیریت کاربران
- فایلهای Register.aspx.cs و Login.aspx.cs از کلاس UserManager استفاده میکنند. این ارجاعات را با کلاس UserManager جدیدی که در پوشه Models ساختید جایگزین کنید.
- همچنین ارجاعات استفاده از کلاس IdentityUser را به کلاس User که در پوشه Models ساختید تغییر دهید.
- لازم است توسعه دهنده مقدار ApplicationId را برای کاربران جدید طوری تنظیم کند که با شناسه اپلیکیشن جاری تطابق داشته باشد. برای این کار میتوانید پیش از ساختن حسابهای کاربری جدید در فایل Register.aspx.cs ابتدا شناسه اپلیکیشن را بدست آورید و اطلاعات کاربر را بدرستی تنظیم کنید.
private Guid GetApplicationID() { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString)) { string queryString = "SELECT ApplicationId from aspnet_Applications WHERE ApplicationName = '/'"; //Set application name as in database SqlCommand command = new SqlCommand(queryString, connection); command.Connection.Open(); var reader = command.ExecuteReader(); while (reader.Read()) { return reader.GetGuid(0); } return Guid.NewGuid(); } }
var currentApplicationId = GetApplicationID(); User user = new User() { UserName = Username.Text, ApplicationId=currentApplicationId, …};
در ادامهی کار با ابزارهای پشتیبان گیری که داخل شاخه Bin قرار داشتند، ابزارهای دیگری را معرفی میکنیم.
MongoExport از اطلاعات داخل دیتابیس شما خروجی گرفته و آنرا به قالب مورد نظر بر میگرداند. تعدادی از پارامترهای آن به شرح زیر است:
نام پارامتر | شرح کارکرد |
c- یا collection-- | میتواند خروجی را به یک کالکشن خاص محدود کند. |
d- یا db-- | از دیتابیسی مشخص استفاده کند. |
u- یا username- | نام کاربری سرور |
p- یا password-- | کلمه عبور سرور |
dbpath-- | مسیر پوشهای را که دیتاها داخل آن است، دریافت میکند و به جای ایجاد یک Instance مستقیم، خروجی را ارائه میکند. توجه : در این حالت پوشه به طور کامل قفل خواهد شد و سرور نباید در حالت اجرا قرار گرفته باشد. |
DirectoryPerDb-- | در صورتیکه هر دیتابیسی دارای محل جداگانهای برای خروجی باشد. |
o- یا out-- | محل ذخیره خروجی را مشخص میکند. |
f- یا field-- | نام فیلدهایی که قرار است در خروجی ظاهر شوند. به شکل زیر نوشته میشود: field Title,ISBN-- |
fieldfile-- | معرفی نام فیلدها در یک فایل جداگانه. نام هر فیلد در یک خط باید قرار بگیرد. Title ISBN |
q- یا query-- | خروجی به شکل کوئری و جیسن در قالب رشته |
csv-- | خروجی csv به جای جیسن |
D:\Program Files\MongoDB\Server\3.4\bin>mongoexport -d publisher -c books -f Title,ISBN --csv -o D:\temp\books.csv 2017-03-04T22:50:20.671+0330 csv flag is deprecated; please use --type=csv instead 2017-03-04T22:50:20.673+0330 connected to: localhost 2017-03-04T22:50:20.673+0330 exported 7 records
توجه: نام فیلدها، CaseSensitive بوده و در غیر اینصورت، فیلد مورد نظر شامل ستونی خالی خواهد بود.
MongoImport هم برای ورود دادهها به کار میرود. پارامترهای این دستور همانند بالا است، ولی با چند پارامتر مهم دیگر که در پایین ذکر میشود:
پارامتر | شرح کارکرد |
ignoreBlanks | مقادیر خالی ندیده گرفته میشوند. |
type-- | نوع فایل ورودی چیست؟ json,tsv,csv |
upset | درج مقادیری که از قبل موجود هستند. |
upsertFields | همانند بالا فقط برای فیلدهایی که ذکر شدهاست. |
stopOnError | با برخورد به اولین خطا، کار ورود را نادیده بگیر. |
D:\Program Files\MongoDB\Server\3.4\bin>mongoimport -d publisher -c books -f Title,ISBN --type csv D:\temp\books.csv 2017-03-04T23:05:50.588+0330 connected to: localhost 2017-03-04T23:05:50.591+0330 imported 8 documents
کد بالا، فایل قبلی را به داخل فایل اضافه میکند.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; namespace Image2Base64Converter { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnOpen_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = false; ofd.Filter = "Pictures |*.bmp;*.jpg;*.jpeg;*.png"; if (ofd.ShowDialog(this) == DialogResult.OK) { txtImagePath.Text = ofd.FileName; } } private void btnConvert_Click(object sender, EventArgs e) { if (!File.Exists(txtImagePath.Text)) { MessageBox.Show("File not found!"); return; } btnCopy.Enabled = false; btnConvert.Enabled = false; txtOutput.Enabled = false; BackgroundWorker bworker = new BackgroundWorker(); bworker.DoWork += (o, a) => { string header = "data:image/{0};base64,"; header = string.Format(header, txtImagePath.Text.GetExtension()); StringBuilder data = new StringBuilder(); byte[] buffer; BinaryReader head = new BinaryReader( new FileStream(txtImagePath.Text, FileMode.Open)); buffer = head.ReadBytes(6561); while (buffer.Length > 0) { data.Append(Convert.ToBase64String(buffer)); buffer = head.ReadBytes(6561); } head.Close(); head.Dispose(); this.Invoke(new Action(() => { txtOutput.ResetText(); txtOutput.AppendText(header); txtOutput.AppendText(data.ToString()); btnCopy.Enabled = true; btnConvert.Enabled = true; txtOutput.Enabled = true; })); }; bworker.RunWorkerAsync(); } private void btnCopy_Click(object sender, EventArgs e) { Clipboard.SetText(txtOutput.Text); } } public static class ExtensionMethods { public static string GetExtension(this string str) { string ext = string.Empty; for (int i = str.Length - 1; i >= 0; i--) { if (str[i] == '.') { break; } ext = str[i] + ext; } return ext; } } }