Dapper and DAL Where must i place my validation - data-access-layer

I am started with my first Dapper Dal project.
I have three projects:
- Website (MVC)
- DataLayer (Dapper)
- Model (Poco Classes)
I want to add validation to my model but i also want to use clean poco classes for my datalayer. My datalayer use dapper to map my poco classes to the database.
I have searched the internet but i can't find a good answer.
My question is:
Where do i add my validation?
- In a seppetated project with classes that extend my poco classes or is there a different way?

If you want a clean separation between your DAL classes and your MVC classes, then you can do just that by, for instance, using ViewModels in your MVC-project. The ViewModel would have the properties and validations that works best with what you are presenting in the browser. Your controller would be responsible for mapping the data between the DAL classes and the ViewModels. Automapper is a very good tool for just that.
It would look a bit like the following:
DAL:
public class MyDapperClass
{
public int Id { get; set; }
public string SomeProperty { get; set; }
}
ViewModel:
public class MyViewModelClass
{
public int Id { get; set; }
[StringLength(50),Required]
public string SomeProperty { get; set; }
}
Controller:
// using AutoMapper;
public class MyController : Controller
{
public MyController()
{
// Set up AutoMapper to be able to map your class
Mapper.CreateMap<MyDapperClass, MyViewModelClass>();
}
public ActionResult MyAction()
{
var dalObject = DAL.GetObject();
var viewModel = Mapper.Map<MyViewModelClass>(dalObject);
return View(viewModel);
}
}

Related

ASP.NET MVC 4 ApiController doesn't serialize all properties

I'm testing the new ApiController in asp.net mvc 4 beta but when I try to return an class that looks like the following only a few properties gets serialized?
public class PageModel : IPageModel {
public string Id { get; set; }
public virtual IPageMetadata Metadata { get; private set; }
public PageModel() {
Metadata = new PageMetadata();
}
}
this is the code in my api controller
// GET /api/pages/5
public PageModel Get(string id) {
return new PageModel { Id = "pages/1", Metadata = {Name = "Foo"} };
}
and this is the result
{
Id: "pages/1",
Parent: null
}
Is it possible to get the complete object and not only a few things?
Readonly properties are not serialized. Make the setter of the Metadata property public if you want it to be serialized. I think that this behavior is normal for input parameters but not for output which is your case. IMHO it's a bug that could be workarounded by using a JSON serializer which supports this but maybe they will fix it before the final release and allow readonly properties to be serialized for output parameters.
Actually it's not a big pain, because you should be using view models anyway, so simply map your domain model to a view model and have your method return this view model which will contain only the properties that you need to actually expose to the client. This view model will contain properties with public getters and setters.

Class Naming Conventions with Layered Architecture and Entity Framework

I'm designing a layered architecture (Service/Business Logic Layer, Data Access Layer) and am struggling with the intersection of a few problems.
Entity Framework 4.1 does not support interfaces directly
My Interfaces contain collections of other interfaces with read/write properties
This means using an implementing class won't work either, since it would still refers to another interface type
Example (please excuse the poorly written code, this is ad-hoc from my brain):
Data Access Layer
public interface IEmployer
{
string Name { get; set; }
ICollection<IEmployee> Employees { get; set; }
}
public interface IEmployee
{
string Name { get; set; }
}
public class Employer : IEmployer
{
public string Name { get; set; }
public ICollection<IEmployee> Employees { get; set; }
}
public class Employee : IEmployee
{
public string Name { get; set; }
}
public class DataManager
{
public IEmployer GetEmployer(string name) { ... }
public IEmployee CreateEmployeeObject(string name) { ... }
public void Save(IEmployer employer) { ... }
public void Save(IEmployee employee) { ... }
}
Service Layer
[DataContract]
public class Employee
{
[DataMember]
public string Name { get; set; }
}
public class HireService
{
public void HireNewEmployee(Employee newEmployee, string employerName)
{
DataManager dm = new DataManager();
IEmployer employer = dm.GetEmployer(employerName);
IEmployee employee = dm.CreateEmployeeObject(newEmployee.Name);
dm.Save(employee);
employer.Employees.Add(employee);
dm.Save(employer);
}
}
Without EF, the above works fine. The IEmployee type is used in the service layer, and does not conflict with the Employee data contract type. However, EF cannot use an interface, so I would be required to use class instead of an interface.
I see a few options:
Change IEmployer/IEmployee to classes, leaving the same names
Change IEmployer/IEmployee to classes, rename to EmployerDAL/EmployeeDAL
Change IEmployer/IEmployee to classes, rename to Employer/Employee, sprinkle using EmployerDL = DataLayer.Employer at the beginning of any service classes using it
What naming convention should I follow for class names which are defined in both the business and data layer?
Similar question to this: What's the naming convention for classes in the DataAccess Project? except that EF causes a problem with interfaces.
Actually the class defined in your DAL should be the one used in your business layer - those are your real domain objects. Classes exposed from your business layer are just data transfer objects so if you want to build any convention you should imho rename your data contracts.
Anyway the naming convention is something really subjective. Choose the way which best fits your needs and be consistent in that naming.

