نحوه Handle کردن درخواستهای Put ،Post و Delete در Asp.net Core Web Api
شناسه پست: 2421
بازدید: 1469

در پست قبلی، ما درخواستهای متفاوتی از GET را با کمک یک آبجکت handle ،DTO کردیم. در این پست، میخواهیم درخواستهای Put ،Post و Delete را ایجاد کنیم و با این کار، میخواهیم سمت سرور این سری از دوره (قسمت NET Core.) را تکمیل کنیم.

این مقاله، قسمتی از مجموعه آموزشی زیر میباشد:

اگر می خواهید تمام آموزشهای لازم و پایه مربوط به این دوره آموزشی را ببینید ، لطفاً روی این لینک کلیک کنید: صفحه مقدمه برای این آموزش.

این پست، شامل قسمتهای زیر میباشد:

Handle کردن درخواست POST

اول از همه، attribute را دربالای اکشن متد GetOwnerById در کنترلر Owner تغییر میدهیم:

با این تغییر، ما نام OwnerById را برای اکشن متد GetOwnerById ست کردیم. این نام را قرار است که در اکشن متد ایجاد owner جدید استفاده کنیم که نام مفیدی است.

قبل از اینکه ادامه دهیم، باید کلاس DTO دیگری ایجاد کنیم. همانطور که در قسمت قبلی گفتیم، ما از کلاس مدل، فقط برای واکشی داده از دیتابیس استفاده میکنیم و برای برگرداندن نتیجه، به یک DTO نیاز داریم. برای اکشن create هم، کار به همین صورت است. پس کلاس OwnerForCreationDto را در پوشه Entities/DataTransferObjects ایجاد میکنیم:

همانطور که میبینید، اینجا خصوصیات Id و Accounts را نداریم.

حال خط آخر را به اینترفیس IOwnerRepository اضافه میکنیم:

بعد از تغییر اینترفیس، ما آن اینترفیس را پیاده سازی میکنیم:

قبل از اینکه OwnerController را تغییر دهیم، باید یک قانون map دیگر ایجاد کنیم:

در آخر، کنترلر را به صورت زیر تغییر میدهیم:

حالا زمان آن است که این کد را با فرستادن درخواست POST با استفاده از Postman تست کنیم.

نتیجه را بررسی کنیم:

اکشن create در Net Core.

شرح کد

حالا کمی در مورد این کد توضیح میدهیم. قسمتهای interface و repository که کاملا واضح هستند، بنابراین در مورد آن صحبت نمیکنیم. اما کد درون کنترلر، شامل مواردی است که قابل ذکر میباشد.

متد CreateOwner با ویژگی [HttpPost] مزین شده است که آنرا با درخواستهای POST محدود میکند. علاوه بر این، به پارامتر owner که از سمت کلاینت می آید دقت داشته باشید. ما آن را از Uri نمیگیریم بلکه از request body میگیریم. به همین دلیل از ویژگی [FromBody] استفاده کرده ایم. همچنین آبجکت owner، یک complex type است و به این دلیل باید از [FromBody] استفاده کنیم.

اگر بخواهیم، میتوانیم در این اکشن متد صراحتا مشخص کنیم که این پارامتر را از Uri بگیرد، که برای این کار، باید پارامتر را با ویژگی [FromUri]، مزین کنیم. اگرچه من به دلایل امنیتی و پیچیدگی request ، چنین کاری را پیشنهاد نمی کنم.

از آنجایی که پارامتر owner، از سمت کلاینت می آید، امکان دارد این اتفاق بیفتد که کلاینت اصلا این پارامتر را ارسال نکند. به عبارتی، ما باید آن را در برابر مقدار پیشفرض reference type که null میباشد اعتبارسنجی کنیم.

در قسمت پایینتر در کد، شما میتوانید متوجه این قسمت از کد اعتبارسنجی شوید: if(!ModelState.IsValid) . اگر به خصوصیات مدل owner نگاه کنید: NameAddress و DateOfBirth، متوجه میشوید که همه آنها با Validation Attribute ها مزین شده اند. اگر به هر دلیل، اعتبارسنجی fail شود، در نتیجه، ModelState.IsValid مقدار false برمیگرداند که به این معنی است که مشکلی با آبجکت creation DTO پیش آمده است. در غیر اینصورت، آن true برمیگرداند که به این معنی است که مقادیر تمام خصوصیات معتبر میباشد.

ما دو map action نیز داریم. اولی، نوع OwnerForCreationDto را به نوع Owner مپ میکند، زیرا ما آبجکت OwnerForCreationDto را از کلاینت میگیریم و باید از آبجکت Owner برای اکشن create استفاده کنیم. دومین map action، نوع Owner را به نوع OwnerDto مپ میکند که نوعی است که به عنوان نتیجه برمیگردانیم.

آخرین چیزی که باید ذکر شود این قسمت از کد است:

CreatedAtRoute یک کد وضعیت 201 که بیانگر Created است را برمیگرداند. همچنین، این کد، بدنه response را با آبجکت جدید owner و همچنین، ویژگی Location در داخل response header را با آدرسی ست میکند که مربوط به دریافت owner ایجاد شده میباشد. در این متد، باید نام اکشن متد مورد نظر، که از آن برای دریافت موجودیت ایجاد شده میتوانیم استفاده کنیم را ارائه دهیم:

header اکشن create در Net Core.

اگر این آدرس را در Postman کپی کنیم، زمانیکه درخواست GET را ارسال میکنیم، در پاسخ، آبجکت owner جدیدی که ایجاد شده است را دریافت میکنیم.

Handle کردن درخواست PUT

عالی.

حالا کارمان را با درخواست PUT برای آپدیت کردن موجودیت owner ادامه میدهیم.

اول از همه،باید یک کلاس DTO دیگر اضافه کنیم:

ما همان کاری را انجام دادیم که با کلاس OwnerForCreationDto انجام دادیم. حتی اگرچه این کلاس همان OwnerForCreationDto به نظر برسد ، اما یکسان نیستند. اول از همه ، آنها یک تفاوت معنایی دارند. این کلاس، برای اکشن update و قبلی برای creation میباشد. علاوه بر این، قوانین اعتبارسنجی که برای creation DTO اعمال شده است نباید برای update DTO نیز اعمال شود. بنابراین، جداسازی آنها، یک شیوه درست میباشد.

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

حالا در مرحله بعد، باید یک قانون map جدید ایجاد کنیم:

سپس، خط آخر را به اینترفیس IOwnerRepository اضافه میکنیم:

البته که باید OwnerRepository.cs را نیز تغییر دهیم:

در آخر، OwnerController را تغییر میدهیم:

همانطور که باید متوجه شده باشید، اکشن متد با ویژگی [HttpPut] مزین شده است. علاوه بر این، این اکشن متد، دو پارامتر دریافت میکند: id موجودیتی که میخواهیم آپدیت کنیم و موجودیت با فیلدهای ویرایش شده که از body درخواست گرفته میشود. مابقی کد کاملا ساده میباشد. بعد از اعتبارسنجی، ما owner را از دیتابیس بیرون میکشیم و عملیات به روزرسانی را بر روی آن اجرا میکنیم. در آخر، ما NoContent را که بیانگر کد وضعیت 204 میباشد برمیگردانیم:

اکشن update در Net Core.

Handle کردن درخواست DELETE

برای درخواست Delete، ما باید این مراحل را دنبال کنیم:

اینترفیس:

OwnerRepository:

OwnerController:

اجازه دهید یک مورد دیگر را نیز handle کنیم. اگر شما بخواهید یک owner ای که دارای  account میباشد را حذف کنید سپس خطای 500 internal دریافت میکنید، زیرا ما مجوز allow cascade delete را در پیکربندی دیتابیسمان نداریم. حالا کاری که ما باید انجام دهیم این است که در همچین موقعیتی، یک BadRequest برگردانیم. پس برای این کار، مقداری تغییرات ایجاد میکنیم.

اینترفیس IAccountRepository را تغییر دهید:

سپس فایل AccountRepository را با افزودن یک متد جدید تغییر دهید:

در آخر، اکشن DeleteOwner در OwnerController را با افزودن یک مرحله از اعتبارسنجی دیگر قبل از حذف owner، تغییر دهید:

کل کار همین است. حالا درخواست Delete را از طریق Postman بفرستید و نتیجه را ببینید. آبجکت owner باید از دیتابیس، حذف شده باشد.

نتیجه گیری

حال که همه اینها را یاد گرفتید، تمام این اکشنها را برای موجودیت Account تکرار کنید. زیرا این شیوه، هیچ حرف و حدیثی در آن نیست. درسته؟😉

با در اختیار داشتن این کد، ما یک web API ای داریم که تمام ویژگی های مربوط به handle کردن عملیات CRUD را شامل میشود.

با مطالعه این پست، شما موارد زیر را باید یاد گرفته باشید:

  • شیوه handle کردن درخواست POST
  • شیوه handle کردن درخواست PUT
  • نحوه کدنویسی بهتر و reusable تر
  • و شیوه handle کردن درخواست DELETE

از مطالعه این مقاله از شما تشکر میکنیم و امیدواریم که برای شما مفید واقع قرار گرفته باشد.

نویسنده

امید عباسی
من امید عباسی هستم. سالهاست که در زمینه برنامه نویسی با تکنولوژی دات نت فعالیت میکنم و عاشق این هستم که تجربیات و دانش خودم را در این زمینه با دیگران به اشتراک بزارم. خیلی دوست دارم که نظر و انتقاد خودتون رو در مورد این نوشته برای من بنویسید تا بتونم در آینده، مطالب بهتر و ارزشمندتری را برای شما فراهم کنم. در صورت داشتن هرگونه سوال هم در قسمت دیدگاه ها میتونید با بنده در ارتباط باشید