We posted a complete Contact Manager sample ASP.NET MVC Application at the www.ASP.net/mvc website. The source code is available in both C# and VB.NET.
The application is intentionally simple. The goal was to provide members of the ASP.NET community with an application that they could use to quickly learn how to build new applications with ASP.NET MVC.
The Contact Manager application is an address book application. The application enables you to list, create, edit, and delete contacts.
I built the application over multiple iterations. With each iteration, I gradually improved the application. The goal of this multiple iteration approach was to enable you to understand the reason for each change.
Iteration #1 – Create the application. In the first iteration, we create the Contact Manager in the simplest way possible. We add support for basic database operations: Create, Read, Update, and Delete (CRUD).
Iteration #2 – Make the application look nice. In this iteration, we improve the appearance of the application by modifying the default ASP.NET MVC view master page and cascading style sheet.
Iteration #3 – Add form validation. In the third iteration, we add basic form validation. We prevent people from submitting a form without completing required form fields. We also validate email addresses and phone numbers.
Iteration #4 – Make the application loosely coupled. In this third iteration, we take advantage of several software design patterns to make it easier to maintain and modify the Contact Manager application. For example, we refactor our application to use the Repository pattern and the Dependency Injection pattern.
Iteration #5 – Create unit tests. In the fifth iteration, we make our application easier to maintain and modify by adding unit tests. We mock our data model classes and build unit tests for our controllers and validation logic.
Iteration #6 – Use test-driven development. In this sixth iteration, we add new functionality to our application by writing unit tests first and writing code against the unit tests. In this iteration, we add contact groups.
Iteration #7 – Add Ajax functionality. In the seventh iteration, we improve the responsiveness and performance of our application by adding support for Ajax.
Each iteration has an associated tutorial. You also can download the Visual Studio Solution associated with each iteration. Here is a direct link to the Contact Manager tutorials:
I’ve just done the first iteration. In the views, there was code to display/edit the id field. This was not in your code. Are you running a newer version. I’m running ( I believe) RC update.
In the sample code (first iteration), the Create/Edit methods have general catch clauses, eating all exceptions. I don’t like this kind of code, especially as this is supposed to teach relatively inexperienced developers.
I am still trying to grasp this a bit but in Iteration #4 aren’t your interfaces dependent on the Entity Framework objects like Customer?
If I use a different ORM in the future wouldn’t my Customer objects be different and shouldn’t they then also implement say an ICustomer interface?
great example, thx Stephen
After Iteration 1, Listing 2, I get this error when trying to build:
The type or namespace name ‘ContactManagerDBEntities’ could not be found (are you missing a using directive or an assembly reference?)
Are you missing a step to add the reference?
P.S. Your blog’s timezone appears to be set to UTC +12. Is that by design? Perhaps you’re blogging from Tuvalu?
Re: 2 comments up. You meant Models.ContactManagerDBEntities in Listing 2, right?
I’m finding more small errors. Want them listed here, or should I contact you another way? I don’t want to flood your Comments system.
@mh415 — Thanks 🙂 I changed the timezone.
@mh415 – Feel free to post any problems that you discover here or email me by clicking the Contact Me link at the top of the page.
This is excellent example, especially iteration 7.
You could help a lot of us if you added an iteration 8 that included paging.
Some problems in C# version:
– Iteration #4, Listing 1:
public interface IContactRepository
{
should be
public interface IContactManagerRepository
{
– ContactManagerService.cs and ContactController have compile time error:
Error 1 Inconsistent accessibility: parameter type ‘ContactManager.Models.Validation.IValidationDictionary’ is less accessible than method ‘ContactManager.Models.ContactManagerService.ContactManagerService(ContactManager.Models.Validation.IValidationDictionary)’ E:My DocumentsVisual Studio 2008ProjectsContactManagerContactManagerModelsContactManagerService.cs 14 16 ContactManager
Also download is provided only in VB so I can’t download Iteration #4 code and continue tutorial.
Overall, good stuff. I only downloaded the code from the iteration 7 and it compiled and worked well. However, the AJAX browser history stuff you implemented does not appear to work in IE7. Works great in Firefox 3.x but I get no back/forward button love in IE7 when using the Ajax links. Is this an issue in the MSAjax js library?
I’m having a problem with your example if I want to obtain only a single column from the Group list.
Your code is like so:
public IEnumerable ListGroups()
{
return _entities.GroupSet.ToList();
}
This, of course returns everything in the Group. Let’s assume th Group table has many columns and only three are needed. What would the code above look like to do that?
It works all great if you allow to edit all fields of a contact. But if you don’t want to allow the user to change the Phone (So Phone is only displayed on the view and is not editable < %=Model.Phone %> instead of < %= Html.TextBox("Phone") %>) I get problems.
First.
In public ActionResult Edit(int groupId, Contact contactToEdit) contactToEdit.Phone will be null so in ValidateContact a NullReferenceException is raised.
Second.
If you don’t validate on Phone, ApplyPropertyChanges in EditContact() throws an exception and next a NullReferenceException is raised in the view on < %=Model.Phone %> because Model=null
So, my question is. What to do with a field that you only want to display on your view ?
@Max — That’s a good point. You should strive to program against abstractions (interfaces and abstract classes) as much as possible. When using Entity Framework, it is possible to generate abstract classes instead of concrete classes. However, I don’t cover this feature in the tutorial. This would be a good idea for a tip.
@Milan — Thanks for pointing out the missing downloads for iteration #4 — we are getting this fixed.
@Walter — You can’t use ApplyPropertyChanges()when you have read-only properties. In this situation, you must set each property by hand:
originalContact.FirstName = contactToEdit.FirstName;
originalContact.LastName = contactToEdit.LastName;
_entities.SaveChanges();
@JoeReynolds — Using LINQ to SQL, you can specify that you want to return only certain properties:
var results = from g in _entities.GroupSet select new {Id=g.Id, Name=g.Name}
In this case, even if the group table contained multiple columns, only the Id and Name columns would be returned.
Patterns
——–
When we use a service layer for business logic then why not use a generic repository (just 1) with IQueriable instead of IEnumerators
EF
—
with new sql server database desgin any advantage EF over Linq 2 SQL ?
toomanylayers.blogspot.com/…/…linq-to-sql.html
http://www.chadmoran.com/…/…v-linq-to-sql-take-4.html
The browser navigation stuff in itteration#7 does not seem to be working with IE7.
Have you tested it with IE7 or is it something in my configuration?
Thanks Stephen for your reply about read-only properties.
But it’s a solution for just a part of my problem. Perhaps I should have told more about it. I want Phone only to be read-only for specific users. But an administrator may change it. Then your solution won’t work because Phone will not be saved. So should I then have to make 2 different EditContact(), one with originalContact.Phone = contactToEdit. Phone; for the administrator. And one without for other users !?
It seems to me that that is not a nice solution. I think the problem is that if you only want to show Phone (so I use Model.Phone instead of Html.TextBox(“Phone”) in the view) you won’t get the value back in the controller-action (public ActionResult Edit(int groupId, Contact contactToEdit)). contactToEdit.Phone will be null. Is there a way to get values back from the view even if there read-only ? Then you can just use EditContact() as it was.
Even so, without all of the above, you’re solution solves the exception in ApplyPropertyChanges in EditContact(), But still, if you enter a wrong value in Email, a NullReferenceException is raised in the view on Model.Phone because Model=null .
One other thing about validation. If you have a datetime-property (RegistrationDate) and on the view you enter something completely wrong (say “%$##”) then contactToEdit. RegistrationDate will have an initial DateTime-value (1-1-0001 0:00:00). This can cause troubles in your own validation, so you should be aware of that.
I want to say thanks for your articles and examples. They are great to help me a in learning MVC!
Thx for you application.
I accounted some problems in practice.
I used ajax to render the partial view,but the whole page was represented by AJAX way in ‘divList’.the second time,i clicked the link in ‘divList’,it worked well.It surprised me for a long time.I don’t know what caused the problem.PLS help me.
great sample. thanks
Steve, this last iteration of tutorials is superb. I am completely sold on your upcoming book judging by your teaching skill.
I have an asp.net mvc project that was not created with a test project in the Visual Studio solution.
Can I add one after the fact? I think you mention in iteration #1 that it is better to create the test project at the very beginning.
Since that is too late for me now, can I add it after the fact?
I couldn’t get a Design Gallery template to work with your example, so I tried just a brand new (empty) project and the “Happy Forest” template: http://www.asp.net/mvc/gallery/View.aspx?itemid=28. Running the project results in a Parser Error: “Could not load type ‘DeleteMe.Views.Shared.Site’.” I’m new to ASP.NET, so maybe there’s an obvious fix, but shouldn’t this just work out of the box especially since “Happy Forest” is a template provided by MS?
@mh415 — Unfortunately, the MVC team keeps releasing new versions of ASP.NET MVC fast and furiously and there are enough changes to cause problems with the design templates that were submitted before the changes. After the final ASP.NET MVC release, I’ve scheduled a day of reviewing and updating all of the existing design templates to ensure compatibility. Thanks for your patience!
@DaveM — I had to check on the issue of using AJAX History with IE 7 with the AJAX team. To get IE 7.0 compatibility you need to include a hidden IFrame in your page named __historyFrame. I’ll update the Contact Manager sample application to include this fix. Thanks for bringing the problem to my attention!
I tried using your “Contact” page, but got this error:
“Your message could not be sent, most likely due to a problem with the mail server.”
Just a heads-up.
Thank you for your work on these tutorials. I’m a beginner with .net and they are really helping me to get my feet wet.
I have currently made it almost through iteration #6 and I have noticed that for iterations 4-6, I have had to download the code because of build errors in the examples from the tutorial page. This has been frustrating since I’m not experienced at debugging C#. I really wanted to edit the code as I went, but found that in a few cases it was impossible to continue without copying in the downloaded code. Now I’m in a complete mess, so I will start 7 with the downloaded code from 6 and cross my fingers.
I am having the same problem as in a previous post.
The type or namespace name ‘ContactManagerDBEntities’ could not be found (are you missing a using directive or an assembly reference?)
Is there something I am missing? I have tried to do iteration#1 twice and get the same error.
Figured it out.
The type or namespace name ‘ContactManagerDBEntities’ could not be found (are you missing a using directive or an assembly reference?)
need to either add reference at top
using ContactManager.Models;
or full namespace
private ContactManagerDBEntities _entities = new ContactManager.Models.ContactManagerDBEntities();
Hope this saves someone else some time.
I have rolled it up and stuck it in my pooper, the whole project!! Hihi.
@ walter:
something like this might solve your problem and leave you requiring one form for both your administrator and for the other users.
I’m assuming that you’ll dynamically added the readonly property to non administrators.
I do a similar thing as follows for Html.Encode fields:
var originalArticle = (from m in _db.NewsArticleSet where m.Id == articleToEdit.Id select m).First();
articleToEdit.dateAdded = originalArticle.dateAdded;
articleToEdit.dateEdited = DateTime.Now;
In your case, if your “Phone” field is null, you would do something like:
articleToEdit.Phone = originalArticle.Phone;
// set Phone for non administrators
Regards,
Gerry (Lowry)
It seems like iteration #6 just takes a dump at “Creating the Views”.
I made it to iteration 6 with no problems at all, and even most of the way through 6 without problem.
For example: “We need to modify the following existing views so that they include contact groups”:
* ViewsHomeCreate.aspx
* ViewsHomeEdit.aspx
* ViewsHomeIndex.aspx
There is no Home directory at all in the downloaded code.
Issue with Iteration #2
I’m following the 2nd part where the the style sheet and master are installed from the ‘vendor’. I made the changes to the other files indicated in the tutorial; however, in both my solution and the downloaded solution, my visual studio is giving this error:
The class or CssClass value is not defined
on these four lines of code in index.aspx:
I don’t understand enough about this yet so I’m not sure where/if this class=”actions delete/edit” is meant to be defined but the error seems to indicate it is not defined.
Any thoughts?
Thanks! Lori
Issue with Iteration #2
(Sorry for the second post, clearly my html code was interpreted rather than pasted)
I’m following the 2nd part where the the style sheet and master are installed from the ‘vendor’. I made the changes to the other files indicated in the tutorial; however, in both my solution and the downloaded solution, my visual studio is giving this error:
The class or CssClass value is not defined
on these four lines of code in index.aspx:
th class=”actions edit”
th class=”actions delete”
….
td class=”actions edit”
td class=”actions delete”
I don’t understand enough about this yet so I’m not sure where/if this class=”actions delete/edit” is meant to be defined but the error seems to indicate it is not defined.
Any thoughts?
Thanks! Lori
Really very nice example. Iteration #7 is very important.
Thanks for sharing really useful information.
Really interesting one! Thanks for sharing a nice blog.
Thanks for publishing this example.
Everyone understands what categories and products are, so there is no time wasted learning the domain.
Great.. thank you.
Nice, that mini MVC flowchart looks tasty.
Thanks, for the samples.
Excellent. I don’t wonder why Microsoft hire you.
would be most appreciated.
I’m really quite taken with the MVC approach.
Thanks for the sample.
I really enjoyed the 4 screencasts on MVC, good stuff.
Thanks very much.
Many thanks MATE.
This is excellent example.
Great example, thanks Stephen
Thanks Stephen.
Thank you for your work on these tutorials.
Great.. thanks.
Thanks for your work on these tutorials.
Thanks for sharing useful info.
Great, thanks Stephen
very nice post thanks!
great post
f3wqe I tried to mock a call to a Linq to SQL query, but I am struggling.
Thanks for this article.
f3wqe I tried to mock a call to a Linq to SQL query, but I am struggling. online masters degree |
Doctorate Psychology | online associate degree
thanks Engineering Diploma | online associate degree
Tiffany and co tiffany and co Tiffany and co tiffany jewellery tiffany jewellery tiffany & co tiffany & co Tiffany jewelry Tiffany jewelry tiffany tiffany tiffany price tiffany price tiffany london tiffany london tiffanys tiffanystiffany sale tiffany sale tiffany uk tiffany uk tiffany and co jewelry tiffany and co jewelry tiffany and co for wedding tiffany and co for wedding
HEY ED treatments are helping me a lot Now i have a happy sex life
HI people the number one selection to cure the ED its viagra use it and see for youre self the power of this great medication
Really interesting one! Thanks for sharing a nice blog.
f3wqe I tried to mock a call to a Linq to SQL query,
Essay| Essay Writing| Essay Help| Custom Essay| Buy Essay|
great .
Online Essay| Essay Writing Service| Essay Service| Essay Topics| UK Essay|
Well done! Nice post! This really helps me to find the answers to my question. Hoping, that you will continue posting articles having lots of useful information. Thanks a lot!
It’s lucky to know this, if it is really true. Companies tend not to realize when they create security holes from day-to-day operation.wr
selam hi This sounds fascinating sıcak sohbet I’m going to read that tracing articlekısa aşk şiirleri when I have a moment.
Wow. erotik film izle is
şifalı bitkiler zayıflama de
çet sohbet fer
netlog ger
müzik dinle err
şarkı dinle
cüneyt arkın filmleri kk
isyan sözleri fer
hikayeler er
kadir inanır filmleri izle der
escort bayanlar der
bedava chat dd
chat odaları der
liseli kızlar derf
kızlarla sohbet fder
sohbet errÖÖ
Hello
Stephen your posts are always useful. Thanks for sharing.
Have a nice day