If WCF is in a MVC application, should it use the controller to access the database to keep 'DRY'

I have an MVC application that accesses SQL and Windows Azure. The logical flow looks like this:
Person <--> View <--> Controller.ConvertPersonHere(x) <--> StorageContext.DoDataAction <--> AzurePersonTableEntity
ConvertPersonHere is the answer to this Stack Overflow question and it converts the Model entity to the Storage entity
public class Person
{
public string Name {get;set;}
public int ID {get;set;}
}
public class PersonEntity : TableServiceEntity
{
public string Name {get;set;}
public int ID {get;set;}
// Code to set PartitionKey
// Code to set RowKey
}
Now that I'm adding WCF to the mix, how should I go about accessing data functions? Assume I have currently have a method to .Save(Person) in the controller and want to Save(Person) from my WCF call.
Do I need to abstract out the data actions in the controller?
I would refactor the code like this - move the functionality to convert from Person to PersonEntity and vice versa to a separate mapper, move saving functionality to separate repository as well, and move controller's code for invoking mapper and repository to separate service too.
So methods in your controller will look similar to:
public ActionResult SomeMethod(Person person)
{
if (ModelState.IsValid)
{
_personService.Save(person)
return View("Success");
}
return View();
}
And in your WCF service you'll be able to reuse the code. In order to validate the classes in WCF using DataAnnotations attributes, you can use the approach similar to the following - http://blog.jorgef.net/2011/01/odata-dataannotations.html
From this example, if your Mvc project was gone and replaced by a Wpf project, your other functionality is still available. If you have both projects they can reference core functionality. Have the implementation which has no relation to UI (MVC or WPF) in other projects. This way those UI projects can reference this functionality.
public interface IConverter<TDataModel, TModel> { TModel MapToDomain(TDataModel source);}
public interface IPersonConverter : IConverter<PersonEntity, Person> { }
public interface IPersonRepository { Person GetById(int id); }
public class PersonConverter : IPersonConverter
{
public Person MapToDomain(PersonEntity source)
{
return new Person { ID = source.ID, Name = source.Name };
//or use an AutoMapper implementation
}
}
public class PersonRepository : IPersonRepository
{
private readonly IPersonConverter _personConverter;
public PersonRepository(IPersonConverter personConverter)
{
_personConverter = personConverter;
}
public Person GetById(int id)
{
PersonEntity personEntity = new PersonEntity(); //get from storage
return _personConverter.MapToDomain(personEntity);
}
}
public class MvcController
{
private readonly IPersonRepository _personRepository;
public MvcController(PersonRepository personRepository)
{
_personRepository = personRepository;
}
public ActionResult SomeMethod(int id)
{
Person person = _personRepository.GetById(id);
//make your view model based on the person domain model
//with another convert / map, to fit view as personForm
//(if this is overkill you can use person).
return View(personForm);
}
}
Mvc or Wpf project
PersonForm (ui model)
Controller or Wpf Class
Person -> PersonForm converter
List item
Core project
Person
IPersonRepository
Infrastructure project
Person Repository
Person Entity
Azure Person Table Entity
Storage Context
I know it's a tangent, but if you're mixing WCF and ASP.NET MVC, you should at least be aware of OpenRasta. A good start is this Herding Code podcast with the main contributor.
(No, this is not even intended to answer your actual question!)

Bundling a list of entities into a component

