Let me start by saying that I’m not a webdeveloper I do most of my work in Winforms. I personaly think webdevelopment is a bit frustrating. The way you have to test for x number of browsers just to find out there is another browser ou there you never heard f and that doesn’t render your site like it should. But anyway. I had a stab at ASP.Net MVC just to see how they implement MVC (Model-View-Controller).
I must add at this point that I had previous experience with JSF and I kinda liked it. But what I didn’ like was the fact that the MV and C were pretty closely coupled. Especialy the C and the V. Personaly I would like them a little less coupled so that I can use my M with another V and perhaps even have the C with another V. I understand that certain technologies work in a different way and that they really don’t mix and match but in an ideal world that should be possible. If for example I want a winforms application that has the same functionality as a web application. I really don’t want to write all the controllers and models twice just the view. Just put everything else that is reusable in one assembly and have two view components. ANd I’m not saying everything will be or needs to be reusable. I just want to reuse as much as possible.
Here we go. First thing to do is download the stuff. And install it of course.
Then I startup VS2008 and I get the option to make a new asp.net MVC project.
So I do that. And then it asks me if I want a Test project to go with that.
I only get to choose a Visual studio unit test. But I don’t really want that, allthough I am curious what it will do so I create it anyway.
First thing it does is create a whole bunch of folders and files that it things I will need and that serve as an example. It has also created some unittests for me, for the things that are already there. Ok, looks pretty cool. I can even run it. And it works.
This is the main page.
So now I want to add my own page to the mix. I want to add the Person page. A page with a lastanme and a firstname, because our Person only has those two attributes.
Here is what our Person looks like in VB.Net.
Namespace Model
Public Class Person
Private _firstName As String
Private _lastName As String
Public Sub New(ByVal FirstName As String, ByVal LastName As String)
_firstName = FirstName
_lastName = LastName
End Sub
Public Property FirstName() As String
Get
Return _firstName
End Get
Set(ByVal value As String)
_firstName = value
End Set
End Property
Public Property LastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
End Set
End Property
Public Overrides Function ToString() As String
Return _lastName & " " & _firstName
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If TypeOf obj Is Person OrElse obj IsNot Nothing Then
Return (_lastName & " " & _firstName).Equals(CType(obj, Person)._lastName & " " & CType(obj, Person)._firstName)
Else
Return False
End If
End Function
Public Overrides Function GetHashCode() As Integer
Return (_lastName & " " & _firstName).GetHashCode()
End Function
End Class
End Namespace```
Simple but clean.
But for the moment I want to take it one step at a time. So I want to have an extra menu item named Person on the menu page.
I found the menuitems (Home, About) in the Views/Shared/Site.Master file. And it looks like this.
```html
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>```
So I guess I just have to add my own to make it work.
```html
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("Person", "Person", "Person")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>```
How does this ActionLink work. Well according to the intelisense (who needs a manual anyway) The first magic string is the tag that will be shown on the page. The second is the action and the third is the controller.
So now we have this.
<div class="image_block">
<img src="https://lessthandot.z19.web.core.windows.net/wp-content/uploads/blogs/WebDev/mvcnewproject2.jpg" alt="" title="" width="326" height="124" />
</div>
I can live with that.
Of course when I click on it nothing happens since I have no controller yet. I get this errormessage. Which is in Dutch for some reason. But in short it says it can’t find Person/Person.
<div class="image_block">
<img src="https://lessthandot.z19.web.core.windows.net/wp-content/uploads/blogs/WebDev/mvcnewproject3.jpg" alt="" title="" width="1070" height="220" />
</div>
Which means it can’t find a controller.
So lets create PersonController with an action Person on it.
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class PersonController : Controller
{
public ActionResult Person()
{
return View();
}
}
}
That should work, right?
No, it doesn’t because a controller also needs a view. In this Case called Person. If we click on it we get this errormessage.
Serverfout in toepassing /.
The view ‘Person’ or its master could not be found. The following locations were searched:
~/Views/Person/Person.aspx
~/Views/Person/Person.ascx
~/Views/Shared/Person.aspx
~/Views/Shared/Person.ascx
Beschrijving: Er is een onverwerkte uitzondering opgetreden tijdens het uitvoeren van de huidige webaanvraag. Raadpleeg de stacktracering voor meer informatie over deze fout en de oorsprong ervan in de code.
Details van uitzondering: System.InvalidOperationException: The view ‘Person’ or its master could not be found. The following locations were searched:
~/Views/Person/Person.aspx
~/Views/Person/Person.ascx
~/Views/Shared/Person.aspx
~/Views/Shared/Person.ascx
Fout in bron:
Er is een onverwerkte uitzondering gegenereerd tijdens het uitvoeren van de huidige webaanvraag. Aan de hand van de onderstaande tracering van de uitzonderingsstack kunt u meer informatie verkrijgen over de oorsprong en de locatie van de uitzondering.
Stacktracering:
[InvalidOperationException: The view ‘Person’ or its master could not be found. The following locations were searched:
~/Views/Person/Person.aspx
~/Views/Person/Person.ascx
~/Views/Shared/Person.aspx
~/Views/Shared/Person.ascx]
So we seem to have a choice where we put our view and how to name it.
~/Views/Person/Person.aspx
~/Views/Person/Person.ascx
~/Views/Shared/Person.aspx
~/Views/Shared/Person.ascx
I will just create a new folder in views and call it Person and then a new page called Person.aspx.
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
PersonPage
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>Person</h2>
<p> FirstName: <%= Html.Encode(ViewData["FirstName"]) %><br />
LastName: <%= Html.Encode(ViewData["LastName"]) %>
</p>
</asp:Content>
The important part is this.
<%= Html.Encode(ViewData["FirstName"]) %>```
Where I say to get the ViewData from the somewhere. If I change my controller like this.
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
public class PersonController : Controller
{
public ActionResult Person()
{
ViewData["FirstName"] = "Christiaan";
ViewData["LastName"] = "Baes";
return View();
}
}
}
I will even get something to show up on that page.
So all this in less than 5 minutes. Next stop is using some real data.