Rectangle 27 10

The controller is part of the UI. It should validate and bind for a better user experience, but the service should not rely on it.

The service cannot know how it's being called. What if you wrap it as a REST service?

The service also knows about business logic violations in a way that no UI can. It needs to validate to make sure that the use case is fulfilled appropriately.

But then why the service doesn't allow @Valid annotations? ... I got your point, service and controller can use (for example) different fields in their classes. In my app, it's always the same. Because of this, I just pass through the DTO into the service.

Because there is a difference between validation and defensive programming/error handling. That being said I do use validation for defensive programming. I'll post an answer soon.

Spring DTO validation in Service or Controller? - Stack Overflow

spring validation spring-mvc service dto
Rectangle 27 2

If you really want to do validation like error handling in your Service layer similar to Spring MVC you can use javax.validation and AspectJ (to advice the methods to validate) which is what I do because I like making reflection do the work and declarative programming (annotations).

Spring MVC doesn't need to do AspectJ/AOP to do the error handling because the methods are being called through reflection (url routing/dispatching).

Finally for you MVC code you should know that @Valid is sort of unofficially deprecated. Instead consider @Validated which will leverage more of the javax.validation features.

I now use @Validated at Service layer, which is pretty awesome. Just register Spring's MethodValidationPostProcessor, then put an @Validated annotation on the Service interface itself and last but not least put some @Valid or @NotNull annotations on the method signatures defined in the Service Interface. The ServiceImpl stays clean. This works extremely well! The only "problem" is, that the propertyPath within the thrown ConstraintViolationException get prefixed with the whole call hierarchy, i.e. controllerMethod.serviceMethod.dtoProperty. I must somehow get rid of this.

What do you mean by 'sort of unofficially deprecated'?

Spring DTO validation in Service or Controller? - Stack Overflow

spring validation spring-mvc service dto
Rectangle 27 4

Thanks Darin. I followed the approach in the article and have updated my question with my final solution and a few thoughts.

asp.net mvc - Recommended approach for model validation that needs to ...

asp.net-mvc validation asp.net-mvc-3
Rectangle 27 13

I think quite an elegant way would be to have a validate method on your service that returns a dictionary of model errors from business logic. That way, there is no injection of the ModelState to the service - the service just does validation and returns any errors. It is then up to the controller to merge these ModelState errors back into it's ViewData.

So the service validation method might look like:

public IDictionary<string, string> ValidatePerson(Person person)
{
    Dictionary<string, string> errors = new Dictionary<string, string>();

    // Do some validation, e.g. check if the person already exists etc etc

    // Add model erros e.g.:
    errors.Add("Email", "This person already exists");
}

And then you could use an extension method in your controller to map these errors onto the ModelState, something like:

public static class ModelStateDictionaryExtensions
{
    public static void Merge(this ModelStateDictionary modelState, IDictionary<string, string> dictionary, string prefix)
    {
        foreach (var item in dictionary)
        {
            modelState.AddModelError((string.IsNullOrEmpty(prefix) ? "" : (prefix + ".")) + item.Key, item.Value);
        }
    }
}

And your controller would then use:

ModelState.Merge(personService.ValidatePerson(person), "");

Would this be called from the controller before using Service.Create() (for example)? But what if Service.Create() has some specialised business logic which the passed in object fails - how would we inform the controller? It seems to me that each Service method requires its own unique validations and thus a way to inform the controller of problems. I guess my Service methods could return IDictionary?

Yes, you could call Validate separately, but validate should also be called from the service itself in the create method. That way, the create method could also return a dictionary of errors. If the dictionary is empty then validation was successful.

I think this may well be the way to go. I don't want to be throwing exceptions without good reason as suggested in many guides. Have you used this method yourself? My main concern is that if a Service method already has a return type, then I won't be able to return IDictionary. I guess this is why some guides use ModelStateWrapper.

Yes I see what you mean about returns types but I don't see why validate or create would need one. Yes, I've used this myself and it's worked well for me so far!

