jjczopek jjczopek - 1 month ago 17
C# Question

WebAPI 2 & Fluent validation - leverage RuleSet

I'm working on a Web API application, leveraging

FluentValidation
and
AutoMapper
and
AutoFac
. I have the basic setup, and everything is working as supposed. Validation is executed transparently for me, and in controller I can just check whether its valid or not:

[Route("")]
[HttpPost]
public HttpResponseMessage PostDinnerList(DinnerListDTO newDinnerList)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
var dinnerList = _mapper.Map<DinnerList>(newDinnerList);
dinnerList.Owner.Token = _userService.GetUserToken();
dinnerList = _dinnerListRepository.InsertDinnerList(dinnerList);
var newDinnerListDto = _mapper.Map<DinnerListDTO>(dinnerList);
return Request.CreateResponse(newDinnerListDto);
}


This is OK when I pass the DTO and save it into database. However I would like to leverage the same validator with ruleset to differentiate between when new entry is created and when it's edited as different rules kick in.

I saw that in MVC version of
FluentValidation
,
CustomizeValidatorAttribute
is available, and rulesets can be selected with it. There is nothing like that in WebAPI version.

I'm thinking how can I tackle the issue. Ideally I would like to have two actions: new/update, and use the same validator and just indicate which ruleset should be used.

Workarounds that come to my mind:


  • On edit action use different DTO than on new action and create separate validator - but I feel like creating unnecessary/duplicated/boilerplate code.

  • instantiate validator in the action with the controller manually - based on a condition, indicate ruleset and invoke validation manually - but that counterfeits whole IoC setup and abstraction.



Please advise.

Answer
  1. In case your entity for example has an auto generated Ids (identity), You can probably depend on the id of the DTO to check if your entity is new (no id set) or it is about to update (id will be set) and build your validation rules according to that using "When" or "Unless" methods.

  2. Other option is your DTO will have a state which describe the action that you want to perform, so Added, Updated, Deleted, and Unchanged, and building the validation rules around that using "When" or "Unless" methods.

Hope this helps.