مسیرراه‌ها
ASP.NET MVC
              مطالب
              PowerShell 7.x - قسمت دوم - آشنایی با Pipelineها
              PowerShell برای نام‌گذاری Commandها، از ساختار verb-noun استفاده میکند. به عنوان مثال Get-Command, New-Service, Get-Help نمونه‌هایی از این Commandها در PowerShell هستند. لازم به ذکر است که در PowerShell، منظور از cmdlet یا Command let، همان Commandهای native در PowerShell هستند؛ نه Commandهای عمومی مانند dir, cd, ipconfig و غیره. به عنوان مثال از Get-Help برای نمایش مستندات یک cmdlet میتوان استفاده کرد و دقیقاً مشابه man page در لینوکس است.

              Get-Help Get-Command
              با فلگ Online میتوان مستندات cmdlet موردنظر را درون مرورگر مشاهده کرد:
              Get-Help Get-Command -Online
              برای بیشتر cmdletها میتوانیم فیلتر نیز اعمال کنیم. به عنوان مثال با دستور زیر میتوان لیست تمام processهای سیستم را که به واژه‌ی Process ختم میشوند، مشاهده کنیم:
              Get-Command -Name '*Process'
              خروجی دستور فوق، یک جدول به صورت زیر خواهد بود:
              CommandType     Name                                               Version    Sour
                                                                                            ce
              -----------     ----                                               -------    ----
              Cmdlet          Debug-Process                                      7.0.0.0    Mic…
              Cmdlet          Enter-PSHostProcess                                7.2.6.500  Mic…
              Cmdlet          Exit-PSHostProcess                                 7.2.6.500  Mic…
              Cmdlet          Get-Process                                        7.0.0.0    Mic…
              Cmdlet          Start-Process                                      7.0.0.0    Mic…
              Cmdlet          Stop-Process                                       7.0.0.0    Mic…
              Cmdlet          Wait-Process                                       7.0.0.0    Mic…
              Application     mysqltest_safe_process                             0.0.0.0

              Pipeline
              توسط Pipeline میتوان خروجی یک command را به عنوان ورودی یک command دیگر ارسال کرد. در دیگر زبان‌های اسکریپتی مانند bash یا batch (در ویندوز) چیزی که به command بعدی ارسال میشود، در واقع یک text است:
              ls -l | grep "\.pdf$"
              در مثال فوق، خروجی برنامه ls -1 را به ورودی برنامه grep ارسال کرده‌ایم. در حالت عادی، خروجی دستورات به standard output یا به طور خلاصه stout ارسال میشوند. توسط pipe یا pipeline میتوانیم خروجی متنی را به اصطلاح redirect کنیم و به کامندهای بعدی به صورت یک زنجیره ارسال کنیم. اما در PowerShell این objectها هستند که ارسال (pipe) میشوند. به عنوان مثال میتوانیم با کمک Pipelineها، خروجی مثال قبل را محدود به نمایش ستون‌های دلخواهی کنیم. به عبارتی تنها ستون‌های Name و CommandType را در خروجی نمایش دهیم:
              Get-Command -Name '*Process' | Select-Object Name,CommandType
              همچنین میتوانیم خروجی را با کمک Sort-Object مرتب کنیم:
              Get-Command -Name '*Process' | Select-Object Name,CommandType | Sort-Object Name -Descending
              یا اینکه خروجی را محدود به نمایش ۳ آیتم کنیم:
              PS /> Get-Command -Name '*Process' | Select-Object Name,CommandType -First 3 | Sort-Object Name -Descending
              
              Name                CommandType
              ----                -----------
              Exit-PSHostProcess       Cmdlet
              Enter-PSHostProcess      Cmdlet
              Debug-Process            Cmdlet
              همچنین میتوانیم از Where-Object برای اعمال شرط نیز استفاده کنیم. به عنوان مثال، در ادامه لیست ۵ پروسس سیستم را که مقدار CPU بیشتر از 1.24، در اختیار دارند نمایش داده‌ایم:
              PS /> Get-Process | Where-Object CPU -gt 1.24 | Sort-Object WorkingSet -Descending | Select-Object -First 5

              Pipelineها چطور کار میکنند؟
              در PowerShell در واقع stdinی وجود ندارد که shell از آن استفاده کند؛ در نتیجه PowerShell باید بداند خروجی cmdlet قبلی را به کدام پراپرتی از cmdlet بعدی در pipeline ارسال کند:


              PowerShell از مکانیزمی تحت عنوان pipeline binding برای انجام این نگاشت استفاده میکند. دو روش برای انجام این binding وجود دارد:
              • ByValue
              • ByPropertyName 
              در نظر داشته باشید که هر کدام از روش‌های فوق توسط کسی که cmdlet موردنظر را پیاده‌سازی خواهد کرد میتواند پشتیبانی شود. برای درک بهتر این مکانیزم دستور زیر را در نظر بگیرید:
              Get-Process Slack | Stop-Process
              قبل از هر چیزی باید بدانیم خروجی cmdlet اول یعنی Get-Process چه چیزی است. اینکار را میتوانیم توسط دستور زیر انجام دهیم:
              Get-Process | Get-Member
              دستور فوق یک لیست از خواص Get-Process خواهد بود و خط اول این خروجی دقیقاً تایپی است که Get-Process برمیگرداند:
              TypeName: System.Diagnostics.Process
              بنابراین این تایپی است که به عنوان ورودی، به Stop-Process درون pipeline ارسال میشود. در ادامه توسط دستور Get-Help Stop-Process -Full لیست پارامترهایی را که Stop-Process دریافت میکند، لیست خواهیم کرد:
              PS /Users/sirwanafifi> Get-Help Stop-Process -Full
              
              NAME
                  Stop-Process
              
              SYNTAX
                  Stop-Process [-Id] <int[]> [-PassThru] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
              
                  Stop-Process -Name <string[]> [-PassThru] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
              
                  Stop-Process [-InputObject] <Process[]> [-PassThru] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
              
              
              PARAMETERS
                  -Confirm
              
                      Required?                    false
                      Position?                    Named
                      Accept pipeline input?       false
                      Parameter set name           (All)
                      Aliases                      cf
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  -Force
              
                      Required?                    false
                      Position?                    Named
                      Accept pipeline input?       false
                      Parameter set name           (All)
                      Aliases                      None
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  -Id <int[]>
              
                      Required?                    true
                      Position?                    0
                      Accept pipeline input?       true (ByPropertyName)
                      Parameter set name           Id
                      Aliases                      None
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  -InputObject <Process[]>
              
                      Required?                    true
                      Position?                    0
                      Accept pipeline input?       true (ByValue)
                      Parameter set name           InputObject
                      Aliases                      None
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  -Name <string[]>
              
                      Required?                    true
                      Position?                    Named
                      Accept pipeline input?       true (ByPropertyName)
                      Parameter set name           Name
                      Aliases                      ProcessName
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  -PassThru
              
                      Required?                    false
                      Position?                    Named
                      Accept pipeline input?       false
                      Parameter set name           (All)
                      Aliases                      None
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  -WhatIf
              
                      Required?                    false
                      Position?                    Named
                      Accept pipeline input?       false
                      Parameter set name           (All)
                      Aliases                      wi
                      Dynamic?                     false
                      Accept wildcard characters?  false
              
                  <CommonParameters>
                      This cmdlet supports the common parameters: Verbose, Debug,
                      ErrorAction, ErrorVariable, WarningAction, WarningVariable,
                      OutBuffer, PipelineVariable, and OutVariable. For more information, see
                      about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).
              
              
              INPUTS
                  System.Int32[]
                  System.String[]
                  System.Diagnostics.Process[]
              
              
              OUTPUTS
                  System.Diagnostics.Process
              
              
              ALIASES
                  spps
              
              
              REMARKS
                  Get-Help cannot find the Help files for this cmdlet on this computer. It is displaying only partial help.
                      -- To download and install Help files for the module that includes this cmdlet, use Update-Help.
                      -- To view the Help topic for this cmdlet online, type: "Get-Help Stop-Process -Online" or
                         go to https://go.microsoft.com/fwlink/?LinkID=2097058.
              از پارامترهای فوق تنها Id, Name و InputObject هستند که خاصیت Accept pipeline inputشان به true تنظیم شده‌است. همانطور که مشاهده میکنید InputObject از نوع ByValue است و Id و Name نیز از نوع ByPropertyName هستند:
              -Id <int[]>
              
                  Required?                    true
                  Position?                    0
                  Accept pipeline input?       true (ByPropertyName)
                  Parameter set name           Id
                  Aliases                      None
                  Dynamic?                     false
                  Accept wildcard characters?  false
              
              -InputObject <Process[]>
              
                  Required?                    true
                  Position?                    0
                  Accept pipeline input?       true (ByValue)
                  Parameter set name           InputObject
                  Aliases                      None
                  Dynamic?                     false
                  Accept wildcard characters?  false
              
              -Name <string[]>
              
                  Required?                    true
                  Position?                    Named
                  Accept pipeline input?       true (ByPropertyName)
                  Parameter set name           Name
                  Aliases                      ProcessName
                  Dynamic?                     false
                  Accept wildcard characters?  false
              نوع ورودی این پارامتر نیز یک آرایه از Processها میباشد. بنابراین در اینجا ByValue به این معنا است که اگر مقدار pipe شده از نوع Process بود، پراپرتی InputObject مقداردهی میشود. برای حالت ByPropertyName دستور زیر را در نظر بگیرید:
              "Slack" | Stop-Process
              با اجرای دستور فوق خطای زیر را دریافت خواهیم کرد:
              Stop-Process: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
              علت آن نیز مشخص است؛ چون هیچ پراپرتی از نوع ByValue که ورودی string یا آرایه‌ایی از stringها را دریافت کند برای Stop-Process وجود ندارد، بنابراین pipeline binding اتفاق نخواهد افتاد. برای درک بهتر موضوع، یک شیء تستی ایجاد خواهیم کرد که شامل یک پراپرتی Name با مقدار Slack است؛ سپس شیء جدید را به Stop-Process ارسال میکنیم:
              PS /Users/sirwanafifi> $newObject = [pscustomobject]@{ Name = "Slack" }
              PS /Users/sirwanafifi> $newObject | Stop-Process
              با اجرای دستور فوق، پراسس موردنظر stop خواهد شد.
              لازم به ذکر است که اگر یک پارامتر، هم ByValue و هم ByPropertyName باشد، PowerShell ابتدا سعی میکند ByValue را امتحان کند و اگر با شکست مواجه شد از ByPropertyName استفاده خواهد کرد.
              مطالب
              لیست اکران‌های نوروزی MIX09

              MIX09 | Web Design and Development Conference






              اشتراک‌ها
              آموزش مقدماتی NET Aspire.

              Build Better Apps with .NET Aspire - Complete Beginner's Guide & Tutorial

              Let's start building better apps with .NET Aspire! Find out how adding .NET Aspire to your existing apps can help them be more observable, resilient, scalable, and manageable. All in just a few lines of code enable these features and at the same time boost developer productivity with features to help you build apps faster including orchestration and service discovery. It also gives you deep insight into your application with OpenTelemetry and a developer dashboard on your local development machine or in the cloud. We will also take a look at how to deploy your projects that use .NET Aspire and how it works under the hood. Finally, we will look at how to use some of these great features in non-.NET projects such as JavaScript and Python!

              آموزش مقدماتی NET Aspire.
              اشتراک‌ها
              تشخیص تفاوت بین IIS سرورهای مختلف

              I commonly hear the phrase “The web application worked in the pre-production environment and now is encountering issues in production and the server’s configuration are identical!” when I appear onsite to help assist with the resolution of the issues. Upon further investigation, an IIS module has not been installed on the production server, or the configuration is different for an application pool setting between the pre-production and production environments. This is a very common scenario I encounter in the field and here are some suggestions on how to determine differences between IIS servers in an IIS farm environment or between servers in different environments, such as pre-production and production. Keeping server configuration and content synchronized is always a challenge and I hope these suggestions help out.

              تشخیص تفاوت بین IIS سرورهای مختلف
              مطالب
              ایجاد صفحات راهنما برای ASP.NET Web API
              وقتی یک Web API می‌سازید بهتر است صفحات راهنمایی هم برای آن در نظر بگیرید، تا توسعه دهندگان بدانند چگونه باید سرویس شما را فراخوانی و استفاده کنند. گرچه می‌توانید مستندات را بصورت دستی ایجاد کنید، اما بهتر است تا جایی که ممکن است آنها را بصورت خودکار تولید نمایید.

              بدین منظور فریم ورک ASP.NET Web API کتابخانه ای برای تولید خودکار صفحات راهنما در زمان اجرا (run-time) فراهم کرده است.


              ایجاد صفحات راهنمای API

              برای شروع ابتدا ابزار ASP.NET and Web Tools 2012.2 Update را نصب کنید. اگر از ویژوال استودیو 2013 استفاده می‌کنید این ابزار بصورت خودکار نصب شده است. این ابزار صفحات راهنما را به قالب پروژه‌های ASP.NET Web API اضافه می‌کند.

              یک پروژه جدید از نوع ASP.NET MVC Application بسازید و قالب Web API را برای آن انتخاب کنید. این قالب پروژه کنترلری بنام ValuesController را بصورت خودکار برای شما ایجاد می‌کند. همچنین صفحات راهنمای API هم برای شما ساخته می‌شوند. تمام کد مربوط به صفحات راهنما در قسمت Areas قرار دارند.

              اگر اپلیکیشن را اجرا کنید خواهید دید که صفحه اصلی لینکی به صفحه راهنمای API دارد. از صفحه اصلی، مسیر تقریبی Help/ خواهد بود.

              این لینک شما را به یک صفحه خلاصه (summary) هدایت می‌کند.

              نمای این صفحه در مسیر Areas/HelpPage/Views/Help/Index.cshtml قرار دارد. می‌توانید این نما را ویرایش کنید و مثلا قالب، عنوان، استایل‌ها و دیگر موارد را تغییر دهید.

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

              ستون "API" متد HTTP و آدرس نسبی را لیست می‌کند. ستون "Documentation" مستندات هر API را نمایش می‌دهد. مقادیر این ستون در ابتدا تنها placeholder-text است. در ادامه مقاله خواهید دید چگونه می‌توان از توضیحات XML برای تولید مستندات استفاده کرد.

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


              افزودن صفحات راهنما به پروژه ای قدیمی

              می توانید با استفاده از NuGet Package Manager صفحات راهنمای خود را به پروژه‌های قدیمی هم اضافه کنید. این گزینه مخصوصا هنگامی مفید است که با پروژه ای کار می‌کنید که قالب آن Web API نیست.

              از منوی Tools گزینه‌های Library Package Manager, Package Manager Console را انتخاب کنید. در پنجره Package Manager Console فرمان زیر را وارد کنید.

              Install-Package Microsoft.AspNet.WebApi.HelpPage
              این پکیج اسمبلی‌های لازم برای صفحات راهنما را به پروژه اضافه می‌کند و نماهای MVC را در مسیر Areas/HelpPage می‌سازد. اضافه کردن لینکی به صفحات راهنما باید بصورت دستی انجام شود. برای اضافه کردن این لینک به یک نمای Razor از کدی مانند لیست زیر استفاده کنید.

              @Html.ActionLink("API", "Index", "Help", new { area = "" }, null)

              همانطور که مشاهده می‌کنید مسیر نسبی صفحات راهنما "Help/" می‌باشد. همچنین اطمینان حاصل کنید که ناحیه‌ها (Areas) بدرستی رجیستر می‌شوند. فایل Global.asax را باز کنید و کد زیر را در صورتی که وجود ندارد اضافه کنید.
              protected void Application_Start()
              {
                  // Add this code, if not present.
                  AreaRegistration.RegisterAllAreas();
              
                  // ...
              }

              افزودن مستندات API

              بصورت پیش فرض صفحات راهنما از placeholder-text برای مستندات استفاده می‌کنند. می‌توانید برای ساختن مستندات از توضیحات XML استفاده کنید. برای فعال سازی این قابلیت فایل Areas/HelpPage/App_Start/HelpPageConfig.cs را باز کنید و خط زیر را از حالت کامنت درآورید:

              config.SetDocumentationProvider(new XmlDocumentationProvider(
                  HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
              حال روی نام پروژه کلیک راست کنید و Properties را انتخاب کنید. در پنجره باز شده قسمت Build را کلیک کنید.

              زیر قسمت Output گزینه XML documentation file را تیک بزنید و در فیلد روبروی آن مقدار "App_Data/XmlDocument.xml" را وارد کنید.

              حال کنترلر ValuesController را از مسیر Controllers/ValuesController.cs/ باز کنید و یک سری توضیحات XML به متدهای آن اضافه کنید. بعنوان مثال:

              /// <summary>
              /// Gets some very important data from the server.
              /// </summary>
              public IEnumerable<string> Get()
              {
                  return new string[] { "value1", "value2" };
              }
              
              /// <summary>
              /// Looks up some data by ID.
              /// </summary>
              /// <param name="id">The ID of the data.</param>
              public string Get(int id)
              {
                  return "value";
              }

              اپلیکیشن را مجددا اجرا کنید و به صفحات راهنما بروید. حالا مستندات API شما باید تولید شده و نمایش داده شوند.

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


              توضیحات تکمیلی

              صفحات راهنما توسط کلاس ApiExplorer تولید می‌شوند، که جزئی از فریم ورک ASP.NET Web API است. به ازای هر API این کلاس یک ApiDescription دارد که توضیحات لازم را در بر می‌گیرد. در اینجا منظور از "API" ترکیبی از متدهای HTTP و مسیرهای نسبی است. بعنوان مثال لیست زیر تعدادی API را نمایش می‌دهد:

              • GET /api/products
              • {GET /api/products/{id
              • POST /api/products

              اگر اکشن‌های کنترلر از متدهای متعددی پشتیبانی کنند، ApiExplorer هر متد را بعنوان یک API مجزا در نظر خواهد گرفت. برای مخفی کردن یک API از ApiExplorer کافی است خاصیت ApiExplorerSettings را به اکشن مورد نظر اضافه کنید و مقدار خاصیت IgnoreApi آن را به true تنظیم نمایید.

              [ApiExplorerSettings(IgnoreApi=true)]
              public HttpResponseMessage Get(int id) {  }

              همچنین می‌توانید این خاصیت را به کنترلر‌ها اضافه کنید تا تمام کنترلر از ApiExplorer مخفی شود.

              کلاس ApiExplorer متن مستندات را توسط اینترفیس IDocumentationProvider دریافت می‌کند. کد مربوطه در مسیر Areas/HelpPage/XmlDocumentation.cs/ قرار دارد. همانطور که گفته شد مقادیر مورد نظر از توضیحات XML استخراج می‌شوند. نکته جالب آنکه می‌توانید با پیاده سازی این اینترفیس مستندات خود را از منبع دیگری استخراج کنید. برای اینکار باید متد الحاقی SetDocumentationProvider را هم فراخوانی کنید، که در HelpPageConfigurationExtensions تعریف شده است.

              کلاس ApiExplorer بصورت خودکار اینترفیس IDocumentationProvider را فراخوانی می‌کند تا مستندات API‌ها را دریافت کند. سپس مقادیر دریافت شده را در خاصیت Documentation ذخیره می‌کند. این خاصیت روی آبجکت‌های ApiDescription و ApiParameterDescription تعریف شده است.


              مطالعه بیشتر

              اشتراک‌ها
              Entity Framework Core 7 نسخه نهایی

              Entity Framework Core (EF Core) 7 is available on NuGet today!

              EF Core 7 is the successor to EF Core 6, and can be referred to as EF7 for brevity. EF Core 7 contains many features that help in porting “classic” EF6 applications to use EF7. As such, we encourage people to upgrade existing classic EF applications to use EF7 where possible. See Porting from EF6 to EF Core for more information. 

              Entity Framework Core 7 نسخه نهایی
              اشتراک‌ها
              10تا از جالبترین باگهای پیدا شده در پروژه های C# در سال 2020

              This tough year, 2020, will soon be over at last, which means it's time to look back at our accomplishments! Over the year, the PVS-Studio team has written quite a number of articles covering a large variety of bugs found in open-source projects with the help of PVS-Studio. This 2020 Top-10 list of bugs in C# projects presents the most interesting specimens. Enjoy the reading! 

              10تا از جالبترین باگهای پیدا شده در پروژه های C# در سال 2020
              اشتراک‌ها
              پشتیبانی SQL Server 2017 از بانک های گراف محور

              Graph extensions in SQL Server 2017 will facilitate users in linking different pieces of connected data to help gather powerful insights and increase operational agility. Graphs are well suited for applications where relationships are important, such as fraud detection, risk management, social networks, recommendation engines, predictive analysis, dependence analysis, and IoT applications. In this session we will demonstrate how you can use SQL Graph extensions to build your application using graph data. 

              پشتیبانی SQL Server 2017 از بانک های گراف محور