I'm implementing an MVC solution that has some Web API endpoints for various data queries. I'm using the techniques described in this post to separate my validation concerns to a Services layer.
This post has a TL;DR at the end if you want to skip to the specific question.
Here is my ApiController
code:
[Authorize]
public class FriendsController : ApiController
{
private IItemService _service;
public FriendsController()
{
_service = new ItemService(new HttpModelStateWrapper(ModelState), new ViewModelRepository());
}
public FriendsController(IItemService service)
{
_service = service;
}
// GET api/friends
public IEnumerable<User> Get()
{
return _service.GetFriends(User.Identity.Name);
}
.
.
.
// POST api/friends
public void Post(Guid id)
{
var user = _service.AddFriend(User.Identity.Name, id); // Handles error and should update ViewModel
NotificationAsyncController.AddNotification(user);
}
}
and the code for _service.AddFriend(User.Identity.Name, id);
looks like this:
public User AddFriend(string userName, Guid id)
{
try
{
return _repository.AddFriend(userName, id);
}
catch (Exception e)
{
_validationDictionary.AddError("AddFriend", e.Message);
return null;
}
}
And _validationDictionary
looks like this:
public class HttpModelStateWrapper : IValidationDictionary
{
private ModelStateDictionary ModelState;
public HttpModelStateWrapper(ModelStateDictionary ModelState)
{
this.ModelState = ModelState;
}
public void AddError(string key, string errorMessage)
{
if (ModelState != null)
ModelState.AddModelError(key, errorMessage);
}
public bool IsValid
{
get { return ModelState == null ? false : ModelState.IsValid; }
}
}
Well, I found out that if _repository.AddFriend(userName, id);
throws an error and _validationDictionary.AddError("AddFriend", e.Message);
is called, the ModelState object that is in _validationDictionary
does not update the ModelState object that resides in the FriendsController
.
In other words, after AddError
is called, the ModelState in the HttpModelStateWrapper
is not valid, but once that method returns and scope is returned to the FriendsController
, its ModelState has not updated and is still valid!
How do I get the ModelState object that I've passed into the HttpModelStateWrapper
in the ctor of the FriendsController
have its changes reflected in the ModelState object of the FriendsController
?
I ended up just passing the whole controller and that gave me access to the ModelState object