Monthly Archives: June 2014

Keeping domain models and view models separate with ASP.NET MVC and WCF

The location, role and responsibility of objects within a software system is a common topic in the forums with plenty of disagreement about what is and isn’t correct. But first, let’s just define some commonly found objects and their roles:

Domain repository entity: Object which is an in-memory representation of a record persisted in some sort of backing data store. In most business scenarios, a repository entity will be mapped to a physical database table via an ORM tool such as NHibernate or the Microsoft Entity Framework. 

Domain model entity: An object which lives in the service layer and typically contains both logic and/or data. This is where your business rules should be defined. Often, a domain model entity and a domain repository entity will be the same thing. In other words, an object which contains business logic and is also mapped to a data store (e.g. an Order domain entity may be mapped to an Order database table, but also contains business logic to calculate the total cost of the order, including tax). This arrangement allows data to be processed by business code and persisted via the same object.

Data contract: This is a DTO (data transfer object) which is decorated with the WCFDataContract attribute. This is essentially a ‘dumb’ object containing just data and no logic, and is used to pass data across service boundaries via serialisation. Data contracts will usually by mapped to domain models to copy data from one to the other.

View model: Another type of DTO but limited to just the MVC UI layer. View model objects are used to pass data between MVC controller action methods and the views which display and capture model data.

follow url Passing data between services and the web UI
So with these definitions in mind, it is OK (and necessary) for data contracts which are defined in your WCF service layer to be passed to and from your MVC web application. However for this to be possible, the MVC web app must have access to the data contract type declarations. The way you achieve this is to always have your WCF service implementation and WCF service & data contracts in separate assemblies. Then from your MVC web app, you can reference the project/assembly containing the service & data contracts (but do not reference the service implementation assembly).  Now your MVC web app can happily use data contracts defined in the service layer, and will still compile.

However it’s not OK for domain entities to be passed across the same service boundaries because then you blur the line between what should be a simple data transfer object and something containing logic which should never be directly exposed to your MVC views and controllers. Ignore this at your peril otherwise you will end up with business logic contaminating your UI layer which will lead to no end of problems in the future and result in a lot of refactoring and maintenance.

But how do you keep them apart?  Well from a coding point of view, one approach is that only classes that have absolutely no business logic should be decorated with DataContractand DataMember attributes. This prevents serialisation of domain entities meaning that they can’t accidentally or intentionally be used as a parameter in service contract. Another more basic check is to make sure that the web UI project never references an assembly containing domain entities (sounds obvious but I’ve seen it happen). This will keep them safely isolated from the UI. However from a physical point of view, the simple answer is that you can’t absolutely guarantee this won’t happen. It only takes one developer to unwittingly do the wrong thing and the rot starts to set in.

So if you can’t physically keep them apart, what can you do to contain the problem?  Well you have to rely on some fundamental development techniques which have been around for years: discipline, team communication and code reviews. OK I’m not going to win any awards for innovation here, but building a reliable system is more than just writing a lot of tests and then assuming everything’s OK. You have to enforce design rules and best practices which the development team sticks to, and the appropriate use of domain entities, view models, data contracts, etc. is all part of that.

source Passing data within the UI
Any application with an MVC web client and WCF services will reach a point where types defined in the service layer and types defined in the web UI meet, and in most cases that will happen in your MVC controllers. But for most scenarios, that’s the only time they will share the same space. It will also help if you give data contracts and view models different names. View model names typically should reflect the view they relate to, and I usually add a ‘Model’ suffix to them for clarity (but it’s down to personal preference how you do it). However if you are using the SvcUtil tool to generate service proxies, I recommend you specify a namespace so that it’s clear which models are defined in the service layer (see this post for generating service proxies).

In a typical case where you need to get data from a view model object into a data contract object so that it can be sent to a service, all you have to do is map the properties between the two via an object initialiser, in a constructor, or using a mapping tool such as AutoMapper, although AutoMapper can be quite hungy on memory resources so be aware of this when you decide what to use. Writing your own mapping code is trivial so why use anything else?

There’s a bone of contention about whether data contracts defined in the service layer should be used as view models. Personally I don’t have a problem with it and actually prefer to have my view model types declared as data contracts in the service layer rather than in the MVC app. This is so I only have to define data annotation validation rules once rather than defining them against data contracts in the service layer, and then again for  view models in the MVC application. This makes unit/integration testing easier and reduces the chance of a property not being validated properly. As a result, data contracts declared in the service layer are passed directly into my views (so there are very few actual view models declared in the MVC app).

