What is better way to validate business rules in ASP.NET MVC application with 3 layer architecture?

12,219

Solution 1

I would avoid using exceptions for validation purposes but rather have methods that return true/false. Obviously for some tasks where validation is data at the data tier (for example enforcing database constraints) you could use exceptions.

You may take a look at the following tutorial about validating at the service layer.

Solution 2

First of all, do not throw Exceptions as a way of validating data - that's a way too expensive operation, instead of graceful handling of invalid data.

In general, when working with an MVC/ASP.NET web application, you typically want to do validation on the client-side as well as on the server side. While your current custom validation is simple enough, you'd have to duplicate it on the client and server, which is annoying - now you have two places to maintain a single validation routine.

For this reason using data annotations via attribute on your model properties is very handy. Check out: http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

Additionally, you seem to need to do custom validation, and not just simple required/max length checks. For that you can define your own custom attributes. Check out: http://msdn.microsoft.com/en-us/library/cc668224.aspx and How to create custom validation attribute for MVC

You may also want to leverage remote validation. For that check out: http://bradwilson.typepad.com/blog/2010/01/remote-validation-with-aspnet-mvc-2.html and http://weblogs.asp.net/imranbaloch/archive/2011/02/05/new-validation-attributes-in-asp-net-mvc-3-future.aspx

Share:
12,219

Related videos on Youtube

Serghei
Author by

Serghei

Software architect. MCPD ASP.NET 4 Web

Updated on June 04, 2022

Comments

  • Serghei
    Serghei about 2 years

    I'm developing a ASP.NET MVC application with 3 layer classic architecture 1. data access (Repositories) 2. Business logic (Services ) 3. Application layer (MVC Controller classes) The task is follow there is domain class Learner and learners can take exams, taking an exam produce an order (Order class), after that the learner take an exam, we need to release results of exam for each learner(this mean give a mark and grade) and has some business rule that need to be verified 1. the results hasn't been released yet 2. all learner who has status present should has mark 3. grading boundary should be confirmed (marks and grade for exam) When user do release results all this rules should validate and if some rule doesn't satisfied should display an error message. I decided that all logic related to validation business rules keep in the Service class and if any rule not pass throw specific exception, in the controller class this exception will catch and display error to the client. Here is the code

    Service class

        public void ReleaseResults(long orderId)
        {
            var order =orderRepository.Get(orderId);
    
            Check.Require(order != null, "Order was not found");
    
    
            if (IsOrderReleased(order))
            {
                throw new ReleaseResultsException("The results has been already released", order.OrderNo);
            }
    
            if (AllLearnersHasStatusPresentAndMark(order))
            {
                throw new ReleaseResultsException("One or more learners unmarked", order.OrderNo);
            }
            if (!GradingBoundaryConfirmed(order))
            {
                throw new ReleaseResultsException("The Grading boundary needs to be confirmed", order.OrderNo);
            }
    
    
    
            foreach (var learnerDetail in order.LearnerDetails)
            {
                if (HasNotStatusPresent(learnerDetail))
                {
                    continue;
                }
                learnerDetail.SetReleasedResults();
    
            }
    
            orderRepository.SaveOrUpdate(order);
        }
    

    Controller class

            public ActionResult Release(EncryptedId orderId)
        {
            Check.Require(orderId != null, "The parameter orderId was null");
    
            try
            {
                orderReleaseResultsService.ReleaseResults(orderId);
            }
            catch (ReleaseResultsException e)
            {
                return Content(string.Format("Error: {0}", e.Message));
            }
    
            return Content(MUI.TheResultsHasBeenReleased);
        }
    

    I am not sure if this is best way to validate business rules, can anyone help me with suggestions or better solution of this problem? Thanks in advance!

  • Serghei
    Serghei about 13 years
    It is good solution but in the project I should be the reference to the using System.Web.Mvc; namespace
  • Darin Dimitrov
    Darin Dimitrov about 13 years
    @Serghei, no, not necessary. All that is needed by the service layer is the IValidationDictionary interface. The ModelStateWrapper implementation which will be passed to the constructor of your services will be defined in the Web tier. As you can see in the example, the ProductService constructor takes a IValidationDictionary in its constructor so no need to reference System.Web.Mvc.
  • Serghei
    Serghei about 13 years
    I need to validate the business rules not correct entered or something else data.
  • Kon
    Kon about 13 years
    Okay, same ideas still apply. Your custom/remove validators can validate against the necessary business rules.
  • BlackTigerX
    BlackTigerX about 13 years
    the argument about exceptions being too expensive is not valid in this context, that is not the reason to avoid exceptions, go ahead, test how many exceptions per second you can throw
  • BlackTigerX
    BlackTigerX about 13 years
    agree, using a ModelStateDictionary to pass the errors back is a much better approach
  • Kon
    Kon about 13 years
    I'm not saying they can't be handled. But it's still a more expensive operation versus gracefully handling invalid data.
  • jgauffin
    jgauffin about 13 years
    DataAnnotations can be used to validate business rules too.
  • Sohail
    Sohail over 10 years
    @DarinDimitrov, kindly help me on this question. thnx