views:

958

answers:

6

Hello, I have a service which has a method that's called when a certain controller method is triggered.

My service returns a custom result object PlacementResult in which I want to communicate errors that may have happened (validation) back to the controller method.

Should PlacementResult have a ModelState or a ModelStateDictionary to communicate errors back to the controller (and finally view)? How would I string this together?

Finally, how do I get the ModelState/ModelStateDictionary (whichever you tell me I should choose) back into the view (highlighting the appropriate text box, show the error message etc.)?

Thank you !

A: 

I don't know what your PlacementResult looks like, see if you can possibly utilize this in your view:

ModelState.AddModelError(ErroredProperty, ErrorMessage);

Make sure you return the object that failed back to the view

return View(myObjectInstance);
Sergey
+1  A: 

No, you do not want to add a ModelStateDictionary to your result type. There is already a ModelStateDictionary on the Controller (in the ModelState property). It is not appropriate for results to set the controller's model state. That should be done during binding or within the controller action itself. Use a custom model binder if you need to.

Your choose one can see the model state errors by examining the controller's ViewData.ModelState property.

Craig Stuntz
How can I have my service do validation though and communicate its result back to the controller? The MVC example was too confusing (there is one on the asp.net/mvc site for this but I didnt understand it)
Alex
Can you wait for the next MVC 2 preview? I think they intend to introduce a more robust validation framework. In MVC 1 you can implement IDataErrorInfo, and in MVC 2 preview 1 you can use System.ComponentModel.DataAnnotations.
Craig Stuntz
When does it come out?
Alex
My wild guess is with .NET 4. But it's just a guess. I'm not on the team. The next preview (soon) is supposed to remove the go-live restriction, and it runs on 3.5 SP 1 already.
Craig Stuntz
"It is not appropriate for results to set the controller's model state."IMHO it's valid to add model validation errors coming from service invocation to ModelState.so you can merge the errors coming from your services to ModelState.
SDReyes
A: 

Based on SoC I think you have to return errors from your services and merge them in your ModelState if needed.

But our objective is maintain decoupling and also to use ModelState.Merge() method. it isn't?

There is an concrete implementation that could help

SDReyes
A: 

You can pass the Controller to your method, since the Controller class contains the ModelState property. Once in your method you can do the following:

private PlacementResult BuildResult(Controller controller)
{
   controller.ModelState.AddModelError(propertyName, errorMessage);
}

In your action...

BuildResult(this);
if(ModelState.IsValid) {...
Dax70
A: 

Your PlacementResult should return a dictionary object or a List which you should merge with the model state at the beginning of each action. If you step through you will notice the controllers model state dictionary contains all your input fields, their values and the errors associated with them. You want to merge the PlacementResult errors into the model state dictionary at the appropriate keys. This is how the view engine knows which fields to flag as invalid.

ModelState.Merge(PlacementResult); if(ModelState.IsValid){...

jackkav
A: 

This is a good link that shows how a service can perform validation and communicate the result back to the controller:

http://www.asp.net/mvc/tutorials/validating-with-a-service-layer--cs

Rashmi Pandit