اشتراک‌ها
SQL Server Management Studio 18.7 منتشر شد

The 18.7 release is the third major release of SSMS in 2020 and expands on our commitment to providing quality tooling for database administration. Key changes include:

  • Fix for Database diagrams add table dialog.
  • Installation of Azure Data Studio.
  • Extended Events script with wait type name. 
SQL Server Management Studio 18.7 منتشر شد
نظرات مطالب
ایجاد کپچایی (captcha) سریع و ساده در ASP.NET MVC 5
با تشکر از پست خوبتون
فقط مساله ای که برای من اتفاق افتاد این بود که زمانی که دکمه مربوط به بازسازی کپچا رو می‌زدم تصویر از کش خونده می‌شد و تصویر جدید نمایش داده نمی‌شد که برای حل این موضوع کافیست کد ایجکس برای آپدیت کپچا توسط دکمه refresh را به صورت زیر بنویسید:
jQuery('#refresh').on({
                'click': function () {
                    var random = new Date();
                    jQuery.ajax({
                        url: '@Url.Action("CaptchaImage","Captcha")',
                        type: "GET",
                        data: null,
                        success: function (result) {
                            jQuery("#imgcpatcha").attr("src", "/Captcha/CaptchaImage?" + random + result);
                        }
                    });
                }
                });