My current thinking is using a combination of the two techniques: have the Service expose a validate method which returns an IDictionary of validation errors. My Service create (or whatever) method will return void (or whatever) but it too will call the validate method as part of its process - if it fails validation, then create will throw an exception. This way caller can first check the POCO is valid before calling create. If they dont, potential exception!

asp.net mvc - Service Layer Validation - Stack Overflow

asp.net-mvc asp.net-mvc-3 validation
Rectangle 27 2

The issue here is validation in the service layer but how to get that information 'back up' to the web app. Something similar we discussed a bit back since the idea of dependency injection clearly comes into play here if a service is validating, you can't sinply call the service in the Model (for instance if IValidateableObject is implemented there you dont want to call the service directly)

Option 3: I didn't know about this earlier, but what appears to be a very powerful way to write validators is to use the ModelValidator class and a corresponding ModelValidatorProvider.

So basically you are injecting a validator (which would then be in your service layer) to be resolved by mvc without a need to an explicit service locator call.

c# - MVC Validation - Keep it DRY with a service layer - What is best ...

c# asp.net-mvc asp.net-mvc-3 validation model-view-controller
Rectangle 27 2

The issue here is validation in the service layer but how to get that information 'back up' to the web app. Something similar we discussed a bit back since the idea of dependency injection clearly comes into play here if a service is validating, you can't sinply call the service in the Model (for instance if IValidateableObject is implemented there you dont want to call the service directly)

Option 3: I didn't know about this earlier, but what appears to be a very powerful way to write validators is to use the ModelValidator class and a corresponding ModelValidatorProvider.

So basically you are injecting a validator (which would then be in your service layer) to be resolved by mvc without a need to an explicit service locator call.

c# - MVC Validation - Keep it DRY with a service layer - What is best ...

c# asp.net-mvc asp.net-mvc-3 validation model-view-controller
Rectangle 27 6

A common approach is to do validation on both places. But if you are talking about @Valid, from my experience it is nicer to put on Controllers level.

It also depends what kind of validation logic we are talking about. Let's say you have a bean:

@Data
public class MyBean {
    @NotNull private UUID someId;
    @NotEmpty private String someName; 
}

It would make sense for this bean to be annotated with @Valid on the controller level so it doesn't even reach the service. There is no benefit to putting the @Valid on the service method, because why would you propagate it further while you can immediately in the controller decide if it is that kind of valid or not.

Then there is a second type of validation: business logic validation. Let's say for the same bean that the someId property is a timeUUid and its timestamp needs to be at most 2 days after some event occurred, in other case, the bean should be discarded by the service.

That seems like a business logic validation case, because by just looking at the bean, you wouldn't be able to validate it, unless you apply some logic to it.

Since both approaches to validation actually validate different things, it is obvious to see that each of your MVC components - Model, View and Controller, do their own validation and it should be reasonable about what it validates without introducing dependency to the other components.

As for showing the error to the user, yes, the Errors object is indeed intended to be used for bean validation at controller level, but you can design some filter that catches exceptions on any level and then pretty formats it for the user. There are many approaches to it, and I am not sure if Spring prescribes that any is better than the other.

Depending on different resolve mechanism (as in, for example, jstl or jackson or something else), you would probably be inclined to deal with validation in a different way. For example, a traditional jstl view resolver would nicely work with a contraption that uses Errors, while a jackson resolver would probably work nicer with a combination of @ResponseBody and some filter that catches errors and puts them in a predefined error part of the response object.

@xSNRG There is no reason to do synchronization between the two validation scopes mostly. The controller layer should briefly examine any bean properties that it can validate, and if all seems valid, pass to service. Then service should do its own business validation and pass it on to the model (which should have its own domain constraints and validation thingies). If you don't tightly couple those layers, there wouldn't be much need to do any synchronization in between them, but rather just maintaining each layer on its own.

java - Validation in Spring MVC in Controllers or Service Layer? - Sta...

java spring validation spring-mvc
Rectangle 27 2

