Business Logic + ASP.NET MVC - asp.net-mvc

I've an MVC application, which is divided into 3 layers:
- Presentation - ASp.NET MVC
- Busines Logic - Here we have entities and object services. We alo have mappers between DAL objects and BL objects
- Data Access Layer - we use EF to query the database.
Now, we've created a factory for object services, and the factory is injected into presentation later using Unity. Each time I want to do some logic, I call an appropriate service which uses DAL repositories to do some stuff.
Now, silly question, let suppose that I want to check if I can add a user with a provided nickname. The nickname is unique in the database, so before I add the user, I check if a user with provided nickname exists. So, it's a simple query that returns true/false. Becuase I don't have any connections between presentation layer and business layer, I check it in the service. But the code of the service method simply looks like:
var exists = repository.NicknameExists(nickname);
return exists;
The code above is strange, because it does nothing, just calls a method and returns its value. On the other hand, I've Separation of Concerns, so my solution is well organised. Can someone give me some suggestions, how should I solve problems like that?

I don't see any problem here. It's perfect method for me:
public bool IsUserExists(string nickname)
{
return repository.NicknameExists(nickname);
}
I would recomend to you to read this blog post about valid reasons to create a routine or the chapter 7.1 of the Code Complete 2ed

Related

MVC Pattern - Is this the correct approach for Repository / Unit of Work

I have been doodling and reading and just want to ensure the approach I am taking is correct. I am using MVC5 with EF, implementing the Repository and Unit of Work patterns.
EntityModel -> <- SomeRepository
SomeRepository -> <- SomeController
SomeController -> SomeViewModel
SomeViewModel -> SomeView
SomeView -> SomeController
SomeController -> <- SomeRepository
etc ..
In the controller I am planning on using something like AutoMapper to map the ViewModel to the EntityModel (and vice versa) which can then be passed to my repository / view.
Also, with this approach I am not 100% sure where my business logic should go. For instance, if I have an EntityModel for products and I wanted to add a GetAssociatedProducts method, would this go against the EntityModel or should another tier be introduced so the EntityModel is just a straightforward mapping class to the DB?
Should the ViewModel contain any logic at all? i.e Creating a Dictionary to populate a dropdown on the view based on values from the EntityModel?
I am trying to avoid the issues associated with just starting to code without thinking to much into how which is the reason for this question.
Note: I am also implementing IoC with Autofac but I don't think that's relevant at this point (saying just in case it is).
Well, you're already thinking too much.
First, since you specifically mention MVC, let me just say that the vast majority of what you're talking about is not MVC. MVC stands for Model-View-Controller. In the strictest sense, your model is the haven of all business logic for your application. The controller merely connects your model to your view, and your view merely presents the data to the client in a readable format.
Despite its name, ASP.NET MVC does not truly follow the MVC pattern. You could call it Microsoft's take on MVC. The controller and views track pretty closely (though there is some very noticeable and repugnant bleed-over, such as ViewBag). But, the "model" bit is very unclearly defined. Since, Entity Framework is integrated, most latch on to the entity and call this the model, but entities are really bad models. They're just (or at least should just be) a programmatic representation of a database table: a way for Entity Framework to take data from your table rows and put it into some structure that lets you get at it easily.
If you look at other MVC implementations such as Ruby on Rails or Django, their "model" is more of a database-backed factory. Instead of the class simply holding data returned from the database, it is itself the gateway to the database for that type. It can create itself, update itself, query itself and its colleagues, etc. This allows you to add much more robust business logic to the class than you can or should with an "entity" in C#. Because of that, the closest you can get a true MVC model is your domain or service layer, which isn't really factored in at all by default in ASP.NET MVC.
That said, though, if you're implementing a repository / unit of work pattern with Entity Framework, you're probably making a mistake. Entity Framework already does this so you don't have to. The DbContext is your Unit of Work and each DbSet is a repository. Any repository you create, dimes to dollars, will simply end up proxying your repository methods to methods on your DbSet, which is your first sign that something's not right. Now, that's not to say that a certain amount of abstraction isn't still a good idea, but go with something like a service pattern instead: something lightweight and flexible that will truly abstract logic instead of just creating a matryoshka doll of code that will only serve to make your application harder to maintain.
Finally, your view model (which is actually a rip from the MVVM pattern) should simply be whatever your view needs it to be. If your view needs a drop down list, then your view model should contain that. Whether your view model should generate it, is a slight different question that depends on the complexity of the data involved. I don't think your view model should know how to query a database, so if you need to pull the data from a database then you should let the controller handle that and just feed it to the view model. But, if it's something like a list of months, a enum structure, a numerically static list, etc., it might be appropriate for the view model to have the logic to construct that list.
UPDATE
No, they are actually implementing a repository. I'm not sure why in the world the introductory MVC articles on MSDN advocate this, but as one who fell into the same trap early on, I can say from personal experience, and many other long-time MVC developers will tell you the same, you don't want to actually follow this advice. Like I said, most of your repository methods end up just proxying to Entity Framework methods, and you end up having to add a ton of boilerplate code for each new entity. And, the further you go down the rabbit hole, the harder it is to recover, leading inevitably to some major refactoring once you finally grow tired of the repetitive code.
A service pattern is a lot simpler. There may still be some proxying for things like updates and deletes, where there's very little unique from one entity to another, but the real difference will be seen with selects. With a repository, you'd do something like the following in your controller:
repo.Posts.Where(m => m.BlogId = blog.Id && m.PublishDate <= DateTime.Now && m.Status == PostStatus.Published).OrderByDescending(o => o.PublishDate).Take(10).ToList();
While with a service you would do:
service.Posts.GetPublishedPostsForBlog(blog, limit: 10);
And all that logic about what is a "published" post, how blog is connected to post, etc., goes into your service method instead of your controller. The other big difference is that service methods should return fully-baked data, i.e. a list type rather than a queryable. The goal with a service is to return exactly what you need, while the goal with a repository is to provide an endpoint to query into.

