آپدیت 2 ویژوال استودیو 2015
بررسی چک لیست امنیتی web.config
Modern software development practices value quick and continuous updates, following processes that minimize the impact of software failures. As important as identifying bugs early, finding out if changes are improving business value are equally important. These practices can only work when a monitoring solution is in place. This article explores options for adding observability to .NET Core apps. They have been collected based on interactions with customers using .NET Core in different environments. We will be looking into OpenTelemetry and Application Insights SDKs to add observability to a sample distributed application.
سری آموزشی PRISM
PRISM یا Composite Application Guidance الگوهایی را برای تولید برنامههای WPF ویا Silverlight ماژولار با قابلیت تست پذیری بالا ارائه میدهند. شعار این مجموعه built for change و built to last است که به معنای تهیه سیستمهایی با قابلیت تغییر بالا و همچنین سهولت نگهداری آنها در دراز مدت میباشد.
جناب Mike Taulty را احتمالا با ویدیوهای آموزش WCF به خاطر دارید. ایشان مجموعه جدیدی را به نام Video Series on PRISM for Silverlight 3 تهیه کردهاند که از لینکهای زیر قابل دریافت است:
Part 2: Dependency Injection with Unity
Part 3: Modularity with Prism
Part 4: The Unity Bootstrapper
Part 5: Moving to a Modular Silverlight Project
Part 6: Shells, Regions, Views
Part 7: Commands
Part 8: Loosely Coupled Events with Event Aggregation
Part 9: Sharing Data via Region Contexts
Part 10: A Larger Example: "Email Client"
مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger - قسمت چهارم - تکمیل مستندات نوعهای خروجی API
در برنامههای ASP.NET Core، اطلاعات OpenAPI بر اساس سرویس توکاری به نام ApiExplorer تولید میشود که کار آن فراهم آوردن متادیتای مرتبط با یک برنامهی وب است. برای مثال توسط این سرویس میتوان به لیست کنترلرها، متدها و پارامترهای آنها دسترسی یافت. Swashbuckle.AspNetCore به کمک ApiExplorer کار تولید OpenAPI Specification را انجام میدهد. برای فعالسازی این سرویس نیازی نیست کار خاصی انجام شود و زمانیکه ()services.AddMvc را فراخوانی میکنیم، ثبت و معرفی این سرویس نیز جزئی از آن است.
اهمیت تولید Response Types صحیح
در قسمتهای قبل مشاهده کردیم که اگر متدی برای مثال در قسمتی از آن return NotFound یا 404 را داشته باشد، این نوع از خروجی، در OpenAPI Specification تولیدی لحاظ نمیشود و ناقص است و یا حتی ممکن است Response Type پیشفرض تولیدی که 200 است، ارتباطی به هیچکدام از نوعهای خروجی یک اکشن متد نداشته باشد و نیاز به اصلاح آن است. این مورد برای تکمیل مستندات یک API ضروری است و استفاده کنندگان از یک API باید بدانند چون نوع خروجیهایی را ممکن است در شرایط مختلف، دریافت کنند.
روش تغییر و اصلاح Response Type پیشفرض OpenAPI Specification
اکشن متد GetBook کنترلر کتابها، دارای دو نوع return Ok و return NotFound است؛ اما OpenAPI Specification تولیدی پیشفرض، تنها حالت return Ok یا 200 را مستند میکند. برای تکمیل مستندات این اکشن متد، میتوان به صورت زیر عمل کرد:
/// <summary> /// Get a book by id for a specific author /// </summary> /// <param name="authorId">The id of the book author</param> /// <param name="bookId">The id of the book</param> /// <returns>An ActionResult of type Book</returns> /// <response code="200">Returns the requested book</response> [HttpGet("{bookId}")] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<Book>> GetBook(Guid authorId, Guid bookId)
در اینجا StatusCodes.Status400BadRequest را نیز مشاهده میکنید. هرچند حالت return BadRequest در کدهای این اکشن متد وجود خارجی ندارد، اما در صورت بروز مشکلی در فراخوانی و یا پردازش آن، به صورت خودکار توسط فریمورک بازگشت داده میشود. بنابراین مستندسازی آن نیز ضروری است.
برای آزمایش آن، برنامه را اجرا کنید. در قسمت مستندات متد فوق، اکنون سه حالت 404، 400 و 200 قابل مشاهده هستند. برای نمونه بر روی دکمهی try it out آن کلیک کرده و زمانیکه authorId و bookId را درخواست میکند، دو Guid اتفاقی و کاملا بیربط را وارد کنید. همچنین Controls Accept header را نیز بر روی application/json قرار دهید. سپس بر روی دکمهی execute در ذیل آن کلیک نمائید. یک چنین خروجی 404 کاملی را مشاهده خواهید کرد:
در این تصویر، response body بر اساس rfc 7807 تولید میشود و استاندارد گزارش مشکلات یک API است. این مورد اکنون به صورت یک اسکیمای جدید در انتهای مستندات تولیدی نیز قابل مشاهدهاست:
بهبود مستندات تشخیص نوعهای مدلهای خروجی اکشن متدها
مورد دیگری که در اینجا جالب توجه است، تشخیص نوع خروجی، در حالت return Ok است:
در اینجا اگر بر روی لینک Schema، بجای Example value پیشفرض کلیک کنیم، تصویر فوق حاصل میشود. تشخیص این نوع، به علت استفادهی از ActionResult از نوع Book، به صورت زیر است که در ASP.NET Core 2.1 برای همین منظور (تکمیل مستندات Swagger) معرفی شدهاست:
public async Task<ActionResult<Book>> GetBook(Guid authorId, Guid bookId)
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Book))]
یک نکته: در این تصویر، در قسمت توضیحات حالت 200، عبارت "Returns the requested book" مشاهده میشود. اما در حالتهای دیگر response types تعریف شده، عبارات پیشفرض bad request و یا not found نمایش داده شدهاند. نحوهی بازنویسی این پیشفرضها، با تکمیل مستندات XMLای اکشن متد و ذکر response code دلخواه، به صورت زیر است:
/// <response code="200">Returns the requested book</response>
استفاده از API Analyzers برای بهبود OpenAPI Specification تولیدی
اکنون این سؤال مطرح میشود که پس از این تغییرات، هنوز چه مواردی در OpenAPI Specification تولیدی ما وجود خارجی ندارند و بهتر است اضافه شوند. برای پاسخ به این سؤال، از زمان ارائهی ASP.NET Core 2.2، بستهی جدید Microsoft.AspNetCore.Mvc.Api.Analyzers نیز ارائه شدهاست که کار آن دقیقا بررسی همین نقایص و کمبودها است. بنابراین ابتدا آنرا به فایل OpenAPISwaggerDoc.Web.csproj اضافه کرده و سپس دستور dotnet restore را صادر میکنیم:
<Project Sdk="Microsoft.NET.Sdk.Web"> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Mvc.Api.Analyzers" Version="2.2.0" /> </ItemGroup>
Controllers\BooksController.cs(40,17): warning API1000: Action method returns undeclared status code '404'. Controllers\BooksController.cs(89,13): warning API1000: Action method returns undeclared status code '201'.
/// <summary> /// Get the books for a specific author /// </summary> /// <param name="authorId">The id of the book author</param> /// <returns>An ActionResult of type IEnumerable of Book</returns> [HttpGet()] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesDefaultResponseType] public async Task<ActionResult<IEnumerable<Book>>> GetBooks(Guid authorId)
کار آن مدیریت تمام حالتهای دیگری است که هنوز توسط ProducesResponseTypeها تعریف یا پیشبینی نشدهاند. هرچند وجود آن میتواند در یک چنین مواردی مفید باشد، اما همواره تعریف صریح نوعهای خروجی نسبت به استفادهی از یک حالت پیشفرض برای تمام آنها، ترجیح داده میشود.
ساده سازی کدهای تکراری تعریف ProducesResponseTypeها
مواردی مانند StatusCodes.Status400BadRequest و یا 406 را در حالت عدم قبول درخواست (مثلا با انتخاب یک accept header اشتباه) و یا 500 را در صورت وجود استثنائی در سمت سرور، باید به تمام اکشن متدها نیز اضافه کرد؛ چون میتوانند تحت شرایطی، نوعهای خروجی معتبری باشند. برای خلاصه سازی این عملیات، یا میتوان این ویژگیها را بجای قراردادن آنها در بالای تعریف امضای اکشن متدها، به بالای تعریف کلاس کنترلر انتقال داد. با اینکار ویژگی که به یک کنترلر اعمال شده باشد به تمام اکشن متدهای آن نیز اعمال خواهد شد و یا حتی برای عدم تعریف این ویژگیهای تکراری به ازای هر کنترلر موجود، میتوان آنها را به صورت سراسری تعریف کرد:
namespace OpenAPISwaggerDoc.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(setupAction => { setupAction.Filters.Add( new ProducesResponseTypeAttribute(StatusCodes.Status400BadRequest)); setupAction.Filters.Add( new ProducesResponseTypeAttribute(StatusCodes.Status406NotAcceptable)); setupAction.Filters.Add( new ProducesResponseTypeAttribute(StatusCodes.Status500InternalServerError)); setupAction.Filters.Add( new ProducesDefaultResponseTypeAttribute()); setupAction.ReturnHttpNotAcceptable = true; // ...
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: OpenAPISwaggerDoc-04.zip
در قسمت بعد، روشهای دیگری را برای تکمیل مستندات خروجی API بررسی میکنیم.
jqGrid
- صفحه بندی و مرتب سازی خودکار اطلاعات به کمک jqGrid در ASP.NET MVC
- فرمت کردن اطلاعات نمایش داده شده به کمک jqGrid در ASP.NET MVC
- فعال سازی و پردازش جستجوی پویای jqGrid در ASP.NET MVC
- فعال سازی و پردازش صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid در ASP.NET MVC
- استفاده ازExpressionها جهت ایجاد Strongly typed view در ASP.NET MVC
- سفارشی سازی عناصر صفحات پویای افزودن و ویرایش رکوردهای jqGrid در ASP.NET MVC
- تهیه خروجی PDF و اکسل از حاصل جستجوی پویای jqGrid به کمک PDF Report
- آپلود فایل توسط فرمهای پویای jqGrid
- اعتبارسنجی سفارشی سمت کاربر و سمت سرور در jqGrid
- فعال سازی و پردازش Inline Add در jqGrid
- گروه بندی اطلاعات در jqGrid
- نمایش Subgrid در jqGrid
- ایجاد زیر گریدهای چند سطحی در jqGrid
- نمایش ساختارهای درختی توسط jqGrid
کتابخانه MediatR
Simple mediator implementation in .NET. In-process messaging with no dependencies.
Supports request/response, commands, queries, notifications and events, synchronous and async with intelligent dispatching via C# generic variance.
You should install MediatR with NuGet:
Install-Package MediatR
Or via the .NET Core command line interface:
dotnet add package MediatR
پیاده سازی مطلب جاری برای ASP.NET Identity 2.x یک چنین تغییراتی را پیدا میکند:
app.UseCookieAuthentication(new CookieAuthenticationOptions { // ... Provider = new CookieAuthenticationProvider { OnValidateIdentity = context => { if(shouldIgnoreRequest(context)) // How to ignore Authentication Validations for static files in ASP.NET Identity { return Task.FromResult(0); } return container.GetInstance<IApplicationUserManager>().OnValidateIdentity().Invoke(context); } }, // ... });
private static bool shouldIgnoreRequest(CookieValidateIdentityContext context) { string[] reservedPath = { "/__browserLink", "/img", "/fonts", "/Scripts", "/Content", "/Uploads", "/Images" }; return reservedPath.Any(path => context.OwinContext.Request.Path.Value.StartsWith(path, StringComparison.OrdinalIgnoreCase)) || BundleTable.Bundles.Select(bundle => bundle.Path.TrimStart('~')).Any(bundlePath => context.OwinContext.Request.Path.Value.StartsWith(bundlePath,StringComparison.OrdinalIgnoreCase)); }