Friday, August 22, 2008

Microsoft recently released the ASP.Net Model View Controller framework (MVC).  It is currently available as Preview 3 and can be downloaded at http://www.microsoft.com/downloads/details.aspx?FamilyId=92F2A8F0-9243-4697-8F9A-FCF6BC9F66AB&displaylang=en

A new MVC project contains a couple sample views and controllers so you can get an idea of the proper syntax to use. 

In this article, we will add a new model, view and controller to an existing MVC project. 

1.       Open Visual Studio 2008 and create a new MVC project.  For information on how to create a new MVC project, see http://www.davidgiard.com/2008/08/18/TheASPNetMVCSampleAppDemystified.aspx

2.       Open the Solution Explorer (View | Solution Explorer) and select the Models folder.

3.       Add a Model to the project

a.       Right-click the Models folder and select Add | Class.  The Add New Item dialog displays.
Figure 1
    Figure 1

                                                               i.      At the Name textbox, enter “Customer”.

                                                             ii.      Click the OK button to create a Customer class.

b.      The Customer class opens in the class editor.  This class will contain a few public properties that help describe a customer object.  Add the following code to the Customer class.

    public class Customer

    {

        public int CustID { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string StreetAddress { get; set; }

        public string City { get; set; }

        public string State { get; set; }

        public string PostalCode { get; set; }

    }

4.       Add a Controller to the project

a.       In the Solution Explorer, right-click the Controllers folder and select Add | New Item.  The Add New Item dialog displays.
Figure 2
    Figure 2

                                                               i.      Under Categories, select Visual C#\Web\MVC.

                                                             ii.      Under Templates, select MVC Controller Class.

                                                            iii.      In the Name textbox, enter “CustomerController”.

                                                           iv.      Click the Add button to create the CustomerController class and open it in the class editor.

b.      In the CustomerController class, we will create some actions.  Each action will instantiate one or more Model objects and display them in a view object. 

                                                               i.      Add the following statement at the top of the CustomerController class. 

using TestMVC.Models;

                                                             ii.      Add the following private methods to the CustomerController class.  For now, we will create customers out of thin air (as if it were that easy).  In a real application, we would probably call a web server or query a database to get customers.

        #region private methods

        private Customer GetCustomer1()

        {

            var cust1 = new Customer

            {

                CustID = 1,

                FirstName = "David",

                LastName = "Giard",

                StreetAddress = "123 Main",

                City = "Boringville",

                State = "MI",

                PostalCode = "48108"

            };

 

            return cust1;

        }

 

        private Customer GetCustomer2()

        {

            var cust2 = new Customer

            {

                CustID = 2,

                FirstName = "John",

                LastName = "Smith",

                StreetAddress = "321 Elm",

                City = "Nowhere",

                State = "OH",

                PostalCode = "41001"

            };

 

            return cust2;

        }

 

        private List<Customer> GetAllCustomers()

        {

            Customer cust1 = GetCustomer1();

            Customer cust2 = GetCustomer2();

            List<Customer> allCusts = new List<Customer> {cust1, cust2};

            return allCusts;

        }

 

        #endregion

                                                            iii.      Add some Action method to the CustomerController class.  We’ll start with a List action.  Paste the following code into CustomerController.cs.

        public ActionResult List()

        {

            var allCustomers = GetAllCustomers();

            return View("List", allCustomers);

        }

                                                           iv.      In the List, we get a list of customers (all 2 of them) and return a view.  Unlike the generated code, we explicitly specify which view to return (“List”) and we pass in some extra data (allCustomers) that the view will consume.

5.       Add a view to the project.

a.       In the Solution Explorer, right-click the Views folder and select Add | New Folder.  A new folder appears in the Solution Explorer.  Rename this folder to “Customer”.

b.      In the Solution Explorer, right-click the Customer folder and select Add | New Item.  The Add New Item dialog displays.

                                                               i.      Under Categories, select Visual C#\Web\MVC.

                                                             ii.      Under Templates, select  MVC View Content Page.

                                                            iii.      In the Name textbox, enter “List”.

                                                           iv.      The Select a Master Page dialog displays. 
Figure 3
   Figure 4

1.       Navigate to the Views\Shared folder and select Site.Master.

2.       Click the OK button to add this view content page to the project.

c.       Add visual elements to the View

                                                               i.      If it is not already open, open the List view by double-clicking List.aspx in the Solution Explorer.  Click the Source tab at the bottom of the editor.

                                                             ii.      Replace the code in List.aspx with the following

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="List.aspx.cs" Inherits="TestMVC.Views.Customers.List" %>

<%@ Import Namespace="TestMVC.Views.Customers"%>

<%@ Import Namespace="TestMVC.Models"%>

 

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%= Html.Encode(ViewData["Message"]) %></h2>

    <table>

        <tr>

            <td>ID</td>

            <td>First</td>

            <td>Last</td>

            <td>Addr</td>

            <td>City</td>

            <td>State</td>

            <td>ZIP</td>

            <td>&nbsp;</td>

        </tr>

        <% foreach (Customer cust in (List<Customer>)ViewData.Model)

           { %>

            <tr>

                <td><%=cust.CustID %></td>

                <td><%=cust.FirstName%></td>

                <td><%=cust.LastName%></td>

                <td><%=cust.StreetAddress%></td>

                <td><%=cust.City%></td>

                <td><%=cust.State%></td>

                <td><%=cust.PostalCode%></td>

                <td>&nbsp;</td>

            </tr>

        <% } %>

    </table>

</asp:Content>


The above code displays a list of Customer model objects.  In a real-world example, we may choose to have the Customer model derive from a base class and only refer to the base class in the view.  This would increase the separation between our view and our model.

6.       Test the application

a.       Save and compile the solution (Build | Build Solution).   Correct any errors you find.

b.  Run the solution (Debug | Start Debugging).  Depending on the port number used by Casini, it should display in your browser with a URL such as
http://localhost:4152/Home

c.       Navigate to the List page by changing the URL to
http://localhost:4152/Customers/List
(Replace the port number if necessary)

d.      You should see a list of 2 customers in your browser
Figure 4
    Figure 4

e.      Set a breakpoint in the List method of CustomerController.cs and refresh the page to step through the code as it executes.

In this article, we created a model, view and controller from scratch and displayed them.  You can download the code for this project here.

In the next article, we will use the ID of the URL to specify a single customer.

.Net | ASP.NET | MVC | Tech
Friday, August 22, 2008 8:02:34 AM (Eastern Standard Time, UTC-05:00)
 Wednesday, August 20, 2008

I have been plagued recently by a recurring problem with Visual Studio 2005.

When I attempt to exit Visual Studio, I receive the error "Visual Studio cannot shut down because a modal dialog is open" and I am not able to exit.  The rub is that there is no modal dialog - close every visible window in VS, close all other apps, resize, move and minimize VS and I can find no dialogs, modal or otherwise.  Some bit inside VS is set incorrectly convincing itself that a dialog has not yet been closed.

The only solution was to open Task Manager and kill Visual Studio.

I have automatic updates turned on so, if this is a bug, I expected it would have been fixed by now. 

I found a number of posts and threads about this issue so it is not uncommon but nearly every post did not list a solution.

After some digging, I discovered a hotfix for this problem that is not included in the normal Windows updates. 

You can read the details of the problem from Microsoft here http://support.microsoft.com/kb/936971 and you can download the hotfix here
https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=7259

One important point.  Visual Studio must be closed before installing the hotfix so you may end up killing the process via Task Manager one last time.

.Net | Tech
Wednesday, August 20, 2008 6:51:23 PM (Eastern Standard Time, UTC-05:00)
 Tuesday, August 19, 2008

Every year, I become a bit more accepting of my own ignorance. 

I decided a long time ago that I wanted a career in which I could continue to learn and to expand my knowledge.   Software development affords me that opportunity because it is such a large field and because it changes so rapidly. 

It is conceivable (though extremely unlikely) I could learn everything there is to know about software development and find myself completely caught up with learning for one day.  If that miracle were to occur however, I would go to bed that night and awaken to discover that things had been invented while I slept.  And I would once again be ignorant about some things.

But that day will never come.  There is an infinite amount of knowledge to be acquired and a finite amount of time in which to learn it.  The ratio of what I know to what I don't know is likely to remain small.

Yesterday, I had lunch with a guy who knows a great deal about Windows Presentation Framework (WPF).  Since I am extremely ignorant about WPF, it was a good opportunity to learn some new things.  But WPF contains so much that we could probably have lunch every day for months and I would still only scratch the surface of this framework. 

I want to know everything but I realize and accept that I cannot.  So what's the answer? 

The answer is in learning how to find the answers.  "I don't know" is an acceptable answer to any question, but "I can't do it" is not.  As new challenges and problems arise, we need to be able to figure them out - to find the answer.  Usually our experiences only get us so far.  We need help finding answers. 

Certainly the World Wide Web helps.  Many times, when faced with a problem, I've discovered an article or blog post written by a developer who faced and conquered a similar problem.  Search engines such as Google allow us to find these solutions more quickly. 

Books and magazines help as well.  They provide knowledge based on the experiences of the authors.  So do Classes and conferences.

I've found one of the best ways to improve my knowledge base is to build a network of smart people on whom