However you may not like this and prefer to have separate, dedicated view models because it avoids the situation where views end up being strongly-typed to classes defined in a different layer of your architecture. How you do it is entirely down to person choice.

original article by Phil Munro

Validating with a Service Layer

original article By Stephen Walther|March 2, 2009

http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs

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.

The goal of this tutorial is to describe one method of performing validation in an ASP.NET MVC application. In this tutorial, you learn how to move your validation logic out of your controllers and into a separate service layer.

Separating Concerns

When you build an ASP.NET MVC application, you should not place your database logic inside your controller actions. Mixing your database and controller logic makes your application more difficult to maintain over time. The recommendation is that you place all of your database logic in a separate repository layer.

For example, Listing 1 contains a simple repository named the ProductRepository. The product repository contains all of the data access code for the application. The listing also includes the IProductRepository interface that the product repository implements.

Depakote online no prescription Listing 1 — Models\ProductRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace MvcApplication1.Models
{
    public class ProductRepository : MvcApplication1.Models.IProductRepository
    {
        private ProductDBEntities _entities = new ProductDBEntities();


        public IEnumerable<Product> ListProducts()
        {
            return _entities.ProductSet.ToList();
        }


        public bool CreateProduct(Product productToCreate)
        {
            try
            {
                _entities.AddToProductSet(productToCreate);
                _entities.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }


    }

    public interface IProductRepository
    {
        bool CreateProduct(Product productToCreate);
        IEnumerable<Product> ListProducts();
    }


}

The controller in Listing 2 uses the repository layer in both its Index() and Create() actions. Notice that this controller does not contain any database logic. Creating a repository layer enables you to maintain a clean separation of concerns. Controllers are responsible for application flow control logic and the repository is responsible for data access logic.

Listing 2 – Controllers\ProductController.cs

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductRepository _repository;

        public ProductController():
            this(new ProductRepository()) {}


        public ProductController(IProductRepository repository)
        {
            _repository = repository;
        }


        public ActionResult Index()
        {
            return View(_repository.ListProducts());
        }


        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude="Id")] Product productToCreate)
        {
            _repository.CreateProduct(productToCreate);
            return RedirectToAction("Index");
        }


    }
}

Creating a Service Layer

So, application flow control logic belongs in a controller and data access logic belongs in a repository. In that case, where do you put your validation logic? One option is to place your validation logic in a service layer.

A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer. The service layer contains business logic. In particular, it contains validation logic.

For example, the product service layer in Listing 3 has a CreateProduct() method. The CreateProduct() method calls the ValidateProduct() method to validate a new product before passing the product to the product repository.

erythromycin 250 mg acne reviews Listing 3 – Models\ProductService.cs

using System.Collections.Generic;
using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class ProductService : MvcApplication1.Models.IProductService
    {

        private ModelStateDictionary _modelState;
        private IProductRepository _repository;

        public ProductService(ModelStateDictionary modelState, IProductRepository repository)
        {
            _modelState = modelState;
            _repository = repository;
        }

        protected bool ValidateProduct(Product productToValidate)
        {
            if (productToValidate.Name.Trim().Length == 0)
                _modelState.AddModelError("Name", "Name is required.");
            if (productToValidate.Description.Trim().Length == 0)
                _modelState.AddModelError("Description", "Description is required.");
            if (productToValidate.UnitsInStock < 0)
                _modelState.AddModelError("UnitsInStock", "Units in stock cannot be less than zero.");
            return _modelState.IsValid;
        }

        public IEnumerable<Product> ListProducts()
        {
            return _repository.ListProducts();
        }

        public bool CreateProduct(Product productToCreate)
        {
            // Validation logic
            if (!ValidateProduct(productToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreateProduct(productToCreate);
            }
            catch
            {
                return false;
            }
            return true;
        }


    }

    public interface IProductService
    {
        bool CreateProduct(Product productToCreate);
        IEnumerable<Product> ListProducts();
    }
}

The Product controller has been updated in Listing 4 to use the service layer instead of the repository layer. The controller layer talks to the service layer. The service layer talks to the repository layer. Each layer has a separate responsibility.

Listing 4 – Controllers\ProductController.cs

