مرجع تخصصی برنامه نویسان

انجمن تخصصی برنامه نویسان فارسی زبان

کاربر سایت

CES

عضویت از 1396/01/14

در کدام لایه باید بررسی شرطها قبل از عملیات CRUD انجام بشه؟

  • چهارشنبه 23 شهریور 1401
  • 21:32
تشکر میکنم

سلام دوستان

 

1- یک پروژه از نوع interface دارم که متدهای هر بخش از برنامه اونجا تعریف شده و اسم پروژه IRepository هستش. یک کلاس IUnitofWork هم داره که تمام interfaceها داخلش تعریف شده اند.

2- پروژه دیگه دارم که تمام متدهای IRepository را داخلش پیاده سازی کردم و اسم پروژه Repository هستش. یک کلاس UnitOfWork هم داره که IUnitOfWork را پیاده سازی کرده.

3- Context برنامه هم در بخش services مربوط به WebApp تعریف شده.

 

برنامه من با تعاریف بالا داره کار میکنه و هیچ مشکلی نیست. اما در لایه Repository نیاز دارم تا بررسی های بیشتری را روی داده ها انجام بدم. برای مثال متد Remove را مثال میزنم. این دستور دو Overload داره. ورودی یکی id هستش و ورودی متد دوم model هستش.

قبل از انجام عملیات Remove میخوام چند شرط زیر بررسی بشه:

1- کاربر جاری همان کاربری باشد که ردیف را قبلا ثبت کرده. در واقع باید UserId ردیف جاری با UserId کاربری که به برنامه لاگین کرده یکی باشد.

2- ردیف جاری نباید توسط کاربر Approve شده باشد (یکی از ستون های جدول هستش).

3- اگر مدیر برنامه اقدام به حذف ردیف جاری کرد، برنامه بدون در نظر گرفتن UserId این اقدام را انجام بده.

 

برای پیاده سازی سناریوی بالا من در ActionMethod کدهای زیر را نوشتم:

       public IActionResult OnPostRemove(int id)
       {
           var report = db.tblDailyReportPiping.Find(id);

           if (report == null)
               return new JsonResult(new { status = false, message = "Invalid Data" });

           //فقط کاربری که اطلاعات را تولید کرده است اجازه حذف اطلاعات را دارد
           if (report.fldUserId != HttpContext.Session.GetActiveUser_UserId())
               return new JsonResult(new { status = false, message = "Incorrect user" });

           try
           {
               //حذف ردیف مورد نظر
               if (!db.tblDailyReportPiping.Remove(report))
                   return new JsonResult(new { status = false, message = "unable to remove" });

               //ذخیره تغییرات در بانک اطلاعاتی
               if (db.SaveChangesByUserId(HttpContext.Session.GetActiveUser_UserId()) == 0)
                   return new JsonResult(new { status = false, message = "unable to save" });

               return new JsonResult(true);
           }
           catch (Exception ex)
           {
               return new JsonResult(new { status = false, message = ex.Message });
           }
       }

کدهای موجود در متد Remove در پروژه Repository بصورت زیر می باشد:

       public bool Remove(cesEntities.Models.cesProject.tblDailyReportPiping model)
       {
           if (model == null)
               throw new Exception("Invalid data");

           //فقط ردیفی را میتاون حذف کرد که تایید اولیه و تایید نهایی نشده باشد
           if (model.fldApproved || model.fldFinalized)
               throw new Exception("Approved or finalized before");

           model.fldDeleted = true;
           return true;
       }

       public bool RemoveById(int id, bool force)
       {
           return Remove(Find(id));
       }

برنامه به درستی کار میکنه و لی مساله من اینه که شرط هایی که گفتم را در ActionMethod بررسی کردم و دلیلش هم اینه که نیاز به UserId کاربر لاگین شده دارم تا بتونه با UserId ردیف جاری مقایسه کنه. از طرفی هم باید مقدار ستون Approve را هم بررسی کنه که اگر کاربر ردیف را تایید کرده باشه دیگه عملیات Remove انجام نشه و تنها مدیر برنامه باید بتونه اون را حذف کنه. حالا برای اینکه شرط UserId و Approve بررسی نشه باید بررسی بشه که آیا کاربر Admin هستش یا نه که برای این کار نیاز به اطلاعات Identity دارم. در واقع قبل از Remove کردن اطلاعات باید بررسی هایی انجام بشه که اطلاعات آن در HttpContext و یا Session و یا شاید Coookie قرار داده شده.

اگر دستور remove در سراسر برنامه من تنها از یک ActionMethod اجرا بشه هیچ مشکلی نیست و تمام بررسی ها را به ActionMethod انتقال میدم و در Repository فقط Remove را انجام میدم. ولی امکان این هست که متد از بخش های مختلف برنامه هم صدا بزنم اونوقت متد موجود در Repository هیچ شرطی را بررسی نخواهد کرد و اگر هم شرط را در جاهای دیگه بخوام بررسی کنم باید کدهای تکراری بنویسم که صحیح نیست.

سوالم در انتها این هستش که آیا باید UserId و یا پارامتری که مورد نیاز هست را برای متد Remove در Repository ارسال کنم و تمام بررسی ها اونجا انجام بشه؟ یا روش دیگه ای وجود داره؟ در جایی خواندم که باید یک لایه دیگه به نام Service هم اضافه کنم. از طرفی لایه سرویس هم یک پروه جداگانه هستش و در انتهای باز هم نیاز به اطلاعات کاربر جاری دارم که در Session و یا HttpContext قرار داده.

لطفا راهنمایی کنید که چطور این مشکل را باید حل کرد. در واقع میخوام یک متد را بصورت جامع ر جایی پیاده سازی کنم و از هر جای برنامه (چه وب و یا ویندوز) فقط اون را صدا بزنم و درگیر چگونگی حذف اطلاعات نباشم. البته سوال را در StackOverflow هم مطرح کردم:

https://stackoverflow.com/questions/73582175/which-level-is-better-for-inspection-in-crud-operation

 تشکر

پاسخ های این پرسش

تعداد پاسخ ها : 1 پاسخ
کاربر سایت

CES

عضویت از 1396/01/14

  • پنجشنبه 24 شهریور 1401
  • 22:26

سلام مجدد

 

دوستان اگر تجربه ای در این خصوص دارید لطفا راهنمایی کنید. آیا اصلا ضرورتی داره که کد کاربری در عملیات Remove و Update بررسی بشه که کاربری که قصد حذف ردیف را داره همان کاربری است که آن را تولید کرده؟ البته کاربری که به برنامه ورود کرده قطعا داده های مربوط به خودش را داره مشاهده میکنه و قطعا تغییرات هم روی ردیف های خودش اتفاق میوفته. ولی در بخش هایی از برنامه که مدیر برنامه میتونه فعالیت سایر کاربران رو ببینه میتونه کمی مهم باشه.

 

تشکر

کاربرانی که از این پست تشکر کرده اند

هیچ کاربری تا کنون از این پست تشکر نکرده است

اگر نیاز به یک مشاور در زمینه طراحی سایت ، برنامه نویسی و بازاریابی الکترونیکی دارید

با ما تماس بگیرید تا در این مسیر همراهتان باشیم :)