I'm not sure I completely understand your question, so I apologize if I misinterpreted it.
A controller may have an access to any model of your application. There is no reason to assign a set of models to every controller, and to restrict the access to those models only.
Now, a model is linked to a view (if the view requires a model). If the view HomePage
expects the model RecentPosts
, the controller has to provide the initialized RecentPosts
model to the view.
It's up to the controller to decide where and when to call a view and to pass to it a model this view requires.
So what you're suggesting / currently doing is one method, and it's certainly a valid way of gathering additional information about error messages.
It's a reasonably lightweight approach - the caller gets a success | failure message and then it's up to the caller to dig deeper for additional information if it so cares. The downside is what you alluded to with the comments - what if there are multiple issues within the validation?
It wouldn't be too hard to extend this approach so that the caller loops over a GetErrorDetails()
call until that method returns an indicator of "no more errors."
Another potential issue with this approach is the implicit assumption that the caller is in the best position to deal with whatever the error messages may be. Since you're using MVC, the controller isn't always the best layer to fix that problem. The validation errors need to be pushed back to the View so the user can correct the issue. I'm not focusing on this aspect since there are some valid counter-arguments to indicate that the Controller could / should indicate the error. That discussion is not the point of your question.
Altertnative 1
As an alternative, consider making a full blown object to return errors with. Instead of the boolean that you're currently returning, you'll return that error object instead.
Obviously, the error object will need to have a value to indicate success | failure | partial-success | whatever. The benefit is that you can now add a collection of errors within the error object itself.
Here's some pseudo-code to give you an idea of what I'm suggesting.
ErrorParent()
{
bool success;
List errorMsgs;
}
ErrorMessages()
{
string message;
int severity;
List callstack;
}
The caller has to work a little harder to determine success, but it's an equally simple ErrorParent.success
check as opposed to a success
check. Yes, yes, I know the troubles of typing out a few more characters...
If the caller cares about the errors, then it can iterate over the ErrorParent.errorMsgs
collection and see what all went wrong. If the caller doesn't care about the errors then it can pass the error object off to an error handler and let the handler do all the hard work.
Alternative 2
Instead of returning a bool for success / error, you could return a numeric value. The numeric value would indicate the number of failed validations. The Controller could pass that numeric error return to the "best" error handler for that situation, and then the error handler would loop over the GetErrorDetails()
method.
Best Answer
I think the serialization to JSON is a web concern (infrastructure), not necessarily a model concern. So invoking a helper from the controller to do the serialization is fine, I would regard it as desirable. It handles a pretty clear concern, I think it's a valid component.
The tabulation you mention however sounds like it is a model thing, I would avoid doing implicit model tranforms during the serialization step. See if the controller can ask for this tabulated model directly or if the model can supply it transparently if you don't want the controller to know about it. Either way make sure the data is fully prepared before you give it to the serializer. If the tabulation is specific to one view I might do this tabulation in a 'view model' that I situate between the views and the (domain) model.