I would recommend you perform validation in both places rather than trying to turn off validation in the UI. I understand your point that the service cannot assume that it's being passed valid data - that is a valid concern and is the reason your service should have validation. But you should also have validation in your UI. This is also nice because you can have client-side validation to prevent user errors and give you users a better experience.

Thanks for your reply. I have clientside UI validation. I use the attributes in the DataAnnotations namespace for my models. My service layer adds the validation errors to the Modelstate (if in a web context). There is no reason to perform the same validation twice. :)

Basically my service layer follows this approach asp.net/mvc/tutorials/validating-with-a-service-layer--cs It works fine, but the example doesnt use the DataAnnotations attributes for validation, which are automatically validated in MVC (and what i am trying to prevent).

That link doesn't have a date as to when it was written but my guess is that it's pretty old. When MVC was first released, there was some confusion around where validation logic should go (controller, etc.). But that story has been solidified in the last year or so with the recommended best practice typically being that UI validation should happen in the model binder which is why that's now the default in MVC 2.

If you are set on doing it this way, then it could be accomplish by inheriting the DataAnnotationModelBinder and then override the OnModelUpdated() method and inside just do ModelState.Clear(). I'm not saying I would do this though. :)

I assume you are talking about the DefaultModelBinder (as there is no DataAnnotationsModelBinder - there is a DataAnnotationsModelValidator though). Doing a ModelState.Clear() inside the ModelBinder will affect the entire WebApplication which i dont want to, i want it to keep working the traditional way, but be able to disable the model validation either per action or per model type. I could of course make a big switch or if clause and add every single Model type that i dont want validated - but that would be pretty ugly i guess - but maybe it is the best option! :)

Disable Model Validation in Asp.Net MVC - Stack Overflow

asp.net-mvc model-view-controller validation model
Rectangle 27 2

WCF doesn't deal with client-side validation, because it can't know the capabilities of the client on the other end of the service. If you want to do something like this you're either going to need to:

It would be a killer feature if WCF could pass validation rules over to the client like you want, but it just can't. :(

I'm not looking to do the validation with WCF. Your #1 above is the simple description of what I was hoping to find an existing means of doing. DataAnnotations is the feature I had hoped to make use of due to the fact that the default model binder in MVC would read those attributes and create jQuery validation controls automatically. It looks like there isn't a built-in solution, so we'll look at writing our own model binder to do that for us. Thanks for your input.

I've knocked together a first-pass at this and it is working smoothly. In a nutshell, a client can invoke a method on the WCF service that returns description of the specified type's properties, along with metadata for validating those properties. Custom validation objects in the MVC app are registered to perform the metadata and validation tasks. Tomorrow I'll put together a thorough synopsis along with code samples and post it here for future reference. Thanks again. - Rick

Rick, if you could post some sample code of how you accomplished this, that would be great. I have the same problem you do...

jquery - How can I approach client-side validation with MVC and WCF wi...

jquery asp.net-mvc wcf validation
Rectangle 27 14

You can check this awesome tutorial by Stephen Walther that shows Validating with a Service Layer.

Learn how to move your validation logic out of your controller actions and into a separate service layer. In this tutorial, Stephen Walther explains how you can maintain a sharp separation of concerns by isolating your service layer from your controller layer.

This is the most correct answer. I personally further advocate not exposing services to the controller, choosing instead to use a ViewModel concept such as is found in the MVVM pattern. Imagine a scenario where you want to write a business app with a desktop interface (say, windows forms or WPF) and also a web interface. Solving that problem leads you to the "skinny controller" pattern as is advocated here also. Bottom line: never put business logic in a model or a controller and don't put anything in a controller that you don't have too.

design patterns - ASP.NET MVC - Should business logic exist in control...

asp.net-mvc design-patterns controller business-logic
Rectangle 27 14

You can check this awesome tutorial by Stephen Walther that shows Validating with a Service Layer.

Learn how to move your validation logic out of your controller actions and into a separate service layer. In this tutorial, Stephen Walther explains how you can maintain a sharp separation of concerns by isolating your service layer from your controller layer.