ASP.NET MVC Business Logic in Domain Model vs Service Layer

I have been reading about where to put business logic in ASP.NET MVC Project for a while and I still can't get clear on some things.
1 - Domain models. What are these really? In my Model folder I have only a bunch of classes corresponding to my database. I am using EF code first. I assume these are my domain models.
2 - Service Layer. This answer suggests a service layer and I think this makes perfect sense. I had decided to go with this one. However, Martin Fowler's "Anemic Domain Models" article messed up my mind.
I am not really sure how can I add logic to my domain models.
I have gone through many business logic-related questions and each of them proposes either 1 or 2. What I don't understand is how I can implement the first one. Adding methods to entity classes (domain models for me) does not make sense at all. And why is the second approach considered bad?
First off, your Model folder in your Asp.Net MVC project should be used for ViewModels. These are the models that your Controllers send to your Views. They should be highly optimized for the View, meaning only the properties needed for the view, and nothing else.
What you are taking about, Domain Models, are the same as Business Models, and belong in your Business Layer. The Model folder in your Asp.Net MVC project are the models for your UI Layer.
The second approach, business logic in your service (really business) layer is not considered bad. It's a very nice buffer between your Data Layer and your UI Layer (3-tier architecture). Your data layer handles getting data, from either web services or a database, and your business/service layer handles translating that data into business/domain models. It also holds any business logic, like calculations, etc.
These business/domain models are usually POCOs, but they don't have to be. This is how I sometimes set up my business models:
public class BusinessObject
{
private DataObject _dataObject;
public BusinessObject(DataObject dataObject)
{
_dataObject = dataObject;
}
public int BusinessId
{
get {return _dataObject.Id;}
set {_dataObject.Id = value;}
}
public string Name
{
get {return _dataObject.Description;}
set {_dataObject.Description = value;}
}
}
I prefer to NOT have business logic in domain models. I keep my domain models usually as POCO's to represent my DB tables/schema.
Keeping the business logic away from the domain models will allow me to reuse my domain model with another project as well.
You may consider a middle layer between your controllers and your data access layer/ Repositary layer to handle this. I would call this as a service layer.
I know this has already been answered, but I categorize models into 3 groups
ViewModels - These are light weight (often poco) classes that model the data needed by a page on your site. These classes handle the mundane boilerplate of what gets shown to the user, and changes when the data that you want to display changes.
DomainModels - These are normally heavy weight business logic classes. They normally model the core business rules for what you're doing. These classes are often highly cohesive and are where the majority of the work that makes your site special happens. I said these models are normally heavyweight but in reality if all your project does is take that data from the user and stick it in the database, this class is going to be a little data mapping class. Many times you'll see these classes being composed of persistence models and returning view models.
PersistenceModels - These are models of your persistence mechanism. For most of us this means modeling a database table, but could also be a complex nosql document or json (or whatever) data that's returned from an api request. Their responsibility is to handle the mundane boiler plate of what shape your external data takes.
Keep in mind also that you don't always need to have all three of these types of models present in your project. Sometimes your view model will be line for line what you're persistence model is. In that case you'd be wasting your clients money to write the whole thing twice and add a domain model to map one to the other. You're the developer and it's your job to know when to build a air-craft carrier to go to the store for groceries.
Domain models should be able to perform their work on their own and expose properties and methods that represent their state and functions. They act as roots (aggregate roots) to a hierarchy of information that is required by models to function. They remain hidden only available to services.
Services expose business/domain functionality to the outside world (web services, UI etc) as a set of APIs following the message pattern (requests/responses), by retrieving models from the repositories that encapsulate the data access layer, then calling methods/business functions on the models and finally saving them back to the repositories.
Some times it feels that services repeat methods of business objects, but in time and real practice that is not what really happens.
In a real domain driven design you need at least 3 sets of objects. Business Objects, Repositories of Business Objects and Services.
Think as if your requirement is always that each type of component is written by different teams. One team requires an exposed service without knowing the details and without the other having to write the logic on the service it self. The service could then be consumed by anyone that requires it without having to dig into the core model itself.
Application flow control logic belongs in a controller.
Data access logic belongs in a repository.
Validation logic belongs 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 validation logic.
For example, a product service layer has a CreateProduct() method.
The CreateProduct() method calls the ValidateProduct() method to validate a new product before passing the product to the product repository.
Source:
http://www.asp.net/mvc/overview/older-versions-1/models-data/validating-with-a-service-layer-cs

