My View Model looks like this:
public class ProductVM
{
public string SerialNumber { get; set; }
// Other properties left out for brevity
}
In the form that fills this model, users can supply the SerialNumber of the Product or they can supply the ProductId. The SerialNumber is always 100 characters long and the ProductId is always 50 characters long.
My current solution is to get the SerialNumber from database if ProductId is supplied, inside the Action method of the Controller, after checking if ModelState.IsValid. From my view of thinking, this is bad because of the following reasons:
- All validation logic on the parameters data passed to the action method(same goes for View Models) should be done when calling
ModelState.IsValid. - It makes the controller 'Fat' which is viewed as an anti-pattern, as it makes it harder to understand the flow of the process.
What I want to know is:
- Should I leave the code as is?
- Should I move this check/transformation outside the controller action method, and if so, where?
- Should I make new
Service Queryto fetch the needed data, but instead of querying bySerialNumber, to query byProductId? (This solution looks to me like repetition of code for most of the part)
Currently my Action method looks like this:
[HttpPost]
public ActionResult GenerateReport(ProductVM vm)
{
if(ModelState.IsValid == false)
{
vm.Rehydrate();
return View(vm);
}
// If Length is 100 then ProductId has been supplied, query database to find SerialNumber
if(vm.SerialNumber.Length == 100)
{
vm.SerialNumber = _db.GetSerialNumber(vm.SerialNumber);'
// This is the thing that I don't like.
// Multiple places where data validation of View Model is being done inside Controller.
if(string.IsNullOrEmpty(vm.SerialNumber))
{
ModelState.AddModelError("", "No Product has been found with the given ProductId!");
return View(vm);
}
}
var reportData = _productDomainService.GetReportData(vm.SerialNumber);
var report = _infrastructure.GenerateReport(reportData);
// Rest of code left out for brevity
}