This is the most correct answer. I personally further advocate not exposing services to the controller, choosing instead to use a ViewModel concept such as is found in the MVVM pattern. Imagine a scenario where you want to write a business app with a desktop interface (say, windows forms or WPF) and also a web interface. Solving that problem leads you to the "skinny controller" pattern as is advocated here also. Bottom line: never put business logic in a model or a controller and don't put anything in a controller that you don't have too.

design patterns - ASP.NET MVC - Should business logic exist in control...

asp.net-mvc design-patterns controller business-logic
Rectangle 27 13

Ideally you would do it in both places. But your confusing two different things:

You absolutely should do validation in the controller and defensive programming in your service. And here is why.

You need to validate for forms and REST requests so that you can send a sensible error back to the client. This includes what fields are bad and then doing localization of the error messages... etc... (your current example would send me a horrible 500 error message with a stack trace if ProductInfo.name property was null).

Defensive programming is done in the service layer BUT NOT validation because you don't have access to locale to generate proper error messages. Some people do but Spring doesn't really help you there.

The other reason why validation is not done in the service layer is that the ORM already typically does this through the JSR Bean Validation spec (hibernate) but it doesn't generate sensible error messages.

One strategy people do is to create there own preconditions utils library that throws custom derived RuntimeExceptions instead of guava's (and commons lang) IllegalArgumentException and IllegalStateException and then try...catch the exceptions in the controller converting them to validation error messages.

spring - Check preconditions in Controller or Service layer - Stack Ov...

spring validation service controller
Rectangle 27 6

Have your service layer throw exceptions on business rule/validation rule failure. Create your own validation Exception for this, and include some properties to hold details of the validation error - (e.g. which property has the validation error, and what the message is)

Then create an extension method on Exception which will copy the details of the error to the ModelState (I got this idea from Steve Sandersons rather excellent 'Pro Asp.Net MVC 2 Framework' book) - if you do this right, MVC will highlight invalid fields, show errors in the UI etc.

try
{
    Service.DoSomeThing();
}
catch (Exception err)
{
    err.CopyTo(ModelState);
}

This means that your business rules and validation are now in your service layer, and this could be re-used.

Then the DTOs / View Models can reside in the MVC layer, and you can decorate these with the Validation attributes, and have the controller pass these to the views - thus using the built in MVC validation.

You will find that for any complex project, the validation you require at the UI end may be slightly different from what you require at the business rules end, so this helps seperate that.

There is a good library called AutoMapper which makes it easy to map from your domain objects to your DTOs (and vice versa) without a lot of boilerplate code.

Hmm, I'm not sure invalid data is "exceptional" and worthy of an exception. Why do you choose exceptions over returning a result or using built-in validation interfaces?

I agree, it's more that any invalid data not caught by the MVC layer validation is exceptional, and is caught by the serice layer. I'm actually using the NHibernate.Validator for the validation side of things, which throws exceptions in the datalayer. I am using the builtin validation interfaces as well in the MVC layer. The idea is the MVC layer should catch the input errors using built in data annotation, but if invalid data does get past the MVC layer, the service layer will throw an exception

Ok, that makes more sense. Personally, I do not do things that way, but I see merit in your clarification.

I like this except it will only notify the client of the first validation failure. If there are a bunch of validation failures in the request, the client will have to fix them one at a time and resend the entire request after each fix.

c# - MVC Validation - Keep it DRY with a service layer - What is best ...

c# asp.net-mvc asp.net-mvc-3 validation model-view-controller
Rectangle 27 6

Have your service layer throw exceptions on business rule/validation rule failure. Create your own validation Exception for this, and include some properties to hold details of the validation error - (e.g. which property has the validation error, and what the message is)

Then create an extension method on Exception which will copy the details of the error to the ModelState (I got this idea from Steve Sandersons rather excellent 'Pro Asp.Net MVC 2 Framework' book) - if you do this right, MVC will highlight invalid fields, show errors in the UI etc.

try
{
    Service.DoSomeThing();
}
catch (Exception err)
{
    err.CopyTo(ModelState);
}

This means that your business rules and validation are now in your service layer, and this could be re-used.