ASP.NET MVC - M V C Responsibilities

I am probably over analyzing here, but with all the reading I have done on MVC, there seem to be so many opinions on how to do things.
Is there a "Best Practices" site or document out there that defines the responsibility of each piece of MVC?
The few questions I have, keep in mind I am using the EF/Repository&UnitOfWork/Service pattern are:
1) How to get the validation results (error messages, etc) of Domain Objects and Business Rules from the Service Layer to the View Models?
2) I am using Domain Objects and a Service Layer that does all the Business Logic, then I send the Domain Objects to the controllers and let them (via AutoMapper) convert them to View Models for the views. What other types of things are the responsibility of the controller? Is the following code OK? Is this too much logic in the controller?:
public ActionResult SomeAction()
{
var model = Mapper.Map<DomainObject, ViewModel>(service.QueryReposForData());
model.SomeCollectionForSelectList = Mapper.Map<IEnumerable<DomainObject>, IEnumerable<ViewModel>>(service.QueryReposForSelectListData());
return View(model);
}
I don't think that the only thing in a controller is one line that returns a view with an object graph mapped to view models?
3) I think it is OK to have properties on the ViewModels that can indicate to a view if something can be hidden for example and then perform that logic in the view? Example:
#if(Model.DisplaySomething)
{
<div>Something to show</div>
}
else
{
<div>Something else to show</div>
}
4) I was thinking of having my services return some sort of TransactionResult object back to the controllers on writes to make it the responsibility of the service to handle the transaction. So I would have an aggregate service that would start a transaction (UnitOfWork) do what ever it needed to do and then return this TransactionResult that could have error messages? I don't think I should make the controller responsible for managing the transaction, but rather have it just pass in a view model mapped to a domain object to the service and let it act on it?
5) Also, how much of ActionFilter's do you want to use? I know it is a huge extensibility point, but I often find myself trying to stuff all of the model creation into a filter.
Just opinions here based on how we work.
We keep our Controllers so skinny they are anorexic, in almost every case.
As for ViewModels, we follow the pattern of having a ViewModel for every view. The Controller loads it up with anything it needs, and kicks it off. From there, the ViewModel drives everything. In our world, the ViewModel is tied directly to the view and contains no code that would/could be used in other parts of the application. It interacts with any part of the larger 'Model' (service layer, etc) that it needs to and packages stuff up for the View to consume.
For your #3 example, I'd say absolutely yes - it's the way we use our ViewModels.
Again, none of this is gospel - just my take on how we handle it.
Excellent questions!
1) How to get the validation results (error messages, etc) of Domain
Objects and Business Rules from the Service Layer to the View Models?
I use EntityFramework in the back-end and implement IValidatableObject both on my models and my entities. On models, I perform cross-field validation, while on entities, I perform cross-entity validations.
2) I am using Domain Objects and a Service Layer that does all the
Business Logic, then I send the Domain Objects to the controllers and
let them (via AutoMapper) convert them to View Models for the views.
What other types of things are the responsibility of the controller?
Is the following code OK? Is this too much logic in the controller?:
This code is perfect. Controllers gather data, transform data into models and feeds them into a view.
3) I think it is OK to have properties on the ViewModels that can
indicate to a view if something can be hidden for example and then
perform that logic in the view? Example:
Yes, this is exactly what a ViewModel is meant for. To capture all data AND logic required for your view to render.
4) I was thinking of having my services return some sort of
TransactionResult object back to the controllers on writes to make it
the responsibility of the service to handle the transaction. So I
would have an aggregate service that would start a transaction
(UnitOfWork) do what ever it needed to do and then return this
TransactionResult that could have error messages? I don't think I
should make the controller responsible for managing the transaction,
but rather have it just pass in a view model mapped to a domain object
to the service and let it act on it?
I struggled with this a bit in my projects. In the end, I moved the SaveChanges method of EntityFramework to the front-end. This allows me to build a transaction in the front-end and then commit it once. Every method in my ApiController which performs an update, create or delete will also do a SaveChanges.
I use ApiControllers as a layer of abstraction between my back-end and actual Controller classes. To elaborate, my application both uses normal Controllers (HTML) and ApiControllers (REST aka Web API). Both types of controllers share a common interface for retrieving data.
Example: http://pastebin.com/uL1NGGqH
The UnitOfWork still resides in my back-end behind a facade. I just expose the SaveChanges to the front-end. Side-effects such as ValidationExceptions are either handled by ASP.NET MVC automagically or captured in custom ActionFilters.
5) Also, how much of ActionFilter's do you want to use? I know it is a
huge extensibility point, but I often find myself trying to stuff all
of the model creation into a filter.
I only used a handful of ActionFilters in the large MVC project I am currently working on. These ActionFilters are mostly used to enforce security and to translate Exceptions (such as ValidationExceptions) to JSON-format so my client-side validation framework can handle it.
Off-topic: You can never over analyze. Asking yourself these fundamental questions of MVC makes you better grasp the concepts of MVC and makes you a better developer in general. Just make sure you don't do it too much in the boss' time ;)
Same here:
base controllers with common actionfilters
Validation is done using DataAnnotation and model validation within the controller.
tiny controllers with injected wrapped context or specific service layer
Automapper mapping ViewModels/EF Pocos.
I don't really bother about implementing UnitOfWork or explicitly using transactions since EF4 automatically creates (if it does not exist) a new transaction for all the changes done within a SaveChanges (http://msdn.microsoft.com/en-us/library/bb896325.aspx. I just have a generic interface exposing the DbSets of the Context as IQuerable and the Add/Delete/Find methods.
But as said it's all personal.