With FluentNHibernate I have mapped a UserPreference entity which references the GeneralPreference, GeneralPreferenceOption, and Profile entities:
public class UserPreference
{
public virtual long Id { get; set; }
public virtual Profile Profile { get; set; }
public virtual GeneralPreference Preference { get; set; }
public virtual GeneralPreferenceOption Value { get; set; }
}
It's easy enough to map a list of UserPreference on my Profile entity, but what I actually would like to do is wrap this list inside another class so that I can simplify operations concerning a user's given preferences:
public class Preferences
{
public IList<UserPreferences> UserPreferences{get;set;}
public Language Language {
{
//look up the language preference here
}
}
This kind of feels like a Component, but Components were not created for this type of scenario. Does anyone have any pointers on how I might map this?
I figured out a way to do this by mapping a private property on my Profile Entity. Using the techniques from the Fluent NHibernate wiki on mapping private properties (http://wiki.fluentnhibernate.org/Fluent_mapping_private_properties) I map a collection of UserPreference on my Profile Entity. Then I create another class PropertyHandler which takes an IEnumerable as a constructor parameter and make an instance of this a public property on Profile as well:
public class Profile
{
private PreferenceHandler _preferenceHandler;
get { return _preferenceHandler ?? (_preferenceHandler = new PreferenceHandler(UserPreferences)); }
private IEnumerable<UserPreference> UserPreferences { get; set; }
public static class Expressions
{
public static readonly Expression<Func<Profile, IEnumerable<UserPreference>>> UserPreferences = x => x.UserPreferences;
}
}
Notice the nested static class. It's used to enable mapping of a private property with FluentNHibernate.
The mapping class looks something like this:
public class ProfileMappings : ClassMap<Profile>
{
public ProfileMappings()
{
//... other mappings
HasMany(Profile.Expressions.UserPreferences);
}
}
I can now use the PreferenceHandler class to create helper methods over my collection of UserPreference.
An alternative is to build extension methods for IEnumberable. This works, but I decided not to do this because
1) I'm not really extending the IEnumerable functionality and
2) my helper methods disappear inamongst all the other IEnumerable extension methods making the whole thing a bit cluttered.

NHibernate, AutoMapper and ASP.NET MVC

I'm wondering about a "best practice" using NHibernate, AutoMapper and ASP.NET MVC. Currently, i'm using :
class Entity
{
public int Id { get; set; }
public string Label { get; set; }
}
class Model
{
public int Id { get; set; }
public string Label { get; set; }
}
Entity and model are mapped like this :
Mapper.CreateMap<Entity,Model>();
Mapper.CreateMap<Model,Entity>()
.ConstructUsing( m => m.Id == 0 ? new Entity() : Repository.Get( m.Id ) );
And in the controller :
public ActionResult Update( Model mdl )
{
// IMappingEngine is injected into the controller
var entity = this.mappingEngine.Map<Model,Entity>( mdl );
Repository.Save( entity );
return View(mdl);
}
Is this correct, or can it be improved ?
that's how I was doing in a project:
public interface IBuilder<TEntity, TInput>
{
TInput BuildInput(TEntity entity);
TEntity BuildEntity(TInput input);
TInput RebuildInput(TInput input);
}
implement this interface for each entity or/and for some group of entities you could do a generic one and use it in each controller; use IoC;
you put your mapping code in the first 2 methods (doesn't matter the mapping technology, you could even do it by hand)
and the RebuildInput is for when you get the ModelState.IsValid == false, just call BuildEntity and BuildInput again.
and the usage in the controller:
public ActionResult Create()
{
return View(builder.BuildInput(new TEntity()));
}
[HttpPost]
public ActionResult Create(TInput o)
{
if (!ModelState.IsValid)
return View(builder.RebuildInput(o));
repo.Insert(builder.BuilEntity(o));
return RedirectToAction("index");
}
I actually do sometimes generic controller that is used for more entities
like here: asp.net mvc generic controller
EDIT:
you can see this technique in an asp.net mvc sample application here:
http://prodinner.codeplex.com
I would inject the IMappingEngine into the controller, instead of the using the static Mapper class. You then get all the benefits of being able to mock this in your tests.
Take a look at this link by AutoMapper's creator,
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/11/automapper-and-ioc.aspx