ممنون از مطلب خوبتون
به نظرم اگه جوری Sp را مینوشتید که یک ورودی متنی Query یا یک جدول موقت میگرفت و عمل Paging را روی اون انجام میداد مطلبتون بسیار کاملتر بود. مثلا ورودی Sp به این صورت بود که (1,10,'select * from Tbl_1') بازهم ممنون
بعضی وقتها مایکروسافت یکسری کارها رو اونقدر سخت میکنه !
paging هم یکی از همونها بود تازه داره پخته میشه
این syntax من رو یاد mysql انداخت
paging هم یکی از همونها بود تازه داره پخته میشه
این syntax من رو یاد mysql انداخت
SELECT column FROM table LIMIT 10 OFFSET 10
از ویژگیهای جدید و البته جالب شیرپوینت 2013 امکان استفاده از Appها میباشد. برای شناخت بیشتر appها پیشنهاد میکنم به MSDN مراجعه کنید. در این پست قصد دارم مراحل استفاده از SharePoint Marketplace مایکروسافت را برای دریافت و نصب app در سرور شیرپوینت و طریقه پیکر بندی سروربیان کنم.
اگر برای بار اول بخواهید یک app را روی سرور شیرپوینت نصب کنید ممکن است این پیغام به شما نمایش داده شود :
Sorry, apps are turned off. If you know who tuns the server, tell them to enable apps.
دقت کنید که کم رنگ بودن آیکون App به معنی عدم پشتیبانی در سرور شیرپوینت شما است و در صورت تلاش برای نصب آن این پیغام را خواهید دید :
دلیل این پیغام ( apps are turned off) تنظیم نبودن سرور شیرپوینت (Front-End) برای پشتیبانی و میزبانی از Appها میباشد . برای استفاده از appها در شیرپوینت نیازمند یک sub-domain و دیگر تنظیمات هستید تا بتوانید از appها استفاده کنید . برای این منظور مراحل زیر را پی بگیرید :
وارد سایت Office Store مایکروسافت شده و app مورد نظر خود را بیابید . در اینجا من از appهای رایگان1 مورد را انتخاب میکنم و با آن شروع میکنم : نمایش وضعیت آب و هوا در شیرپوینت .
روی Add کلیک کنید تا جزییات app و شناسه آن نمایش داده شود . سپس آن شناسه را کپی کنید : ( شناسه app مذکور WA103062091 است )
در اینجا یک بار مراحل را برای نصب app تا رسیدن به خطا پیگیری میکنیم. سپس راه حل آن بیان میشود. توجه داشته باشید که باید پس از رفع مشکل ، مراحل این قسمت از نصب app مجدد انجام شوند .
وارد سایت شده و روی آیکون چرخدنده (تنظیمات) کلیک کنید :
در پنجره باز شده شناسه app را paste کنید و جستجو را آغاز کنید :
باید در نتیجه جستجو نمایش داده شود که app در SharePoint Store یافت شد
روی لینک کلیک کنید تا نتیجه جستجو در Store نمایش داده شود :
توجه داشته باشید که در صفحه باز شده حتما یک واحد پولی و یک زبان را انتخاب نمایید .
ودر این مرحله خطای مذکور که گفته شد نمایش داده میشود :
حال به بیان راه حل میپردازیم :
برای استفاده از Appها در شیرپوینت باید سرویسهای مرتبط و زیر دامنه (CNAME) سرور مرتبط برای آن تنظیم شده باشد .
برای این منظور ابتدا تنظیمات DNS را انجام میدهیم :
برای دامنه جاری یک CNAME تعریف کنید :
Alias Name پنجره فوق به این معنا است که تمام appها در مسیری با فرمت زیر مدیریت میشوند :
AppID.app.vm-seifollahi.iri
اگر به جای *.app فقط * قرار دهید ، هر شناسه app به عنوان زیر دامنه آدرس دهی میشود که در کل تفاوتی ندارد و برای مشخص شدن بهتر این کار را انجام دادم .
برای چک کردن صحت تنظیمات خود روی مسیری مانند Apps-12345678ABCDEF.app.vm-seifollahi.iri دستور ping را اجرا نمایید.
پس از تایید این تنظیمات باید وارد CA شوید و سرویسها را تنظیم کنید : باید دو سرویس App Management Service و Subscription Setting Service در وضعیت Started باشند .
پس از چک کردن سرویسها باید تنظیمات مربوط به App Poolهای IIS و دیتابیس برای App Managemetn Service و Subscription Service تنظیم شود . برای این منظور از Power Shell کمک میگیریم و دستورات زیر را در آن اجرا میکنیم (توضیحات در کامنتها وجود دارند ) :
$account = Get-SPManagedAccount "vmseifollahi\administrator"
# Gets the name of the managed account and sets it to the variable $account for later use.
$appPoolSubSvc = New-SPServiceApplicationPool -Name SettingsServiceAppPool -Account $account
# Creates an application pool for the Subscription Settings service application.
# Uses a managed account as the security account for the application pool.
# Stores the application pool as a variable for later use.
$appPoolAppSvc = New-SPServiceApplicationPool -Name AppServiceAppPool -Account $account
# Creates an application pool for the Application Management service application.
# Uses a managed account as the security account for the application pool.
# Stores the application pool as a variable for later use.
$appSubSvc = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPoolSubSvc –Name SettingsServiceApp –DatabaseName MBS_SettingsServiceDB
# Creates the Subscription Settings service application, using the variable to associate it with the application pool that was created earlier.
# Stores the new service application as a variable for later use.
$proxySubSvc = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $appSubSvc
# Creates a proxy for the Subscription Settings service application.
$appAppSvc = New-SPAppManagementServiceApplication -ApplicationPool $appPoolAppSvc -Name AppServiceApp -DatabaseName MBS_AppServiceDB
# Creates the Application Management service application, using the variable to associate it with the application pool that was created earlier.
# Stores the new service application as a variable for later use.
$proxyAppSvc = New-SPAppManagementServiceApplicationProxy -ServiceApplication $appAppSvc
# Creates a proxy for the Application Management service application.
پس از نصب مشاهده میکنید که دیتابیسها با موفقیت نصب شدند :
حال به CA رفته ( DOMAIN/_admin/ServiceApplications.aspx ) و از Start بودن سرویسهای تنظیم شده اطمینان پیدا کنید : (از همین صفحه نیز میتوانید تنظیماتی که قبلا در power shell انجام شد را انجام دهید)
حال در CA به صفحه Apps میرویم :
و روی Configure App URL کلیک کنید :
در صورتی که پیغام زیر را مشاهده کردید ، IIS را باز کنید :
در قسمت Application Pools به دنبال SharePoint Web Service Root بگردید و آن را Start نمایید :
حال صفحه تنظیمات باز میشود . مقادیر domain و prefix را تنظیم کنید :
سپس روی OK کلیک کنید در این مرحله تنظیمات سرور شیرپوینت تمام شد و باید به ترتیب زیر آنها را restart کنید :
ابتدا SharePoint Timer service را Stop کنید.
سپس سرویس IIS را Restart کنید
حال SharePoint Timer service را Start کنید .
اکنون مراحل را مجدد از سر بگیرید یعنی روی منوی تنظیمات سایت و روی add App کلیک کنید و app را جستجو کنید و مراحل نصب را اجرا کنید تا به مرحله Add کردن app برسید . حال مشاهده میکنید که دکمه فعال بوده و میتوانید آن را نصب کنید :
پس از کلیک روی add به store preview منتقل خواهید شد : (این تصویر مربوط به محصولی دیگر است)
ممکن است پس از زدن دکمه continue خطایی مانند تصویر زیر را مشاهده کنید :
در این صورت احتمالا با کاربر System Account وارد سیستم شده اید که باید از آن خارح شده و با نام کاربری دیکری که دسترسی لازم را دارد وارد شوید .
با کلیک روی continue به marketplace مایکروسافت منتقل خواهید شد که نیازمند یک حساب کاربری در مایکروسافت میباشد :
حال پنجره زیر نمایش داده میشود و به شما اجازهی دانلود app داده میشود :
روی return to site کلیک کنید تا پنجره بعدی برای گرفتن اعتماد شما برای نصب نمایش داده شود :
روی trust it کلیک کنید تا به صفحه site Content منتقل شوید :
همانطور که مشاهده میکنید app در حال دانلود شدن است :
حال در سمت چپ سایت روی نام App کلیک کنید (ترجیحا از مرور گر IE و ورژن 9 یا 10 استفاده کنید )
حال وارد تنظمیات app میشوید (در صورت درخواست نام کاربری و کلمه عبور آن را وارد کنید)
و نتیجه این هفت خوان رستم :
نظرات اشتراکها
Kendo UI Q1 2015 منتشر شد
ریز تغییرات آن همیشه در این آدرسها منتشر میشوند:
- نسخهی اصلی: http://www.telerik.com/support/whats-new/kendo-ui/release-history
- محصور کنندهی ASP.NET MVC آن: http://www.telerik.com/support/whats-new/aspnet-mvc/release-history
- نسخهی اصلی: http://www.telerik.com/support/whats-new/kendo-ui/release-history
- محصور کنندهی ASP.NET MVC آن: http://www.telerik.com/support/whats-new/aspnet-mvc/release-history
Nowadays, I am trying to learn different design patterns in object oriented paradigm that are pretty useful to implement generic solutions for different scenarios. Few weeks ago for a job hunt, I got an assignment to do which was a web application that would interact with database, so I took it up as a challenge and decided to make it loosely coupled using design patterns which were applicable in that scenario.
علاوه بر فشرده سازی خودکار بک آپها که پیشتر در مورد آنها صحبت شد، اس کیوال سرور 2008 دو نوع فشرده سازی دیگر را نیز پشتیبانی میکند:
Row Compression :
حالت row compression نحوهی ذخیره سازی فیزیکی دادهها را تغییر میدهد. فعال سازی آن اثرات زیر را خواهد داشت:
الف) متادیتای هر رکورد را حداقل میکند (منظور از متادیتا اطلاعاتی مانند اطلاعات ستونها، طول و آفست و غیره است)
ب) دادههای عددی و رشتههایی با طول ثابت، به صورت اطلاعاتی با طول متغیر ذخیره خواهند شد، درست مانند varchar ها.
برای ایجاد جدولی که row compression در آن به صورت پیشفرض فعال است، میتوان مانند مثال زیر عمل کرد:
CREATE TABLE MyTable
(
ID int identity Primary key,
Name char(100),
Email char(100)
)
WITH (DATA_COMPRESSION = Row);
GO
Alter TABLE MyTable REBUILD WITH (DATA_COMPRESSION=Row, MAXDOP=2);
Page Compression :
در روش دوم فشرده سازی اطلاعات در اسکیوال سرور 2008 ، که مهمترین حالت موجود نیز میباشد، اطلاعات مشترک، بین سطرهای یک صفحه به اشتراک گذاشته میشوند. این روش از فناوریهای زیر استفاده میکند:
الف) روش row compression که در مورد آن صحبت شد جزئی از این روش است.
ب) Prefix Compression : به ازای هر ستون در یک صفحه، Prefix های تکراری یافت شده و در هدر مخصوص فشرده سازی ذخیره میشوند (محل این هدر پس از هدر صفحه است). سپس هرجایی که به این Prefix ها اشاره شدهباشد، عدد منحصربفرد شناسایی کننده آنها نسبت داده میشود.
ج) Dictionary Compression : در این حالت مقادیر تکراری یک صفحه جستجو شده و در هدر فشرده سازی صفحه ذخیره میشوند. حالت Prefix Compression فقط به یک ستون منحصر میشود اما Dictionary Compression به کل صفحه اعمال میگردد.
برای فعال سازی آن در یک جدول جدید به روش زیر میتوان عمل نمود:
CREATE TABLE MyTable
(
ID int identity Primary key,
Name char(100),
Email char(100)
)
WITH (DATA_COMPRESSION = Page);
Alter TABLE MyTable REBUILD WITH (DATA_COMPRESSION=Page, MAXDOP=2);
-- بررسی اینکه چه میزان فضا با اعمال فشرده سازی صفحات قابل صرفه جویی خواهد بود
EXEC sp_estimate_data_compression_savings 'schemaname', 'TableName', NULL, NULL, 'PAGE';
-- بررسی اینکه چه میزان فضا با اعمال فشرده سازی ردیفها قابل صرفه جویی خواهد بود
EXEC sp_estimate_data_compression_savings 'schemaname', 'TableName', NULL, NULL, 'ROW';
بنابراین قبل از اینکه فشرده سازی را فعال نمائید، ابتدا بررسی کنید آیا واقعا میزان قابل توجهی اطلاعات فشرده خواهند شد و نتیجه حاصل رضایت بخش است یا خیر. همچنین باید درنظر داشت که جداول و یا ایندکسهایی که read و write بالایی دارند برای این منظور مناسب نیستند. برای یافتن آنها کوئری زیر را اجرا کنید:
USE dbName;
SELECT objectname = OBJECT_NAME(s.object_id),
indexname = i.name,
i.index_id,
reads = range_scan_count + singleton_lookup_count,
'leaf_writes' = leaf_insert_count + leaf_update_count + leaf_delete_count,
'leaf_page_splits' = leaf_allocation_count,
'nonleaf_writes' = nonleaf_insert_count + nonleaf_update_count +
nonleaf_delete_count,
'nonleaf_page_splits' = nonleaf_allocation_count
FROM sys.dm_db_index_operational_stats (DB_ID(), NULL, NULL, NULL) AS s
INNER JOIN sys.indexes AS i
ON i.object_id = s.object_id
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
AND i.index_id = s.index_id
ORDER BY
leaf_writes DESC,
nonleaf_writes DESC
و جهت تکمیل مبحث میتوان به مقاله بسیار جامع زیر که اخیرا توسط مایکروسافت منتشر شده است رجوع نمود:
اشتراکها
کتابخانه WebApiThrottle
ASP.NET Web API Throttling handler, OWIN middleware and filter are designed to control the rate of requests that clients can make to a Web API based on IP address, client API key and request route.
public static void Register( HttpConfiguration config ) { config.MessageHandlers.Add( new ThrottlingHandler { Policy = new ThrottlePolicy( perSecond: 1, perMinute: 20, perHour: 200, perDay: 1500, perWeek: 3000 ) { IpThrottling = true }, Repository = new CacheRepository() } ); }
اشتراکها
تزریق وابستگی در ASP.NET 5
ASP.NET 5 has dependcy injection available at framework level and ASP.NET 5 makes heavy use of it. Most of things surrounding controllers, views and other MVC components are implemented as services that web applications consume. This post is quick overview of dependency injection in ASP.NET 5 with some examples
مطالب
مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger - قسمت چهارم - تکمیل مستندات نوعهای خروجی API
Swashbuckle.AspNetCore چگونه اطلاعات خود را فراهم میکند؟
در برنامههای 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 را مستند میکند. برای تکمیل مستندات این اکشن متد، میتوان به صورت زیر عمل کرد:
در اینجا با استفاده از ویژگی ProducesResponseType، میتوان StatusCodes بازگشتی از متد را به صورت صریحی مشخص کرد. وجود این متادیتاها سبب خواهد شد تاOpenAPI Specification تولیدی، به نحو صحیحی حالت 404 را نیز لحاظ کند.
در اینجا 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) معرفی شدهاست:
بنابراین از ASP.NET Core 2.1 به بعد، بهتر است در APIها خود از IActionResult استفاده نکنید و شروع به کار با <ActionResult<T نمائید تا بتوان مستندات بهتری را تولید کرد. اگر از IActionResult استفاده کنید، دیگر خبری از Example value و Schema تصویر فوق نخواهد بود و از روی متادیتای این اکشن متد نمیتوان نوع خروجی آنرا تشخیص داد. البته در این حالت میتوان این مشکل را به صورت زیر نیز حل کرد؛ اما باز هم بهتر است از <ActionResult<T استفاده کنید:
یک نکته: در این تصویر، در قسمت توضیحات حالت 200، عبارت "Returns the requested book" مشاهده میشود. اما در حالتهای دیگر response types تعریف شده، عبارات پیشفرض bad request و یا not found نمایش داده شدهاند. نحوهی بازنویسی این پیشفرضها، با تکمیل مستندات XMLای اکشن متد و ذکر response code دلخواه، به صورت زیر است:
استفاده از API Analyzers برای بهبود OpenAPI Specification تولیدی
اکنون این سؤال مطرح میشود که پس از این تغییرات، هنوز چه مواردی در OpenAPI Specification تولیدی ما وجود خارجی ندارند و بهتر است اضافه شوند. برای پاسخ به این سؤال، از زمان ارائهی ASP.NET Core 2.2، بستهی جدید Microsoft.AspNetCore.Mvc.Api.Analyzers نیز ارائه شدهاست که کار آن دقیقا بررسی همین نقایص و کمبودها است. بنابراین ابتدا آنرا به فایل OpenAPISwaggerDoc.Web.csproj اضافه کرده و سپس دستور dotnet restore را صادر میکنیم:
پس از نصب این ابزار جدید که به صورت افزونهای برای کامپایلر #C کار میکند، بلافاصله اخطارهایی توسط کامپایلر ظاهر خواهند شد؛ مانند:
همانطور که ملاحظه میکنید، هنوز هم نیاز به تعریف تعدادی ProducesResponseType فراموش شده وجود دارد که آنها را به صورت زیر اضافه خواهیم کرد:
در ابتدا نوعهای خروجی اکشن متد GetBooks را تکمیل میکنیم که آن نیز دارای return NotFound و همچنین return Ok است. به علاوه در اینجا ویژگی جدید ProducesDefaultResponseType را نیز ملاحظه میکنید که یک چنین خروجی را تولید میکند:
کار آن مدیریت تمام حالتهای دیگری است که هنوز توسط ProducesResponseTypeها تعریف یا پیشبینی نشدهاند. هرچند وجود آن میتواند در یک چنین مواردی مفید باشد، اما همواره تعریف صریح نوعهای خروجی نسبت به استفادهی از یک حالت پیشفرض برای تمام آنها، ترجیح داده میشود.
ساده سازی کدهای تکراری تعریف ProducesResponseTypeها
مواردی مانند StatusCodes.Status400BadRequest و یا 406 را در حالت عدم قبول درخواست (مثلا با انتخاب یک accept header اشتباه) و یا 500 را در صورت وجود استثنائی در سمت سرور، باید به تمام اکشن متدها نیز اضافه کرد؛ چون میتوانند تحت شرایطی، نوعهای خروجی معتبری باشند. برای خلاصه سازی این عملیات، یا میتوان این ویژگیها را بجای قراردادن آنها در بالای تعریف امضای اکشن متدها، به بالای تعریف کلاس کنترلر انتقال داد. با اینکار ویژگی که به یک کنترلر اعمال شده باشد به تمام اکشن متدهای آن نیز اعمال خواهد شد و یا حتی برای عدم تعریف این ویژگیهای تکراری به ازای هر کنترلر موجود، میتوان آنها را به صورت سراسری تعریف کرد:
به این ترتیب یکسری از نوعهای خروجی که ممکن است توسط خود فریمورک به صورت خودکار بازگشت داده شوند، به صورت سراسری به تمام اکشن متدهای برنامه اعمال میشوند و دیگر نیازی به تعریف دستی آنها نخواهد بود.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: OpenAPISwaggerDoc-04.zip
در قسمت بعد، روشهای دیگری را برای تکمیل مستندات خروجی 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 بررسی میکنیم.