مسیرراه‌ها
WPF
          مطالب
          Navigation در AJAX - لینک دائمی برای محتوای AJAX
          استفاده از AJAX به ما امکان می‌دهد قسمتی از صفحه را بدون رفتن به صفحه‌ی جدید بروز کنیم. 
          فرض کنید لیستی از اسامی و قیمت کالاها را در اختیار داریم ، کاربر روی دکمه‌ی جزییات کالا کلیک می‌کند ، جزییات کالا را با یک درخواست AJAX بارگزاری می‌کنیم و در یک Dialog به کاربر نمایش می‌دهیم .
          آیا لینک دائمی برای این محتوای لود شده وجود دارد ؟ منظور این است آیا کاربر می‌تواند بدون تکرار مراحل قبلی و با استفاده از یک لینک جزییات آن کالا را مشاهده کند ؟ 
          برای فراهم ساختن یک لینک دائمی برای محتوای AJAX راه حل استفاده از windows.location.hash  هست.
          در این http://example.com/blah#456 مقدار HashTag ما برابر با 456 می‌باشد. 
          مقدار HashTag به سرور ارسال نمی‌شود و فقط سمت کلاینت قابل استفاده هستند.
          <span class='button goodDetail' id='123' >جزییات کالا</span>
          
          به Span بالا یک Attribute سفارشی افزوده شده که حاوی کلید اصلی کالا می‌باشد. هنگامی که روی این دکمه کلیک می‌شود با یک درخواست AJAX اطلاعات جزییات این کالا واکشی می‌شود و قسمتی از صفحه بروزسانی می‌شود : 
          $('.goodDetail').click(function(){
          //add to hash data that you need to make the AJAX request later
          $(window).location.hash = $(this).attr('id');
          $.ajax({
           type: "POST",
           url: 'some url',
           dataType: "html",
           data:'GoodId='+$(this).attr('id'),
           success: function(html) {
                           //do something
           } })  })
          
          در خط سوم کد بالا Location hash را به کلید اصلی کالایی که روی آن کلیک شده است مقدار داده ایم. بعد از کلیک روی آن دکمه URL ما اینگونه خواهد بود : www.mysite.com/goods.aspx#123
          123 همان کلید اصلی کالا است که در Attribute سفارشی در دکمه‌ی جزییات کالا نگهداری می‌شده ، پس انتظار می‌رود اگر کاربر www.mysite.com/goods.aspx#123 را وارد کرد همان درخواست AJAX اجرا شود و جزییات کالای 123 به کاربر نشان داده شود. 
          در Document Ready صفحه‌ی جزییات کالا چک می‌کنیم آیا Hash tag وجود دارد یا خیر ، اگر وجود داشت مقدار آن را به دست می‌آوریم ، درخواست AJAX را صادر می‌کنیم و اطلاعات کالای 123 را به کاربر نشان می‌دهیم : 
          $(document).ready(function(){
          if ($(window).location.hash.length))
          {
          //we will use $(window).location.hash.replace('#','') in the "data" section of the AJAX request
          $.ajax({
           type: "POST",
           url: current_url,
           dataType: "html",
           data:'GoodId='+$(window).location.hash.replace('#',''),
           success: function(html) {
                           //do something
           }  })  
          }
          });
          
          همانطور که مشاهده می‌کنید برای به دست آوردن مقدار Hashtag از کد پراپرتی hash شیء location استفاده شده ، این پراپرتی علامت # را هم بر می‌گرداند ، پس قبل یا بعد از ارسال مقدار این پراپرتی به سرور باید این علامت را حذف کرد.
          این مثال Online را مشاهده کنید. 
          نظرات مطالب
          TwitterBootstrapMVC
          - داره (مجانی نیست). البته فایل‌هایی که ایشون پیوست کردند به نظر محدودیت ندارند.
          - ضمنا باز هم هستند یک سری Wrapper برای بوت استرپ که می‌توانند مورد استفاده قرار گیرند:
          TwitterBootstrapMvc (نسخه سورس باز مطلب جاری است)
          Mvc Bootstrap Html Helper Extensions
          Bootstrap Helpers (معرفی در اینجا)
          Twitter Bootstrap Controls for ASP.NET
          مطالب
          آشنایی و بررسی ابزار Version Manager
          در مطلبی با نسخه بندی و چرخه انتشار نرم افزار آشنا شدید. اما کمبود ابزاری کارآمد و حرفه ای در ویژوال استادیو من را بر آن داشت تا افزونه‌ای را تهیه و در دسترس تمامی توسعه دهندگان قرار دهم. پس از مطالعه و بررسی روش‌های نگارش بندی نرم افزار و ابزار‌های موجود، دو روش عمده نسخه بندی نرم افزار وجود دارد که در زیر آورده شده است.
          • نسخه بندی معنایی
          • نسخه بندی استاندارد مایکروسافت
          در روش معنایی چهار قسمت نسخه بندی Major.Minor.Build.Revision به صورت زیر افزایش و تغییر می‌یابد:
          1. Revision تا 1000 افزایش می‌یابد
          2. در اجرای بعدی به 0 تنظیم شده و قسمت Build بعلاوه 1 می‌شود.
          3. Build تا 100 افزایش می‌یابد
          4. در اجرای بعدی Build به 0 تنظیم شده و قسمت Minor بعلاوه 1 می‌شود و Revision هم 0 می‌شود.
          5. Minor تا 10 افزایش می‌یابد.
          6. در اجرای بعدی Minor به 0 تنطیم شده، قسمت Major بعلاوه 1 می‌شود و قسمت‌های قبل همه 0 می‌شوند. 
          در روش استاندارد ماکروسافت مقادیر قسمت‌های Build و Revision از الگوریتم زیر محاسبه می‌شود.
          1. مقدار Build از مجموع روزهای که از تاریخ پروژه گذشته است بدست می‌آید.
          2. مقدار Revision از مجموع ثانیه‌های که از نیمه شب محلی روز جاری تا زمان اجرای پروژه تقسم بر دو بدست می‌آید.
          3. مقادیر Major و Minor هم با توجه تولید نسخه جدید و تغییرات عمده در نرم افزار بصورت دستی تغییر می‌یابد.
          راهنمای نصب و اجرا:
          ابتدا افزونه Version Manager را از سایت ویژوال استادیو گالری دریافت و نصب کنید.
          سپس از منوی View > Other Windows > Version Manager را انتخاب کنید.

          پس از باز شدن پنجره Version Manager پروژه‌های Solution جاری بارگذاری و  Assembly Version و File Version هر پروژه را می‌توانید به راحتی مشاهده و یا تغییر دهید.

          اگر بخواهید بصورت خودکار بر اساس شمای انتخاب شده، نسخه نرم افزار را افزایش دهید، شمای نسخه بندی را انتخاب کنید. در دو زمان Build و یا Rebuild پروژه می توان نسخه را افزایش داد.

          Semantic Versioning:

          1. گزینه Semantic Versioning را از قسمت Version Style انتخاب کنید.
          2. گزینه Increment Action قسمتی از نگارش که می‌خواهید شمای  نسخه بندی بر روی آن اعمال شود را مشخص می‌کند. که دو گزینه Build یا Revision وجود دارد
          3. گزینه Increment Event زمان رویداد اعمال شمای انتخاب شده را مشخص می‌سازد.
          4. تنظیمات را ذخیره و پروژه خود را Rebuild نمایید.
          5. در پنجره Output نسخه جدید نشان داده می‌شود.

          Microsoft DateTime:

          1. گزینه Microsoft DateTime را از قسمت Version Style انتخاب کنید.

          2. تاریخ شروع پروژه بصورت خودکار خوانده و نمایش داده می‌شود یا تاریخ شروع پروژه را انتخاب کنید
          3. با توجه به انتخاب Increment Action نسخه جدید محاسبه می‌شود.
          4. پروژه را Rebuild و نسخه جدید را مشاهده نمایید.

            همچنین از پروژه‌های #C و VB.NET و C++ Managed  پشتیبانی می‌کند

            این ابزار هنوز در نگارش بتا است و ممکن است باگ‌هایی داشته باشد.

            نظرات و پیشنهادات شما توسعه دهندگان عزیز می‌تواند موجب هر چه بهتر و کامل‌تر شدن این ابزار باشد.

          مطالب
          #Defensive Code in C - قسمت سوم

          رفع مشکلات:  

          در قسمت قبل با ذکر یک مثال و بیان مشکلات آن از دیدگاه اصول Defensive Code قصد داشتیم که مساله را روشن‌تر کنیم. مواردی که در قسمت قبل ذکر شدند، به ساده‌ترین شکل ممکن بیان  شدند و شما به راحتی با بررسی این موارد و تفکر در کد‌های خود، می‌توانید این موارد را در کدی که خودتان می‌نویسید رعایت کنید. حل پیچیدگی‌های موجود در کد قبل، با در نظر گرفتن اصول مذکور و اصول‌های طراحی مختلف می‌تواند به روش‌های مختلفی انجام گیرد. برای مثال می‌توان برای هر یک از کارهایی که کد مثال قبل انجام می‌دهد، یک کلاس مجزا ایجاد نمود و اصول مذکور را در آن رعایت کرد. درنهایت این کلاس‌ها را در قالب یک Class Library دسته بندی کرد.

          Predictability: 

          در ادامه قصد داریم در مورد قابلیت پیش بینی و فواید رعایت اصول آن در کد، بحث کنیم. به صورت کلی یک متد، یکسری پارامتر‌ها را به عنوان ورودی دریافت می‌کند؛ یک عملیات خاص را بر روی پارامتر‌های ورودی انجام می‌دهد و در نهایت، در صورت لزوم یک مقدار را بر می‌گرداند. پارامتر‌های ورودی می‌توانند از سمت کاربر و از یک سورس خارجی وارد شوند و یا می‌توانند از یک متد دیگر به این متد ارسال شوند. اولین مرحله برای ایجاد قابلیت Predictability این است که یکسری گارد‌ها را به کد خود اضافه کنید تا به وسیله‌ی آنها پارامتر‌های ورودی را بررسی کنید و فقط اجازه‌ی ورود، ورودی‌های معتبر را بدهیم. برای مثال کد ذیل را درنظر بگیرد.

          پارامتر‌های ورودی این کد با مستطیل قرمز رنگ مشخص شده اند. حال ما سعی داریم با قرار دادن یکسری گارد برای پارامتر‌های ورودی، از ورود مقادیر ناخواسته جلوگیری کنیم. 

          بر اساس اصول (GIGO (Garbage in-Garbage out در برنامه نویسی متدی که ورودی‌های نامعتبر به آن پاس داده شوند، خروجی‌های نامعتبری هم پس خواهد داد. بنابراین برای جلوگیری از این مسئله باید از ورود ورودی‌های نامعتبر به متد‌ها جلوگیری کرد. گارد‌ها از ورود مقادیر نامعتبر به متد‌ها جلوگیری خواهند کرد و در نتیجه خروجی مناسب و قابل پیش بینی از متد گرفته خواهد شد.  برای جلوگیری از ورود داده‌های نامعتبر، باید با استفاده از این دستورات که در ابتدای متد قرار داده می‌شوند، از ورود داده‌های نامعتبر جلوگیری کرد. به این دستورات Guard Clauses گفته می‌شود. غیر از این مساله، کاهش دادن تعداد پارامتر‌ها و قراردادن قانونی برای تعیین اولویت پارامتر‌های متدها (برای مثال با توجه به اهمیت) می‌تواند به افزایش Predictability متد‌ها بسیار کمک کند. با پیروی کردن از این اصول ساده شما می‌توانید میزان خطاهایی که از پارامتر‌های ورودی منشاء می‌گیرند را کاهش دهید.

          اجازه دهید با یک مثال؛ مساله‌ی بالا را تشریح کنیم. برای مثال یک برنامه‌ی کوچک نوشته‌ایم؛ برای شمردن گام ها. در این برنامه تعداد قدم‌های هدف و تعداد قدم‌های برداشته شده‌ی امروز تعیین می‌شوند و سپس هدف، بر حسب درصد بیان خواهد شد. 

          با استفاده از این Application می‌خواهیم مفاهیمی را که بیان کردیم، به صورت کاربردی نمایش دهیم. کدی این محاسبه را برای ما انجام می‌دهد، در ذیل نمایش داده شده و در قالب یک متد تعیین شده است. 

          private decimal CalculatePercentOfGoalSteps (string goalSteps, string actualSteps)
          {
                      return (Convert.ToDecimal(actualSteps) / Convert.ToDecimal(goalSteps)) * 100;
          }

          این متد دارای دو پارامتر از نوع string می باشد و نتیجه هم در قالب یک مقدار decimal بازگشت داده خواهد شد. این جمله کلیتی از متد را بیان خواهد کرد. نحوه‌ی فراخوانی این متد هم در کد ذیل آورده شد است. 

          private void Calculate_Click(object sender, EventArgs e)
          {
            var result =CalculatePercentOfGoalSteps (stepGoalForTodayTxt.Text, numberOfStepsForToday.Text);
                      lblResult.Text = "شما به" + result + "% از هدف تان رسیده اید";
          }

          حال Application را اجرا کرده و نتیجه کار را مشاهده می‌کنیم. برای مثال شکل ذیل:

             

          در این مثال با توجه به مقادیر وارد شده، به 40 درصد از هدف مورد نظر رسیده‌ایم. اما هدف از بیان این مثال، این نیست که مشخص گردد که ما چقدر به هدفمان نزدیک شده‌ایم. بلکه هدف مسایل دیگری است. در نظر بگیرید که بجای 5000، صفر را وارد کنید. در این حالت با یک Exception روبرو می‌شویم:

          همانطور که در شکل بالا مشاهده می‌کنید، خطای Divide by zero رخ داده است. برای رفع این خطا و جلوگیری از رخداد این خطا، می‌توان کد ذیل را پیشنهاد داد. 

          private decimal CalculatePercentOfGoalSteps(string goalSteps, string actualSteps)
          {
                      decimal result =0;
                      var goalStepsCount = Convert.ToDecimal(goalSteps);
                      if (goalStepsCount>0)
                      {
                          result = (Convert.ToDecimal(actualSteps) / goalStepsCount) * 100;
                      }
                      return result;
          }

          با تغییر کد به این صورت مشکل  Exception  بالا حل می‌شود، اما باز هم مشکل دیگری وجود دارد. فرض کنید همانند شکل ذیل textbox اول را خالی کنیم و بعد از آن سعی در محاسبه داشته باشیم،

          باز هم یک  Exception دیگر

          علت بوجود آمدن این مشکل این است که ما در کد امکان خالی بودن پارامتر‌های متد را در نظر نگرفته‌ایم و پیش بینی‌های لازم صورت نگرفته است بنابراین دستور Convert  .با مشکل مواجه شد. برای حل این مشکل می‌توان به جای Convert از decimal.Tryparse استفاده کرد.

          private decimal CalculatePercentOfGoalSteps(string goalSteps, string actualSteps)
                  {
                      decimal result = 0;
                      decimal goalStepsCount = 0;
                      decimal.TryParse(goalSteps, out goalStepsCount);
                      decimal actualStepsCount = 0;
                      decimal.TryParse(actualSteps, out actualStepsCount);
                      if (goalStepsCount>0)
                      {
                          result = (actualStepsCount / goalStepsCount) * 100;
                      }
                      return result;
                  }

          با انجام دادن این کارها از بروز خطاهایی که ناشی از ورودی‌های نامعتبر در کد هستند، جلوگیری کردیم. اما آیا این پایان کار است؟ خیر با استفاده کردن از این روش ما توانسته‌ایم که از بروز خطا در برنامه جلوگیری کنیم. اما مشکلی که این روش دارد این است که کاربر متوجه نمی‌شود که چه زمانی برنامه دچار مشکل شده است. کاری که ما انجام می‌دهیم این است که برای تمامی حالات خطا، مقدار صفر را بر می‌گردانیم.

          برای اینکه بتوانیم این کد به راحتی debug کنیم باید از مفهوم Fail Fast استفاده کنیم . این مفهوم قابلیتی را در کد ایجاد می‌کند که در صورتی که کد، داده‌های نامعتبری را دریافت کرد، سریعا اجرای آن متوقف می‌شود و همزمان نیز اطلاعاتی در مورد خطا در اختیار کاربر قرار می‌دهد. برای این منظور با قرار دادن یکسری Guard Clauses، کد بالا را همانند شکل ذیل تغییر خواهیم داد.

          private decimal CalculatePercentOfGoalSteps(string goalSteps, string actualSteps)
                  {
                      decimal goalStepsCount = 0;
                      decimal actualStepsCount = 0;
                      /// اطمینان حاصل می‌کنند که پارامتر‌های ورودی دارای مقدار هستند 
                      if (string.IsNullOrWhiteSpace(goalSteps)) throw new ArgumentException("مقدار هدف باید وارد شود", "goalSteps");
                      if (string.IsNullOrWhiteSpace(actualSteps)) throw new ArgumentException("مقدار واقعی باید وارد شود", "goalSteps");
          
                      ///اطمینان حاصل می‌کنند که مقادیر وارد شده حتما عددی هستند
                      if (!decimal.TryParse(goalSteps, out goalStepsCount)) throw new ArgumentException("مقدار هدف باید عددی باشد", goalSteps);
                      if(!decimal.TryParse(actualSteps, out actualStepsCount)) throw new ArgumentException("مقدار واقعی باید عددی باشد", actualSteps);
          
                      ///اطمینان حاصل می‌کند که مقدار متغیر نباید صفر باشد
                      if (goalStepsCount <= 0) throw new ArgumentException("مقدار هدف نباید صفر و یا کمتر از صفر باشد", "goalStepsCount");
                      return (actualStepsCount / goalStepsCount) * 100;
                  }

          ایجاد کردن این تغییرات در متد باعث افزایش خوانایی کد می‌شود و هدف متد را روشن‌تر بیان خواهد کرد. اضافه کردن این کدها به دلیل اینکه تمامی شرایط تست را تعیین خواهیم کرد Test-ability کد را بالا می‌برد. اضافه کردن کد‌های بالا به برنامه کمک خواهد کرد که شرایط خطا در برنامه به درستی هندل شود و به طبع آن تصمیمات مناسبی گرفته شود و در نهایت Predictability متد‌ها و کل برنامه را افزایش می‌هد.

          نظرات مطالب
          صفحه بندی، مرتب سازی و جستجوی پویای اطلاعات به کمک Kendo UI Grid
          var initialLoad = true;
          
          var ds = new kendo.data.DataSource({
          //...
          requestStart: function () {
            if (initialLoad)
               kendo.ui.progress($("#myGrid"), true);
          },
          requestEnd: function () {
            if(initialLoad)
                kendo.ui.progress($("#myGrid"), false);
            initialLoad = false;
          },
          //...
          مطالب
          مبانی TypeScript؛ متغیرها و نوع‌ها
          روش‌های مختلف تعریف متغیرها در TypeScript

          تمام توسعه دهنده‌های JavaScript با واژه‌ی کلیدی var آشنایی دارند؛ اما TypeScript واژه‌های کلیدی let و const را نیز اضافه کرده‌است (که جزئی از ES 6 نیز می‌باشند). تفاوت مهم بین var و let، در میدان دید متغیرهای تعریف شده‌ی توسط آن‌ها خلاصه می‌شود. پیشتر در سری مباحث بررسی ES 6، مطلب «متغیرها در ES 6» را نیز بررسی کردیم که در TypeScript نیز صادق می‌باشند؛ با این تفاوت که TypeScript را می‌توان به ES 5 نیز کامپایل کرد و بدون مشکل با تمام مرورگرهای موجود، اجرا نمود.
          - متغیرهایی که با var تعریف می‌شوند، به صورت سراسری در متدی که تعریف شده‌اند، قابل دسترسی هستند؛ حتی اگر 5 سطح داخل ifهای تو در تو تعریف شده باشند. اما let و const تنها در block و قطعه‌ای که معرفی شده‌اند، معتبر بوده و خارج از آن تعریف نشده‌اند. در اینجا یک block توسط {} معرفی می‌شود.
          - متغیرهای از نوع var به دلیل مفهومی به نام hoisting توسط runtime جاوا اسکریپت، به بالاترین سطح متد منتقل می‌شوند. به همین دلیل عمق تعریف آن‌ها، اثری در دسترسی به این متغیرها ندارد. اما hoisting در مورد let و const اعمال نمی‌شود.
          - متغیرهای var را می‌توان چندبار مجددا تعریف کرد (هرچند این روش توصیه نمی‌شود؛ اما مجاز است). یک چنین تعریف مجددی با متغیرهای از نوع let و const مجاز نیست.
          برای توضیحات بیشتر به مثال ذیل دقت کنید:
          function ScopeTest() {
              if (true) {
                  var foo = 'use anywhere';
                  let bar = 'use in this block';
              }
              console.log(foo); // works!
              console.log(bar); // error!
          }
          در اینجا داخل قطعه‌ی if تعریف شده، یک متغیر، از نوع var و متغیر دیگری از نوع let تعریف شده‌است. خارج از بدنه‌ی این متد، متغیر foo هنوز قابل دسترسی است، اما متغیر bar خیر.


          نوع‌های پایه‌ی TypeScript

          نوع‌های پایه‌ی TypeScript شامل موارد ذیل هستند:
          Boolean: برای ذخیره سازی true یا false.
          let isDone: boolean = false;
          Number: معرف مقادیر عددی اعشاری هستند.
          let decimal: number = 6;
          let hex: number = 0xf00d;
          let binary: number = 0b1010;
          let octal: number = 0o744;
          String: مقادیر رشته‌ای را ذخیره می‌کند.
          let name: string = "bob";
          name = 'smith';
          Array: روش‌های متفاوتی برای تعریف آرایه‌ها در TypeScript وجود دارند که در ادامه آن‌ها را بیشتر بررسی خواهیم کرد.
          let list: number[] = [1, 2, 3];
          Enum: نوع‌های شمارشی؛ جهت دادن نام‌هایی بهتر به مجموعه‌ی مشخصی از مقادیر.
          enum Color {Red, Green, Blue};
          let c: Color = Color.Green;
          Any: به این معنا که یک متغیر می‌تواند به هر نوع دلخواهی اشاره کند. هدف از وجود این نوع، امکان استفاده‌ی از کتابخانه‌های فعلی جاوا اسکریپتی است که نوعی برای متغیرهای آن‌ها تعریف نشده‌اند و در اساس هر نوعی می‌توانند باشند. برای مثال در جاوا اسکریپت مجاز است در سطر اول متغیری را تعریف کرد و در سطر دوم به آن یک رشته و در سطر سوم به آن یک عدد را انتساب داد.
          let notSure: any = 4;
          notSure = "maybe a string instead";
          notSure = false; // okay, definitely a boolean
          Void: به معنای فقدان یک نوع است. برای مثال مشخص کردن اینکه متدی، خروجی ندارد.
           function warnUser(): void {
                  alert("This is my warning message");
          }

          یک نکته: قابلیت Template string در ES 6 نیز در TypeScript پشتیبانی می‌شود.



          مفهوم Type Inference در TypeScript

          در TypeScript الزاما نیازی نیست تا نوع متغیری را صریحا مشخص کرد. در اینجا اگر نوع متغیری را در ابتدای کار تعریف نکنید، نوع آن در اولین باری که مقدار دهی می‌شود، مشخص خواهد شد که به آن Type Inference نیز می‌گویند.
          let myString= 'this is a string';
          myString= 42; // error!
          در مثال فوق، نوع متغیر myString در زمان تعریف آن مشخص نشده‌است؛ اما با یک رشته، مقدار دهی و آغاز شده‌است. بر این اساس، TypeScript نوع این متغیر را رشته‌ای در نظر می‌گیرد و در سطر بعدی، از انتساب یک مقدار عددی به آن جلوگیری خواهد کرد.
          و یا در مثال ذیل، نوع خروجی متد ReturnNumber به صورت صریح مشخص نشده‌است:
          function ReturnNumber() {
             return 42;
          }
          let anotherString = 'this is also a string';
          anotherString = ReturnNumber(); // error!
          اما با توجه به اینکه خروجی آن عددی است، نوع آن نیز عددی درنظر گرفته شده و از انتساب آن به یک متغیر رشته‌ای جلوگیری می‌شود.


          تعریف صریح نوع‌ها در TypeScript با استفاده از Type Annotations

          برای لغو Type Inference و تعیین صریح نوع‌ها در TypeScript می‌توان به صورت زیر عمل کرد:
          let myString : string = 'this is a string';
          myString = 42; // error!
          
          function ReturnNumber() : number {
             return 42;
          }
          let anotherString : string = 'this is also a string';
          anotherString = ReturnNumber(); // error!
          با قراردادن یک کولن پس از نام متغیر و سپس تعریف نوع داده‌ی مدنظر، می‌توان نوع‌ها را در TypeScript به صورت صریحی تعریف کرد. در مورد متدها نیز به همین صورت است. کولن پس از پایان بسته شدن پرانترها قرار می‌گیرد و سپس نوع بازگشتی متد مشخص می‌گردد.


          نوع‌های شمارشی در TypeScript

          Enums در بسیاری از زبان‌های برنامه نویسی متداول وجود دارند و هدف از آن‌ها، دادن نام‌هایی بهتر و مشخص، به مجموعه‌ای از مقادیر است:
           enum Category { Biography, Poetry, Fiction }; // 0, 1, 2
          در مثال فوق یک enum جهت تعریف گروه‌های کتاب‌ها تعریف شده‌است. در اینجا بجای استفاده از مقادیر نامفهوم 0 تا 2، نام‌هایی مشخص و بهتر، جهت معرفی آن‌ها ارائه شده‌اند. به این ترتیب می‌توان در نهایت به کدهایی خواناتر رسید.
          اگر می‌خواهید این مقادیر با اعداد دیگری شروع شوند (بجای صفر پیش فرض)، می‌توان مقدار اولین نام را به صورت صریحی مشخص کرد:
           enum Category { Biography = 1, Poetry, Fiction }; // 1, 2, 3
          و یا الزامی به استفاده از مقادیر افزایش یابنده‌ای در اینجا نیست. در صورت نیاز می‌توان مقدار هر المان را جداگانه تعریف کرد:
           enum Category{ Biography = 5, Poetry = 8, Fiction = 9 }; // 5, 8, 9
          پس از اینکه نوع enum تعریف شده، استفاده از آن همانند سایر نوع‌های پایه‌ی TypeScript است:
           let favoriteCategory: Category = Category.Biography;
          در اینجا متغیر favoriteCategory از نوع enum گروه کتاب‌ها تعیین شده‌است؛ با مقدار اولیه‌ی Category.Biography.
          در این حالت اگر مقدار favoriteCategory را چاپ کنیم، خروجی عددی 5 نمایش داده می‌شود:
           console.log(favoriteCategory); // 5
          اگر نیاز به بازگشت مقدار رشته‌ای این آیتم است، می‌توان از ایندکس‌های یک enum استفاده کرد:
          let categoryString= Category[favoriteCategory]; // Biography


          آرایه‌ها در TypeScript

          در حالت عمومی، آرایه‌ها در TypeScript همانند جاوا اسکریپت تعریف می‌شوند؛ البته به همراه تعدادی استثناء. در TypeScript سه روش برای تعریف آرایه‌ها وجود دارند:
          الف) در مثال زیر آرایه‌ای از رشته‌ها تعریف شده‌است. در اینجا نوع آرایه به همراه [] مشخص می‌شود:
          let strArray1: string[] = ['here', 'are', 'strings'];
          ب) روش دوم تعریف آرایه‌ها در TypeScript با استفاده از مفهوم Generics است که در بحثی جداگانه به آن خواهیم پرداخت. در اینجا از واژه‌ی کلیدی Array به همراه مشخص سازی نوع آن در داخل <> استفاده شده‌است:
          let strArray2: Array<string> = ['more', 'strings', 'here'];
          ج) اگر نیاز به آرایه‌هایی شبیه به جاوا اسکریپت دارید که می‌توانند حاوی انواع و اقسام المان‌هایی با نوع‌های مختلف باشند، نوع آرایه را []any تعریف کنید:
          let anyArray: any[] = [42, true, 'banana'];


          نوع Tuples در TypeScript

          Tuples در TypeScript نوع خاصی از آرایه‌ها هستند که نوع مقادیر اعضای آن‌ها به صورت صریح مشخص می‌شوند:
           let myTuple: [number, string] = [25, 'truck'];
          برای مثال در اینجا نوع متغیر myTuple به صورت آرایه‌ای از دو عنصر عددی و رشته‌ای تعریف شده‌است.
          اکنون برای دسترسی به مقادیر این المان‌ها، همانند کار با آرایه‌های معمولی، از ایندکس‌های آرایه‌ی تعریف شده استفاده می‌شود:
           let firstElement= myTuple[0]; // 25
          let secondElement= myTuple[1]; // truck

          یک نکته: می‌توان به آرایه‌ی تعریف شده، عناصر جدیدی را نیز افزود؛ با این شرط که نوع آن‌ها، یکی از نوع‌های مشخص شده‌ی در تعریف Tuple باشند:
           // other elements can have numbers or strings
          myTuple[2] = 100;
          myTuple[2] = 'this works!';


          مفهوم Type assertions در TypeScript

          حتما با مفهوم cast و تبدیل نوع‌های مختلف به یکدیگر، در زبان‌های دیگر برنامه نویسی آشنا هستید. در TypeScript نیز این مفهوم تحت عنوان Type assertions پشتیبانی می‌شود و دو روش برای تعریف آن وجود دارد:
          الف) تعریف cast توسط angle-bracket syntax که در آن نوع مدنظر داخل یک <> قرار می‌گیرد:
           let someValue: any = "this is a string";
          let strLength: number = (<string>someValue).length;
          در اینجا نوع نامشخص any به string تبدیل شده و سپس امکان دسترسی به خاصیت طول آن که تحت کنترل کامپایلر است و قابل انتساب به یک مقدار عددی، میسر شده‌است.
          ب) تعریف cast توسط as syntax به نحو ذیل:
           let someValue: any = "this is a string";
          let strLength: number = (someValue as string).length;
          هر دو حالت تعریف شده معادل هستند. فقط باید دقت داشت در حین کار با ReactJS توسط TypeScript، فقط حالت as syntax پشتیبانی می‌شود.
          نظرات مطالب
          پیاده سازی Unobtrusive Ajax در ASP.NET Core 1.0
          فعالسازی نمایش خطاهای سمت سرور به کاربر، پس از پایان عملیات ای‌جکسی
          سمت سرور:
          return BadRequest(error: "کاربر مورد نظر یافت نشد");
          سمت کاربر:
          - تغییرات فرم:
          <form
          ...
          ...
          data-ajax-failure="dataAjaxFailure">
          - متد جاوا اسکریپتی متناظر:
          function dataAjaxFailure(xhr, status, error) {
              alert(xhr.responseText);
          }