How to separate model check from controller in service?

I am at the center of refactoring the project I am working on. In my existing controllers, I use the repository template, but I still ran too many scaffolding than I was comfortable with. This and some of my controllers could have 10+ repositories transferred (via Ninject). So, I decided to introduce a service level, where my intention is to have one service per controller, and each service will instead have several repositories entered into it and do the work I need. This has worked fine so far, but I'm confused: how do I transfer model validation from the controller to the service level?

For example, look at this method Editon mine OfficesController:

[HttpPost]
public async Task<RedirectToRouteResult> Edit(
    short id,
    FormCollection form,
    [Bind(Prefix = "Office.Coordinates", Include = "Latitude,Longitude")] Coordinate[] coordinates) {
    if (id > 0) {
        Office office = await this.OfficesService.GetOfficeAsync(id);

        if ((office != null)
            && base.TryUpdateModel(office, "Office", new string[2] {
                "Name",
                "RegionId"
            }, form)
            && base.ModelState.IsValid) {
            this.OfficesService.UpdateOfficeAsync(office, coordinates);
        }

        return base.RedirectToAction("Edit", new {
            id = id
        });
    }

    return base.RedirectToAction("Default");
}

, - Office , , . , . , , . Edit, , , , .

, , , , ? !

, , :

  • . .
  • Data.Google.Maps: , Kml
  • Data.Models: DbContext, , .
  • Data.Repositories. , DbContext. EF , "" . : FindTechnicians() FindActive() ..
  • Data.Services. , . , , , , .
  • . Identity ASP.NET.
  • Web.Private: MVC.
+3
1

2 , , :

: FluentValidation.NET .

- :

private readonly IExecuteCommands _commands;

[HttpPost]
public async Task<RedirectToRouteResult> Edit(short id, UpdateOffice command) {

    // with FV.NET plugged in, if your command validator fails,
    // ModelState will already be invalid
    if (!ModelState.IsValid) return View(command);

    await _commands.Execute(command);
    return RedirectToAction(orWhateverYouDoAfterSuccess);
}

DTO, viewmodel. :

public class UpdateOffice
{
    public int OfficeId { get; set; }
    public int RegionId { get; set; }
    public string Name { get; set; }
}

... :

public class ValidateUpdateOfficeCommand : AbstractValidator<UpdateOffice>
{
    public ValidateUpdateOfficeCommand(DbContext dbContext)
    {
        RuleFor(x => x.OfficeId)
            .MustFindOfficeById(dbContext);

        RuleFor(x => x.RegionId)
            .MustFindRegionById(dbContext);

        RuleFor(x => x.Name)
            .NotEmpty()
            .Length(1, 200)
            .MustBeUniqueOfficeName(dbContext, x => x.OfficeId);
    }
}

, , , , FV MVC. , ModelState.IsValid false.

, () . , 3 .

+2

All Articles