- Added ShouldSkipRow, ShouldSkipFooter & ShouldSkipHeader events. See Events/EventsPdfReport.cs sample for more info. - Updated the project to use iTextSharp.5.5.5. - Improved: Font styles (size, color etc.) are not applied if HTML fragment is rendered and does not have an explicit font-family style. patch #17253. - Improved: Properly aligning the aggregate value, based on the column information. #2395
مدل بایندر برای تاریخ شمسی
How To Use: //In Startup.cs: public void ConfigureServices(IServiceCollection services) { services.AddMvcCore(options => { options.ModelBinderProviders.Insert(0, new PersianDateModelBinderProvider()); }); } //In Actions: public async Task<IActionResult> SampleAction(DateTime birthDate) { if (ModelState.IsValid) { //birthDate is valid } else { birthDate is wrong } ... }
LINQPad is a powerful testing tool for all .NET developers that can help them deliver solutions in less time. In Getting the Most from LINQPad Succinctly, returning Succinctly series author José Roberto Olivas Mendoza lays out different ways to extend the functionality built into LINQPad. In this ebook, you’ll learn how to use LINQPad to query Entity Framework models in Visual Studio, how to work with the LINQPad command-line utility, how to write your own extensions and visualizers, and how to write custom data context drivers.
-
A Quick Tour of LINQPad
-
LINQPad and Entity Framework
-
LINQPad Scripting
-
LINQPad Extensibility
-
Custom Data Context Drivers
قرار دادن Power BI در برنامه خودتان
بررسی تغییرات Blazor در دات نت 8
What's New in Blazor for .NET 8
Come find out about the future of Blazor in .NET 8! We'll explore all the upcoming features and improvements, including our effort to create a unified full stack web UI programming model that combines the strengths of client and server. We hope to see you there!
You will learn:
How Blazor is becoming the best option for full stack web development
How Blazor in .NET 8 will provide full flexibility to build web apps however works best for you
How to try out the latest Blazor features in .NET 8
اگر چک لیستهای SEO وب سایت ها را مشاهده کنیم، میتوانیم آنها را در دو دستهی کلی بهینه سازی درونی و برونی وب سایت در نظر بگیریم:
Off-Page Optimization یا برونی ، که بیشتر بر دوش مشاوران سئو و خود مدیران وب سایت است.(link building ، فعالیت در شبکه اجتماعی و ...)
و اما در حوزه On-Page Optimization یا درونی که بخشهای مهمی از آن وظیفهی مابرنامه نویسها است.(H1 Tag ، URL Naming ، Meta Tags ، عنوان صفحه و ...)
[البته عامل درونی بهینه سازی محتوا (Content Optimization) که مهمترین عامل در الگوریتمهای نسل جدید موتورهای جستجو و همچنین الگوریتم جدید گوگل (و +) به حساب میآید بر عهده مشاوران سئو و خود مدیران وب سایت میباشد]
در ادامه به ارائه چند راهکار جهت بهینه سازی برنامههای وب ASP.NET مان برای موتورهای جستجو میپردازیم:
1.متدی برای ایجاد عنوان سایت
private const string SeparatorTitle = " - "; private const int MaxLenghtTitle = 60; public static string GeneratePageTitle(params string[] crumbs) { var title = ""; for (int i = 0; i < crumbs.Length; i++) { title += string.Format ( "{0}{1}", crumbs[i], (i < crumbs.Length - 1) ? SeparatorTitle : string.Empty ); } title = title.Substring(0, title.Length <= MaxLenghtTitle ? title.Length : MaxLenghtTitle).Trim(); return title; }
- MaxLenghtTitle پیشنهادی برای عنوان سایت 60 میباشد.
2.متدی برای ایجاد متاتگ صفحات سایت
public enum CacheControlType { [Description("public")] _public, [Description("private")] _private, [Description("no-cache")] _nocache, [Description("no-store")] _nostore }
private const int MaxLenghtTitle = 60; private const int MaxLenghtDescription = 170; private const string FaviconPath = "~/cdn/ui/favicon.ico"; public static string GenerateMetaTag(string title, string description, bool allowIndexPage, bool allowFollowLinks, string author = "", string lastmodified = "", string expires = "never", string language = "fa", CacheControlType cacheControlType = CacheControlType._private) { title = title.Substring(0, title.Length <= MaxLenghtTitle ? title.Length : MaxLenghtTitle).Trim(); description = description.Substring(0, description.Length <= MaxLenghtDescription ? description.Length : MaxLenghtDescription).Trim(); var meta = ""; meta += string.Format("<title>{0}</title>\n", title); meta += string.Format("<link rel=\"shortcut icon\" href=\"{0}\"/>\n", FaviconPath); meta += string.Format("<meta http-equiv=\"content-language\" content=\"{0}\"/>\n", language); meta += string.Format("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\n"); meta += string.Format("<meta charset=\"utf-8\"/>\n"); meta += string.Format("<meta name=\"description\" content=\"{0}\"/>\n", description); meta += string.Format("<meta http-equiv=\"Cache-control\" content=\"{0}\"/>\n", EnumExtensions.EnumHelper<CacheControlType>.GetEnumDescription(cacheControlType.ToString())); meta += string.Format("<meta name=\"robots\" content=\"{0}, {1}\" />\n", allowIndexPage ? "index" : "noindex", allowFollowLinks ? "follow" : "nofollow"); meta += string.Format("<meta name=\"expires\" content=\"{0}\"/>\n", expires); if (!string.IsNullOrEmpty(lastmodified)) meta += string.Format("<meta name=\"last-modified\" content=\"{0}\"/>\n", lastmodified); if (!string.IsNullOrEmpty(author)) meta += string.Format("<meta name=\"author\" content=\"{0}\"/>\n", author); //------------------------------------Google & Bing Doesn't Use Meta Keywords ... //meta += string.Format("<meta name=\"keywords\" content=\"{0}\"/>\n", keywords); return meta; }
-
MaxLenghtDescription پیشنهادی برای متاتگ توضیح سایت 170 می باشد.
- آشنایی با متاتگها (Meta tags) و کاربرد آنها در صفحات وب (HTML)
- برای کاربرد allowIndexPage و allowFollowLinks هم میتوانید به لینک بالا و بررسی متاتگ robots بپردازید.
- با توجه به اهمیت شبکههای اجتماعی متاتگهای شبکههای اجتماعی (+ و +) را هم نباید از قلم انداخت.
- برای دریافت Description نوع سفارشی CacheControlType از پروژه متدهای الحاقی علیرضا اسم رام استفاده کردم.
3.متدی برای ایجاد Slug ( اسلاگ آدرسی با مفهوم برای بکار بردن در URL ها است که دوستدار موتورهای جستجو میباشد)
private const int MaxLenghtSlug = 45; public static string GenerateSlug(string title) { var slug = RemoveAccent(title).ToLower(); slug = Regex.Replace(slug, @"[^a-z0-9-\u0600-\u06FF]", "-"); slug = Regex.Replace(slug, @"\s+", "-").Trim(); slug = Regex.Replace(slug, @"-+", "-"); slug = slug.Substring(0, slug.Length <= MaxLenghtSlug ? slug.Length : MaxLenghtSlug).Trim(); return slug; } private static string RemoveAccent(string text) { var bytes = Encoding.GetEncoding("UTF-8").GetBytes(text); return Encoding.UTF8.GetString(bytes); }
- MaxLenghtSlug پیشنهادی برای عنوان سایت 45 میباشد.
نمونه ای از کاربرد توابع :
Head.InnerHtml = SEO.GenerateMetaTag ( title: SEO.GeneratePageTitle(".NET Tips", "آرشیو مطالب", "ASP.NET MVC #1"), description: "چرا ASP.NET MVC با وجود فریم ورک پختهای به نام ASP.NET web forms، اولین سؤالی که حین سوئیچ به ASP.NET MVC مطرح میشود این است: «برای چی؟». بنابراین تا به این سؤال پاسخ داده نشود، هر نوع بحث فنی در این مورد بی فایده است.", allowIndexPage: true, allowFollowLinks: true, author: "وحید نصیری", cacheControlType: SEO.CacheControlType._private );
<title>.NET Tips - آرشیو مطالب - ASP.NET MVC #1</title> <link rel="shortcut icon" href="../../cdn/images/ui/favicon.ico"/> <meta http-equiv="content-language" content="fa"/> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <meta charset="utf-8"/> <meta name="description" content="چرا ASP.NET MVC ؟با وجود فریم ورک پختهای به نام ASP.NET web forms، اولین سؤالی که حین سوئیچ به ASP.NET MVC مطرح میشود این است: «برای چی؟». بن ..."/> <meta http-equiv="Cache-control" content="private"/> <meta name="robots" content="index, follow" /> <meta name="expires" content="never"/> <meta name="author" content="وحید نصیری"/>
if (!(context.SecurityToken is JwtSecurityToken accessToken) || string.IsNullOrWhiteSpace(accessToken.RawData) || !await _tokenStoreService.IsValidTokenAsync(accessToken.RawData, userId)) { context.Fail("This token is not in our database."); return; }
if (!(context.SecurityToken is JsonWebToken accessToken) || string.IsNullOrWhiteSpace(accessToken.UnsafeToString()) || !await tokenStoreService.IsValidTokenAsync(accessToken.UnsafeToString(), userId)) { context.Fail("This token is not in our database."); return; }
نکتهای در مورد مدیریت طول عمر اشیاء در حالت HybridHttpOrThreadLocalScoped در برنامههای دسکتاپ
cfg.For<IUnitOfWork>().Use(() => new MyWpfFrameworkContext());
ThreadLocal - A single instance will be created for each requesting thread. Caches the instances with ThreadLocalStorage. Hybrid - Uses HttpContext storage if it exists, otherwise uses ThreadLocal storage
خوب، مشکل کجا است؟ در یک برنامه دسکتاپ اگر ترد جدیدی را ایجاد نکنیم، کل برنامه در طول مدتی که در حال اجرا است در یک ترد اصلی اجرا میشود. در نتیجه استفاده از حالت HybridHttpOrThreadLocalScoped در برنامههای دسکتاپ، بسیار شبیه به حالت Singleton است. به این ترتیب با بسته شدن یک پنجره یا هدایت به صفحهای دیگر، Context برنامه و EF رها نخواهند شد (چون تضمین شده است که یک وهله از این شیء در طول عمر ترد جاری وجود داشته باشد). نتیجه آن روبرو شدن با خطاهایی است که ردیابی و دیباگ بسیار مشکلی دارند. برای مثال چندی قبل در سایت مطرح شده بود که چرا در یک برنامه WinForms خطای زیر را دریافت میکنم:
An object with the same key already exists in the ObjectStateManager
در برنامههای وب چطور؟
در برنامههای وب، به ازای هر درخواست رسیده، یک ترد جدید ایجاد میشود. به همین جهت استفاده از حالت HybridHttpOrThreadLocalScoped برای داشتن تنها یک Context در طول یک درخواست ضروری است.
نتیجه گیری
در برنامههای دسکتاپ خود اگر از ترد استفاده نمیکنید، از حالت HybridHttpOrThreadLocalScoped برای مدیریت طول عمر UOW استفاده نکنید.