Listing 4 – Controllers\ProductController.cs
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductService _service;

        public ProductController()
        {
            _service = new ProductService(this.ModelState, new ProductRepository());
        }

        public ProductController(IProductService service)
        {
            _service = service;
        }


        public ActionResult Index()
        {
            return View(_service.ListProducts());
        }


        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude = "Id")] Product productToCreate)
        {
            if (!_service.CreateProduct(productToCreate))
                return View();
            return RedirectToAction("Index");
        }


    }
}

Notice that the product service is created in the product controller constructor. When the product service is created, the model state dictionary is passed to the service. The product service uses model state to pass validation error messages back to the controller.

Decoupling the Service Layer

We have failed to isolate the controller and service layers in one respect. The controller and service layers communicate through model state. In other words, the service layer has a dependency on a particular feature of the ASP.NET MVC framework.

We want to isolate the service layer from our controller layer as much as possible. In theory, we should be able to use the service layer with any type of application and not only an ASP.NET MVC application. For example, in the future, we might want to build a WPF front-end for our application. We should find a way to remove the dependency on ASP.NET MVC model state from our service layer.

In Listing 5, the service layer has been updated so that it no longer uses model state. Instead, it uses any class that implements the IValidationDictionary interface.

Listing 5 – Models\ProductService.cs (decoupled)

using System.Collections.Generic;

namespace MvcApplication1.Models
{
    public class ProductService : IProductService
    {

        private IValidationDictionary _validatonDictionary;
        private IProductRepository _repository;

        public ProductService(IValidationDictionary validationDictionary, IProductRepository repository)
        {
            _validatonDictionary = validationDictionary;
            _repository = repository;
        }

        protected bool ValidateProduct(Product productToValidate)
        {
            if (productToValidate.Name.Trim().Length == 0)
                _validatonDictionary.AddError("Name", "Name is required.");
            if (productToValidate.Description.Trim().Length == 0)
                _validatonDictionary.AddError("Description", "Description is required.");
            if (productToValidate.UnitsInStock < 0)
                _validatonDictionary.AddError("UnitsInStock", "Units in stock cannot be less than zero.");
            return _validatonDictionary.IsValid;
        }

        public IEnumerable<Product> ListProducts()
        {
            return _repository.ListProducts();
        }

        public bool CreateProduct(Product productToCreate)
        {
            // Validation logic
            if (!ValidateProduct(productToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreateProduct(productToCreate);
            }
            catch
            {
                return false;
            }
            return true;
        }


    }

    public interface IProductService
    {
        bool CreateProduct(Product productToCreate);
        System.Collections.Generic.IEnumerable<Product> ListProducts();
    }
}

The IValidationDictionary interface is defined in Listing 6. This simple interface has a single method and a single property.

Listing 6 – Models\IValidationDictionary.cs

namespace MvcApplication1.Models
{
    public interface IValidationDictionary
    {
        void AddError(string key, string errorMessage);
        bool IsValid { get; }
    }
}

The class in Listing 7, named the ModelStateWrapper class, implements the IValidationDictionary interface. You can instantiate the ModelStateWrapper class by passing a model state dictionary to the constructor.

Listing 7 – Models\ModelStateWrapper.cs

using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class ModelStateWrapper : IValidationDictionary
    {

        private ModelStateDictionary _modelState;

        public ModelStateWrapper(ModelStateDictionary modelState)
        {
            _modelState = modelState;
        }

        #region IValidationDictionary Members

        public void AddError(string key, string errorMessage)
        {
            _modelState.AddModelError(key, errorMessage);
        }

        public bool IsValid
        {
            get { return _modelState.IsValid; }
        }

        #endregion
    }
}

Finally, the updated controller in Listing 8 uses the ModelStateWrapper when creating the service layer in its constructor.

Listing 8 – Controllers\ProductController.cs

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductService _service;

        public ProductController()
        {
            _service = new ProductService(new ModelStateWrapper(this.ModelState), new ProductRepository());
        }

        public ProductController(IProductService service)
        {
            _service = service;
        }


        public ActionResult Index()
        {
            return View(_service.ListProducts());
        }


        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude = "Id")] Product productToCreate)
        {
            if (!_service.CreateProduct(productToCreate))
                return View();
            return RedirectToAction("Index");
        }


    }
}

Using the IValidationDictionary interface and the ModelStateWrapper class enables us to completely isolate our service layer from our controller layer. The service layer is no longer dependent on model state. You can pass any class that implements the IValidationDictionary interface to the service layer. For example, a WPF application might implement the IValidationDictionary interface with a simple collection class.