Then the DTOs / View Models can reside in the MVC layer, and you can decorate these with the Validation attributes, and have the controller pass these to the views - thus using the built in MVC validation.

You will find that for any complex project, the validation you require at the UI end may be slightly different from what you require at the business rules end, so this helps seperate that.

There is a good library called AutoMapper which makes it easy to map from your domain objects to your DTOs (and vice versa) without a lot of boilerplate code.

Hmm, I'm not sure invalid data is "exceptional" and worthy of an exception. Why do you choose exceptions over returning a result or using built-in validation interfaces?

I agree, it's more that any invalid data not caught by the MVC layer validation is exceptional, and is caught by the serice layer. I'm actually using the NHibernate.Validator for the validation side of things, which throws exceptions in the datalayer. I am using the builtin validation interfaces as well in the MVC layer. The idea is the MVC layer should catch the input errors using built in data annotation, but if invalid data does get past the MVC layer, the service layer will throw an exception

Ok, that makes more sense. Personally, I do not do things that way, but I see merit in your clarification.

I like this except it will only notify the client of the first validation failure. If there are a bunch of validation failures in the request, the client will have to fix them one at a time and resend the entire request after each fix.

c# - MVC Validation - Keep it DRY with a service layer - What is best ...

c# asp.net-mvc asp.net-mvc-3 validation model-view-controller
Rectangle 27 2

There is no "better" way. If you think that the service is going to be used by multiple controllers (or other pieces of code), then it may well make sense to do the checks there. If it's important to your application to check invalid requests while they're still in the controller, it may well make sense to do the checks there. These two, as you have noticed, are not mutually exclusive. You might have to check twice to cover both scenarios.

Another possible solution: use Bean Validation (JSR-303) to put the checks (preconditions) onto the ProductInfo bean itself. That way you only specify the checks once, and anything that needs to can quickly validate the bean.

Definitely agree that you should use bean validation, especially if your DAO is using ORM.

spring - Check preconditions in Controller or Service layer - Stack Ov...

spring validation service controller
Rectangle 27 2

  • Create a User class to wrap the CreateUser() method and add the DataAnnotations to that (this is what I would do, it allows you to go strongly-typed.)
  • Call the CreateUser() method directly from the controller Action and use server-side validation. Add each validation error in the CreateUser() result to the ModelState.Errors collection when any validation rules are violated.

Thanks! I think for our purposes we'll go with ModelState.Errors as this ensures that we can leave all the validation rules enitrely with the service

asp.net - Object property validation in MVC (using web service) - Stac...

asp.net asp.net-mvc web-services validation
Rectangle 27 14

You can do it, but JSF ajax/action/listener methods are semantically the wrong place to do validation. You actually don't want to get that far in JSF lifecycle if you've wrong input values in the form. You want the JSF lifecycle to stop after JSF validations phase.

You want to use a JSR303 Bean Validation annotation (@NotNull and friends) and/or constraint validator, or use a JSF Validator (required="true", <f:validateXxx>, etc) for that instead. It will be properly invoked during JSF validations phase. This way, when validation fails, the model values aren't updated and the business action isn't invoked and you stay in the same page/view.

As there isn't a standard Bean Validation annotation or JSF Validator for the purpose of checking if a given input value is unique according the database, you'd need to homegrow a custom validator for that.

I'll for both ways show how to create a custom validator which checks the uniqueness of the username.

First create a custom @Username constraint annotation:

@Constraint(validatedBy = UsernameValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Username {
    String message() default "Username already exists";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

With this constraint validator (note: @EJB or @Inject inside a ConstraintValidator works only since CDI 1.1; so if you're still on CDI 1.0 then you'd need to manually grab it from JNDI):

public class UsernameValidator implements ConstraintValidator<Username, String> {

    @EJB
    private UserService service;

    @Override
    public void initialize(Username constraintAnnotation) {
        // If not on CDI 1.1 yet, then you need to manually grab EJB from JNDI here.
    }

    Override
    public boolean isValid(String username, ConstraintValidatorContext context) {
        return !service.exist(username);
    }

}

Finally use it as follows in model:

@Username
private String username;

An alternative is to use a custom JSF validator. Just implement the JSF Validator interface:

@ManagedBean
@RequestScoped
public class UsernameValidator implements Validator {

    @EJB
    private UserService userService;

    @Override
    public void validate(FacesContext context, UIComponent component, Object submittedAndConvertedValue) throws ValidatorException {
        String username = (String) submittedAndConvertedValue;

        if (username == null || username.isEmpty()) {
            return; // Let required="true" or @NotNull handle it.
        }

        if (userService.exist(username)) {
            throw new ValidatorException(new FacesMessage("Username already in use, choose another"));
        }
    }

}

Finally use it as follows in view:

<h:inputText id="username" ... validator="#{usernameValidator}" />
<h:message for="username" />
@FacesValidator
Validator
@EJB
@Inject

Thanks BalusC. Will this validator be called before or after the bean validation does its checks or the order is not specified?

JSF validation is executed before Bean validation. But if the value is null or empty then JSF validation other than required won't be executed. So if you've a @NotNull without required="true", then it will be executed first. But if it is not empty and you have for example a @Pattern, then the JSF validator will be called first.

You are awesome. but can i not just use the normal jsf validator but only validate the property using bean validation? If it is valid then I can check the database. I tried the validateProperty method of the Validator class but I couldn't just get it to work because it was asking for groups and other semantics I didn't understand

How to perform JSF validation in actionListener or action method? - St...

validation jsf bean-validation
Rectangle 27 1

Assuming that you want both client and server-side validation of the model based upon the values returned from the service, I would opt for 2., Inject the service into an annotation.

I give some sample code in my response to this question about adding validators to a model. The only additional step in your case is that you will need to inject your service into your class inheriting from DataAnnotationsModelValidatorProvider.

validation - ASP.NET MVC 3: Validating model when information external...

asp.net-mvc-3 validation
Rectangle 27 1

Assuming that you want both client and server-side validation of the model based upon the values returned from the service, I would opt for 2., Inject the service into an annotation.

I give some sample code in my response to this question about adding validators to a model. The only additional step in your case is that you will need to inject your service into your class inheriting from DataAnnotationsModelValidatorProvider.

validation - ASP.NET MVC 3: Validating model when information external...

asp.net-mvc-3 validation
Rectangle 27 14

Option 1 doesn't fit. The only way it would work would be to pull in the dependency via the service locator anti-pattern.

Option 2 doesn't work. Although I couldn't see how this was possible because of the C# attribute requirements, it is possible. See the following for references:

Option 3: I didn't know about this earlier, but what appears to be a very powerful way to write validators is to use the ModelValidator class and a corresponding ModelValidatorProvider.

public class CustomModelValidatorProvider : ModelValidatorProvider
{
    public CustomModelValidatorProvider(/* Your dependencies */) {}

    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {
        if (metadata.ModelType == typeof(YourModel))
        {
            yield return new YourModelValidator(...);
        }
    }
}

ASP.NET MVC's IDependencyResolver will attempt to resolve the above provider, so as long as it's registered with your IoC container you won't need to do anything else. And then the ModelValidator:

public class EntryRatingViewModelValidatorMvcAdapter : ModelValidator
{
    public EntryRatingViewModelValidatorMvcAdapter(
            ModelMetadata argMetadata,
            ControllerContext argContext)
                : base(argMetadata, argContext)
    {
        _validator = validator;
    }


    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        if (/* error condition */)
        {
            yield return new ModelValidationResult
              {
                MemberName = "Model.Member",
                Message = "Rating is required."
              };
        }
    }
}

As the provider is retrieved through the IDependencyResolver and the provider has full control over the returned ModelValidators I was easily able to inject the dependencies and perform necessary validation.

I am using MVC5 but I think the above it still relevant. You've said that "MVC's IDependencyResolver will attempt to resolve the provider". But how would you register the provider with the IoC container? (Unity in my case).

validation - ASP.NET MVC 3: Validating model when information external...

asp.net-mvc-3 validation