locked
Three tier application, validation in business logic layer RRS feed

  • Question

  • User-1877113880 posted

    I have a part on the site that allows the user to register, when they post back to the controller I first check to make sure the ModelState.IsValid and if it is I then pass it to the business later to do validation on it, as follows

      [HttpPost]
            public ActionResult SignUp(UserRegister userRegister)
            {
                if (ModelState.IsValid)
                {
                    try
                    {
                        var userProfile = _loginBusiness.UserRegister(userRegister); // Call method inside business layer
                    }
                    catch (Exception e)
                    {
                        Console.Write(e);
                        ModelState.AddModelError("Error", "Unable to create your account at this time, please try again later.");
                    }
                }
    
                ModelState.AddModelError("Error", "All fields below are required.");
    
                return View(userRegister);
    
               
            }

    In my business layer I have the following method, which will return a UserProfile object after it has saved in the database, but as you can see I call a method validation.ValidateNewUser(registerModel); this particular method returns a string (which is the error message i.e EmailAddress already exists please login) but I can't return the string as the method is expecting to pass back a UserProfile object so when I say return errorMessage i get cannot convert type string to ProjectName.models.UserProfile

     public UserProfile UserRegister(UserRegister registerModel)
            {
                var validation = new ValidateRegistration();
    
                var errorMessage = validation.ValidateNewUser(registerModel);
    
                if (string.IsNullOrWhiteSpace(errorMessage))
                {
                    var model = _loginDataLayer.UserRegister(registerModel);
    
                    return model;
                }
    
                return errorMessage;
            }

    I'm not sure what the correct way to handle this would be can some one shed some light on this for me please, its also the first time I have worked with a three tier application.

    Many thanks

    Saturday, January 10, 2015 7:07 AM

Answers

  • User774448340 posted

    Hi,

    Indeed. Something like:

    var wrapperClass = _loginBusiness.UserRegister(userRegister);
    
    if (!wrapperClass.IsValid)
    {
        ModelState.AddModelError("Error", "Unable to create your account at this time, please try again later.");
        //Or you use the errors that are in the wrapperClass.ErrorMessages
        foreach(var errorMessage in wrapperClass.ErrorMessages)
        {
            ModelState.AddModelError("Error", errorMessage);
        }
    }

    Hope this helps.

    Regards,

    Yorrick

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 10, 2015 9:29 AM

All replies

  • User774448340 posted

    Hi,

    A possible solution to this problem is to make use of a wrapper class that you use as a message between the front-end layer and your business layer. It could consist of the following properties:

    • bool IsValid
    • List<string> ErrorMessages
    • UserProfile UserProfile
    • etc....

    This wrapper class you will return as a result in your UserRegister function. Based on this result you can handle it in your front-end layer.

    BTW don't send ViewModels to your business layer as they belong, in this case, to your MVC application. Use business models instead.

    Hope this helps.

    Regards,

    Yorrick

    Saturday, January 10, 2015 7:32 AM
  • User-1877113880 posted

    When you say a wrapper class in my UserRegistration function would you be able to show me a quick code sample?

    Saturday, January 10, 2015 7:35 AM
  • User774448340 posted

    Hi,

    Below code you could use:

            public WrapperClassForUserRegistration UserRegister(UserRegister registerModel)
            {
                var wrapper = new WrapperClassForUserRegistration();
                var validation = new ValidateRegistration();
    
                var errorMessage = validation.ValidateNewUser(registerModel);
                wrapper.ErrorMessages.Add(errorMessage);
    
                if (string.IsNullOrWhiteSpace(errorMessage))
                {
                    wrapper.UserProfile = _loginDataLayer.UserRegister(registerModel);
                }
                else
                {
                    wrapper.IsValid = false;
                }
    
                return wrapper;
            }
        }
    
        public class WrapperClassForUserRegistration
        {
            public bool IsValid { get; set; }
            public List<string> ErrorMessages { get; set; }
            public UserProfile UserProfile { get; set; }
        }

    Based whether the IsValid property is true or false you show the error messages in the ErrorMessages property in the front end and you do your front-end logic.

    Hope this helps.

    Regards,

    Yorrick

    Saturday, January 10, 2015 8:18 AM
  • User-1877113880 posted

    And then from the UI when the user posts I'd call the WrapperClassForUserRegistration

    Saturday, January 10, 2015 8:34 AM
  • User774448340 posted

    Hi,

    Indeed. Something like:

    var wrapperClass = _loginBusiness.UserRegister(userRegister);
    
    if (!wrapperClass.IsValid)
    {
        ModelState.AddModelError("Error", "Unable to create your account at this time, please try again later.");
        //Or you use the errors that are in the wrapperClass.ErrorMessages
        foreach(var errorMessage in wrapperClass.ErrorMessages)
        {
            ModelState.AddModelError("Error", errorMessage);
        }
    }

    Hope this helps.

    Regards,

    Yorrick

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 10, 2015 9:29 AM