I'm writing a lot of basic CRUD views and controller logic for a website I'm building. So far I've written most of my code in the controllers, this includes the usual validation, input-sanitation, and error handling. Should I be writing all my DB I/O code in my controllers? Or should I move some over to my DbContext? I ask this, because I've heard conflicting views on how much should be going on inside controller classes, versus model classes? And is it appropriate to pass an instance of the Db context out of the controller? Or should I maybe do it with extension classes, on the DbContext?
For Example:
public ActionResult Create(ThingViewModel vModel)
{
try
{
if (ModelState.IsValid)
{
var nm = vModel.ToActualModel();
nm.RelatedThing = nm.RelatedThingId == null ?
null : db.RelatedThings.Single(v => v.Id == nm.RelatedThingId);
nm.UtcCreatedOn = DateTime.UtcNow;
db.Thing.Add(nm);
db.SaveChanges();
var successMessage = "You have created a new Thing!";
return RedirectToAction("Index", new { successMessage = successMessage });
}
else
{
ViewBag.EntityName = "Thing";
ViewBag.ControllerName = "Thing";
ViewBag.Title = "Admin | Thing - Create";
return View("~/Views/Thing/Create.cshtml", vModel);
}
}
catch(Exception e)
{
var errorMessage = "An error occured when creating a new thing!";
return RedirectToAction("Index", new { errorMessage = errorMessage });
}
}
Should this become:
public ActionResult Create(ThingViewModel vModel)
{
try
{
if (ModelState.IsValid)
{
db.CreateNewThing(vModel) // Defined elsewhere
var successMessage = "You have created a new Thing!";
return RedirectToAction("Index", new { successMessage = successMessage });
}
else
{
ViewBag.EntityName = "Thing";
ViewBag.ControllerName = "Thing";
ViewBag.Title = "Admin | Thing - Create";
return View("~/Views/Thing/Create.cshtml", vModel);
}
}
catch(Exception e)
{
var errorMessage = "An error occured when creating a new thing!";
return RedirectToAction("Index", new { errorMessage = errorMessage });
}
}
Inside DbContext:
public bool CreateNewThing(ThingViewModel vModel)
{
//Thing Creation logic
Things.Add(thing);
SaveChanges();
}
For clarification, I want to write my Create/Edit/Delete logic once for each entity, and be able to use them in other controllers. So if I have Person and Pet entities, along with a PersonController and PetController, there are times where a PersonViewModel containing a List<PetViewModel> needs to be written to the database: a Person needs to be created along with each Pet. However, PetController already has public ActionResult Create(PetViewModel vm) defined, but I can't use that from inside the PersonController for just writing a new Pet to the database. So, I would like to move the db logic of Create(PetViewModel vm) somewhere else, where I can access it from inside other controllers. Where would I move it? And is it appropriate to pass a reference to my DbContext from a controller to a static helper method public static bool CreateHelper(DbContext db, PetViewModel vm)?
Things.Add(thing);, that's called repository pattern and it is viewed by the sane as an anti-pattern.