EF Code First #13
شاید مایکروسافت می خواست یک MSIL برای تکنولوژی Data Access داشته باشد!
پر نکردن فیلدهای Textbox فایل PDF
onFillAcroForm: (data, form, pdfStamper) => { form.GenerateAppearances = true;
وبلاگهای ایرانی
- گزارشی از PDC 2008 microsoftpdc.com و یک سری ویدیوی مرتبط با دات نت
Visual Studio
- ویژوال استودیو 2010 و دات نت فریم ورک 4، نگارش CTP برای دریافت!
- و تازههای آن (توسط یکی از اعضای اصلی تیم NHibernate)
- دمویی از ایجاد نمودارهای UML با VS.Net 2010 . (خوشبختانه حجم این مورد در مقایسه با دموهای PDC2008 بسیار کمتر است!)
امنیت اطلاعات
ASP. Net
- نگارش CTP2 پروژهVelocity . (این پروژه قرار است راه حل جامع caching مایکروسافت برای ASP.Net باشد)
طراحی وب
اسکیوال سرور
به روز رسانیها
- سرویس پک 3 بتا اس کیوال سرور 2005 هم ارائه شد (نگارش نهایی آن تا پایان سال جاری میلادی ارائه میشود.)
ابزارها
- مجموعه CodeRush یک نگارش express رایگان نیز ارائه داد. (به نظر من نگارش کامل آن بهترین ابزار refactoring برای VS.Net است)
سیشارپ
- ویژگیهای جدید C# 4.0 ، قسمت اول، واژه کلیدی جدیدی به نام dynamic
- ویژگیهای جدید C# 4.0 ، قسمت دوم، پارامترهای پیش فرض (یا آرگومانهای اختیاری). (چیزی شبیه به VB !! بدون نیاز به overloading برای پیاده سازی آن)
دلفی
- محصور کننده جدید SQLite برای دلفی 2009 (رفع مشکلات عدم سازگاری نگارش قبلی با سیستم یونیکد دلفی 2009)
- ویدیویی از Delphi Prism . (نگارشی از دلفی که به شکل افزونهای کاملا یکپارچه در VS.Net قابل دسترسی است)
SharePoint
- سطوح دسترسی کدها در SharePoint . (به شکل زیبایی این مساله را که مشکل اولیه اکثر وب پارت نویسها است توضیح داده است)
ویندوز
متفرقه
روش پیاده سازی دریافت اطلاعات شخصی در ASP.NET Core Identity 2.1
اگر به IdentityUser نگارشهای اخیر ASP.NET Core Identity دقت کنید، شامل ویژگی جدید PersonalData نیز هست:
public class IdentityUser<TKey> where TKey : IEquatable<TKey> { [PersonalData] public virtual TKey Id { get; set; }
سپس زمانیکه در تصویر فوق بر روی دکمهی download کلیک کرد، ابتدا توسط userManager.GetUserAsync، اطلاعات کاربر جاری از بانک اطلاعاتی دریافت شده و سپس حلقهای بر روی تمام خواص شیء IdentityUser تشکیل میشود. در اینجا هر کدام که مزین به PersonalDataAttribute بود، مقدارش دریافت شده و به دیکشنری personalData اضافه میشود.
var personalData = new Dictionary<string, string>(); var personalDataProps = typeof(TUser).GetProperties().Where( prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute))); foreach (var p in personalDataProps) { personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null"); }
Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json"); return new FileContentResult(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(personalData)), "text/json");
روش پیاده سازی دادن «حق فراموش شدن» به کاربران
اگر به تصویر ارسال شده دقت کنید، یک دکمهی Delete نیز در آن قرار دارد. کار آن، حذف واقعی و فیزیکی کاربر جاری و تمام اطلاعات وابستهی به او از بانک اطلاعاتی است. این دکمه نیز بدون هیچ واسطی در اختیار خود کاربر قرار گرفتهاست. یعنی به این صورت نیست که ابتدا فرمی را پر کند و سپس شخص دیگری اکانت او را حذف کند.
روش پیاده سازی آن نیز به صورت زیر است:
var user = await _userManager.GetUserAsync(User); if (user == null) { return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } RequirePassword = await _userManager.HasPasswordAsync(user); if (RequirePassword) { if (!await _userManager.CheckPasswordAsync(user, Input.Password)) { ModelState.AddModelError(string.Empty, "Password not correct."); return Page(); } }
var result = await _userManager.DeleteAsync(user);
و در آخر، کوکی جاری شخص لاگین شده را نیز حذف میکند تا برای همیشه با او خداحافظی کند!
await _signInManager.SignOutAsync();
قابلیت چند زبانه و Localization در AngularJs- بخش چهارم و نهایی: Best Practiceهای angular-translate
ex7_load_static_files
<script src="Scripts/angular.js"></script> <script src="Scripts/angular-cookies.js"></script> <script src="Scripts/angular-translate.js"></script> <script src="Scripts/angular-translate-storage-cookie.js"></script> <!-- for override loader methods in angular translate --> <script src="/src/service/loader-static-files.js"></script>
// Register a loader for the static files // So, the module will search missing translation tables under the specified urls. // Those urls are [prefix][langKey][suffix]. $translateProvider.useStaticFilesLoader({ prefix: '/l10n/', suffix: '.json' });
حال ببینیم که این فرآیند در loader-static-files چگونه پیاده سازی شده است. در این فایل یک متد load نوشته شده است که فایلهای static را طبق یک الگوی مشتمل بر prefix و suffix از سرور میخواند. لزومی ندارد که شما فایلها را حتما به صورت JSON و با این پسوند ذخیره کنید. اما چیزی که قطعی است این است که فایلها حتما باید به صورت key value ذخیره شده باشند.
تکه کد زیر اطلاعات فایل loader-static-files را نمایش میدهد.
angular.module('pascalprecht.translate') .factory('$translateStaticFilesLoader', $translateStaticFilesLoader); function $translateStaticFilesLoader($q, $http) { 'use strict'; return function (options) { if (!options || (!angular.isArray(options.files) && (!angular.isString(options.prefix) || !angular.isString(options.suffix)))) { throw new Error('Couldn\'t load static files, no files and prefix or suffix specified!'); } if (!options.files) { options.files = [{ prefix: options.prefix, suffix: options.suffix }]; } var load = function (file) { if (!file || (!angular.isString(file.prefix) || !angular.isString(file.suffix))) { throw new Error('Couldn\'t load static file, no prefix or suffix specified!'); } var deferred = $q.defer(); $http(angular.extend({ url: [ file.prefix, options.key, file.suffix ].join(''), method: 'GET', params: '' }, options.$http)).success(function (data) { deferred.resolve(data); }).error(function () { deferred.reject(options.key); }); return deferred.promise; }; var deferred = $q.defer(), promises = [], length = options.files.length; for (var i = 0; i < length; i++) { promises.push(load({ prefix: options.files[i].prefix, key: options.key, suffix: options.files[i].suffix })); } $q.all(promises).then(function (data) { var length = data.length, mergedData = {}; for (var i = 0; i < length; i++) { for (var key in data[i]) { mergedData[key] = data[i][key]; } } deferred.resolve(mergedData); }, function (data) { deferred.reject(data); }); return deferred.promise; }; } $translateStaticFilesLoader.displayName = '$translateStaticFilesLoader';
همانطور که ملاحظه میکنید، کد فوق یک سرویس با نام $translateStaticFilesLoader را تعریف نموده است. در صورتیکه ما در کنترلر فایل ex7، اصلا نامی از آن نبردیم و تنها از $translateProvider.useStaticFilesLoader استفاده نمودیم! جواب در نحوهی نگارش کد angular-translate نهفته است. در خط 866 فایل angular-translate تکه کد زیر مربوط به تعریف translateStaticFileLoader میباشد. همانطور که ملاحظه میکنید سرویس translateStaticFilesLoader درون فضای نام سرویس translateTable قرار گرفته است. بنابراین ما تنها با تعریف سرویس translateStaticFilesLoader، در حقیقت آن را override نمودهایم. در کد نمونهای که در بخشهای قبلی قرار دادهام یک فایل translate.js نیز قرار دارد که در فولدر src/services قرار گرفته است. این فایل نیز برخی از امکانات و سرویسهای built-in درون angular-translate را سفارشی نموده است.
/** * @ngdoc function * @name pascalprecht.translate.$translateProvider#useStaticFilesLoader * @methodOf pascalprecht.translate.$translateProvider * * @description * Tells angular-translate to use `$translateStaticFilesLoader` extension service as loader. * * @param {Object=} options Optional configuration object */ this.useStaticFilesLoader = function (options) { return this.useLoader('$translateStaticFilesLoader', options); };
در این 4 مجموعه سعی کردم تمامی آنچه را که برای ایجاد قابلیت چند زبانه و localization نیاز است و حیاتی بود، تشریح کنم. بنابراین تا کنون دانش خوبی دربارهی این کتابخانه کسب نمودهاید. باقی تمرینها را میتوانید بر حسب نیاز با استفاده از مستندات موجود در angular-translate مطالعه و استفاده نمایید.
قوانین بقای کسب وکارهای نوپا
آپلود فایل توسط فرمهای پویای jqGrid
- مستقل هست از مباحث اعتبارسنجی سمت کاربر تعریف شده توسط data annotationها. از افزونهی jQuery Validator استفاده نمیکند. سیستم خاص خودش را دارد. فقط از اعتبارسنجی سمت سرور حاصل data annotationها میشود در آن استفاده کرد.
- Data Processing Extension
- Using SSRS In ASP.NET MVC Application
- Microsoft.Reporting.WebForms.ReportDataSource