Search code examples
c#entity-frameworkrepositoryunit-of-work

Which Level is Better For Inspection in CRUD Operation?


I am using UnitOfWork pattern in my application. I implemented Remove method in Page like bellow:

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

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

    //Only user whci created data can remove data
    if (report.fldUserId != HttpContext.Session.GetActiveUser_UserId())
        return new JsonResult(new { status = false, message = "Incorrect user" });

    //current row shal no be approved or finalized
    if (report.fldApproved || report.fldFinalized)
        return new JsonResult(new { status = false, message = "Approved or finalized before" });

    try
    {
        //remove
        if (!db.tblDailyReportPiping.Remove(report))
            return new JsonResult(new { status = false, message = "unable to remove" });

        //save
        if (db.SaveChangesByUserId(HttpContext.Session.GetActiveUser_UserId()) == 0)
            return new JsonResult(new { status = false, message = "unable to save" });
    }
    catch (Exception ex)
    {
        return new JsonResult(new { status = false, message = ex.Message });
    }

    return new JsonResult(true);
}

Before using Remove method from UOW, I inspected situation like userId and other situation. My question is: In which level I must inspect situation before CRUD operation? Both is possible, less code in action control or in repository but, which one is best practice?

I may use Remove from repository from different part of my application and by moving all code to repository I can lessen code line throughout in my application and just use Remove method from repository but, I must pass some extra parameter to method like userId, is it correct approach?

Thank you all


Solution

  • Your action methods should be tiny and usually consist of max 3 lines. To do that create a new DailyReportPipingService and then move all of the OnPostRemove method's code to a new method there called public Result RemoveReport(int userId). Now use this new method in your action method. The Result will have a T Result property and a bool Success and string? ErrorMessage properties. Your validation logic is fine and can be extracted/refactored to a new method in that service to use it in other methods as well. If you don't like this type of validation, you can also create a custom ActionFilterAttribute for it and do your validation and if there's an error, add it to the ModelState.AddModelError() of the ActionFilter. This is how the AOP/Aspect oriented programming is implemented in the MVC using ActionFilters. Also you can change the int id parameter of the OnPostRemove method to a class and write a custom validator for it. Usually the validation is a cross-cutting concern and shouldn't be mixed with your business logic. So writing a custom validator for the action method's parameter is a better choice here.