Advice on POCO Validation with ASP.NET MVC/Entity Framework

Here's the scenario:
ASP.NET MVC2 Web Application
Entity Framework 4 (Pure POCO's, Custom Data Context)
Repository Pattern
Unit of Work Pattern
Dependency Injection
Service Layer mediating Controller -> Repository
So basically, all the cool stuff. :)
Flow of events for a basic UI operation ("Adding a Post"):
Controller calls Add(Post) method on service layer
Service layer calls Add(T) on repository
Repository calls AddObject(T) on custom data context
Controller calls Commit() on Unit of Work
Now, i'm trying to work out where i can put my validation.
At this stage, i need two types of validation:
Simple, independant POCO validation such as "post must have a title". This seems a natural fit for Data Annotations on the POCO's.
Complex business validation, such as "cannot add a comment to a locked post". This can't be done by Data Annotations.
Now, i have been reading "Programming Entity Framework, Second Edition" by Julie Lerman (which is excellent BTW), and have been looking into hooking into the SavingChanges event in order to perform "last-minute" validation. This would be a nice way to ensure validation always happens whenever i do "something" (add, modify, delete), but it's also a little late IMO (as the items are already in the state manager) - so what can i do if validation fails, remove them?
I could of course make my POCO's implement an interface (say "IValidatable"), and call a method on this interface during this event.
But this seems "too late" for business validation - is this the consensus?
I'm basically looking for guidance here, i'm trying to design a re-usable, intelligent validation scheme for complex business logic, given my above architecture.
Another curve-ball for you - as you know, POCO's with EF mean the POCO's have all the properties on the DB - so i might have a "PostID" property, with get/set accessors (as EF needs to get/set these properties).
But the problem is, "PostID" is an identity column, so how do i protect the field from being explicity set? E.g if i (for some reason) do the following:
var post = service.FindSingle(10);
post.PostId = 10;
unitOfWork.Commit();
This will throw a SqlException. How can i prevent this? I can't "hide" the property (make it private, or even internal) as the POCO's are in a seperate assembly to the Repository.
A note on validation - i'm planning to create custom exceptions (deriving from Exception). So when validation fails, i need to throw these exceptions.
That way, i can code something like this on my controller:
[HttpPost]
public ActionResult AddPost(Post post)
{
try
{
IUnitOfWork uow = new UnitOfWork();
postService.Add(post);
uow.Commit();
}
catch(InvalidPostOperation ipo)
{
// add error to viewmodel
}
}
Will i have to manually do validation on the service layer everytime i do an Add? Then how can i handle Save? (as this is on the Unit of Work, not the service layer).
So to prevent this from being a "all over the place" question, here are my questions:
Simple POCO validation - should this be done with Data Annotations? Pros/cons/gotchas?
Under what circumstances (if any) should we be hooking into the SavingChanges event of the EF Data Context in order to provide validation?
Where should i be performing complex business validation? In the service explicity, or a method on the POCO's (which i can call from service). How can i create an intelligent/reusable scheme?
How can we "hide" auto-generated properties of POCO's from being tampering with?
Any thoughts would be most appreciated.
Apologize if this post is "too long", but it's an important issue and one that can be solved in many ways, so i wanted to provide all the info in order for the best possible answer.
Thanks.
EDIT
The below answer is helpful, but i'm still (ideally) looking for more thoughts. Anyone else?
Well like you said, DataAnnotations is not appropriate for all situations. Cons are mainly complex validation (multiple property and multiple property different object) in my experience.
If i were you, i would leave business/domain validation out of the Data Layer (EF) as much as possible. If there is a Data Layer validation scenario, then fine (eg. validating complex parent/child relationships - this is purely DB stuff).
Yes, the complex business validation should be in the Service Layer or in the Model Objects (attached, via partial classes or some inheritance approach: interfaces/derived classes). There's debate about this between ActiveRecord people, Repository Pattern people and DDD people, but go with what works for you, is simple and will enable rapid deployment and low cost application maintenance. This is a simple example of how you might attach more complex validation to domain objects yet is still compatible with the DataAnnotations interface and thus is 'MVC friendly'.
Good question. -one i have not found a solution i'm 100% happy with yet. I have played with the idea of private setters and it's not great. Have a quick read of this summarized Evans DDD book. It's great quick read and it might provide some insight about the purpose and difference between Model Objects and Value Objects. This is where i think object design will mitigate the problems your having with the property "tampering" (as you call it) but without fixing the property visibility. Ie, another solution might lie elsewhere. Hope this helps.
Hey, probably a bit late but here goes anyway...
It all depends on your architecture, i.e. Is there a logical seperation, in your application: UI, Service Layer, Repository Layer. If you are hooking onto the Save event, how exactly will that be done? From what I observed you would be calling the repository Layer for Persistance only right? However you are hooking onto the save event, giving control back to the Service Layer/ Business Layer whatever then forcing the save through right?
I personally feel the Service layer/ Business Layer should take care of it in completion then say, hey mr repo layer -> save this object.
With regards to validation, Data Annotations should be used with the UI, so simple valiation like [Required] etc, this will be helpful with the Client Side validation but complex business logic or complex validation should be hooked into the service layer/ business layer, that way it is reusable across all entities/ objects/ POCOS etc.
With regards to preventing certain private fields not being tampered with... only allow your service layer/ business layer to actually set the object that will be persisted (yes i mean :) ...) hand coding it, I felt this was the safest option for me anyway, as I will simple do:
var updatedpost = _repo.GetPost(post.postid);
updatedpost.comment = post.comment;
updatedpost.timestamp = datetime.now;
Kind of wasteful but that way your buseinss layer takes control, however this is just my experience I may be wrong, I have read a lot into model binding, validaiton and other stuff however there seemed to be cases where things never work as expected e.g. [Required] attribute (see Brad WIlson's) post.

Is my ASP.NET MVC application structured properly?

I've been going through the tutorials (specifically ones using Linq-To-Entities) and I understand the basic concepts, however some things are giving me issues.
The tutorials usually involve only simple models and forms that only utilize basic create, update and delete statements. Mine are a little more complicated, and I'm not sure I'm going about this the right way because when it comes time to handle the relationships of a half dozen database objects, the tutorials stop helping.
For the post method, the usual way of performing CRUD operations
entities.AddToTableSet(myClass);
entities.SaveChanges();
Won't do what I want, because a fully implemented class isn't getting posted to the controller method. I may post individual fields, form collections, or multiple DTO objects and then call a method on a service or repository to take the information I receive from a form post, along with information that it needs to query for or create itself, and then from all of those things, create my database object that I can save.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(int id, [Bind(Exclude = "Id")] ClassA classA,
[Bind(Exclude = "Id")]ClassB classB)
{
// Validation occurs here
if(!ModelState.IsValid)
return View();
try
{
_someRepositoryOrService.Add(id, classA, classB);
return RedirectToAction("Index", new { id = id });
}
catch(Exception ex)
{
// Logging and exception handling occurs here
}
}
public void Add(int id, ClassA classA, ClassB classB)
{
EntityA eA = new EntityA
{
// Set a bunch of properties using the two classes and
// whatever queries are needed
};
EntityB eB = new EntityB
{
// Set a bunch of properties using the two classes and
// whatever queries are needed
};
_entity.AddToEntityASet(eA);
_entity.AddToEntityBSet(eB);
_entity.SaveChanges();
}
Am I handling this correctly or am I bastardizing the framework? I never actually use an entity object directly, whenever I query for one I put the information I need in a DTO and base my Views off of that. Same goes with the creation. Is this allowed, or is my avoidance of using entities directly going against the purpose of using the framework?
Edit: I'm also worried about this approach because it requires empty constructors to properly do the LINQ queries because of this error message:
Only parameterless constructors and
initializers are supported in LINQ to
Entities.
This isn't a big deal since I rarely need logic int the constructors, but is this an issue to have no constructors and only public properties?
_someRepositoryOrService.Add(id, classA, classB);
I would say you couple your repositories with presentation layer. This shouldn't be. Your repositories should only work with entities. Next, notice how your Add method
public void Add(int id, ClassA classA, ClassB classB)
breaks Separation of Concerns (SoC). It performs two tasks:
map view data into entities
save to repository
Obviously the first step should be done in presentation layer. Consider using model binders for this. It can also help you to solve the constructors problem, since your model binders can be made aware of the construction requirements.
Check also this excellent post by Jimmy Bogard (co-author of ASP.NET MVC In Action) about ViewModels. This might help you to automate mapping. It also suggest a reversed technique - make your controllers work with entities, not ViewModels! Custom action filters and model binders are really the key to eliminate routine that that don't really belong to controllers but rather an infrastructure detail between view and controller. For example, here's how I automate entities retrival. Here's how I see what controllers should do.
The goal here is to make controllers contentrate on managing business logic, putting aside all the technical details that do not belong to your business. It's techical constraints that you talk about in this question, and you let them leak into your code. But you can use MVC tools to move the to them infrastructure level.
UPDATE: No, repositories shouldn't handle form data, that's what I mean by "coupling with presentation". Yes, repositories are in the controller, but they don't work with form data. You can (not that you should) make form work with "repositories data" - i.e. entities - and that's what most examples do, e.g. NerdDinner - but not the other way. This is because of the general rule of thumb - higher layers can be coupled with lower ones (presentation coupled with repositories and entities), but never low level should be coupled to higher ones (entities depend on repositories, repositories depend on form model, etc).
The first step should be done in the repository, that's right - except that mapping from ClassX to EntityX does not belong to that step. It's mapping concern - an infrastructure. See for example this question about mapping, but generally if you have two layers (UI and repositories) they shouldn't care about mapping - a mapper service/helper should. Beside Jimmy's blog, you can also read ASP.NET MVC In Action or simply look at their CodeCampServer for how they do mapping with IEntityMapper interfaces passed to controller constructors (note that this is more manual and less-work approach that Jimmy Bogard's AutoMapper).
One more thing. Read about Domain Driven Design, look for articles, learn from them, but you don't have to follow everything. These are guidelines, not strict solutions. See if your project can handle that, see if you can handle that, and so on. Try to apply this techniques since they're generally the excellent and approved ways of doing development, but don't take them blindly - it's better to learn along the way than to apply something you don't understand.
I would say using DTOs and wrapping the Entity Framework with your own data access methods and business layer is a great way to go. You may end up writing a lot of code, but it's a better architecture than pretending the Entity Framework generated code is your business layer.
These issues aren't really necessarily tied to ASP.NET MVC in any way. ASP.NET MVC gives basically no guidance on how to do your model / data access and most of the samples and tutorials for ASP.NET MVC are not production worthy model implementations, but really just minimal samples.
It seems like you are on the right track, keep going.
In the end, you are using Entity Framework mostly as a code generator that isn't generating very useful code and so you may want to look into other code generators or tools or frameworks that more closely match your requirements.

Resources