Home .NET ASP.NET MVCon a real-world example. Theory and Introduction.

ASP.NET MVCon a real-world example. Theory and Introduction.

by admin

The Microsoft team is developing its products and tools for developers very intensively. On this topic already and exhausts were joking about the release of new versions of frameworks. Developers who work for large companies, who are involved in big projects generally don’t look too enthusiastic about this, because it’s impossible to migrate such majors to a new version in a short period of time. It can be fraught with both bugs and changes in the entire project structure, which is not always easy to do. The above unfortunately (or fortunately) does not apply to me, and it gives me the opportunity to use everything new without regard to the background. Projects are quite manageable, I often switch to a new version painlessly and implement new features during the implementation of the next task in the project. Of course, at the time of implementation this introduces a certain chaos into the code, since different parts of the code use different principles (e.g., LINQ implementation), but the subsequent refactoring of the code brings everything into a single view and everything is back to normal.

What’s this all about?

One of these innovations is ASP.NET MVC – template implementation Model-View-Controller for the .NET platform. Let’s try to understand what this is, why it’s needed, and let’s apply our knowledge to a simple but real application.

Principle of MVC

The architectural pattern Model-View-Controllerimplies the division of the application into three main components: Model, Viewand Controller, isn’t it strange? 🙂 Each of these components is responsible for its own tasks. In general terms, this is :

  • Model – is basically all the business logic of our application. It contains the classes that are responsible for our data (entities), manipulating it, writing to and reading from the database, as well as the interaction between the entities themselves. If our application is small, we will most likely be working with the data right here. If, however, the project is larger and contains a lot of logic, then it is better to bring the logic and work with the data into separate projects (assemblies). And when we come across a very large application, we will have to physically carry it out to other servers (Application Server).
  • View is in charge of user interaction (UI). We will use it to output our data to the client, create interface to edit them and so on. But only the rendering part. No logic!
  • Controller – is our link between the first two components. Controller Receives data about our request to the server, somehow processes this data (e.g. gets values from the submitted form) and passes it to Model. After processing or receiving data it selects the way we display data to the client (the desired View).

What does this give us? We getfull control over the output HTML. Lighter" applications. Adherents of TDD (Test-Driven Development) will love it, MVC allows you to use this approach to the fullest extent and test just about anything. We also geta complete separation of logic from data presentation. Some of us will just say "finally, everything is for people", while others will be disciplined not to write data manipulation code in button click handler. By the way, did I mention handlers? Forgetit. There are no more. No event handlers, no ViewState, no Drag’n’Drop controls on form. Yes, you’ll have to do more hardcoding by hand, someone might even learn how it all really works. At the same time, if we are deprived of features that are simply contrary to the idea of MVC, we are not deprived of the main thing. We still have MasterPages, UserControls, Membership. All in all, it’s not as bad as it may seem at first glance. Has MVC replaced WebForms? No, WebForms will live on and evolve. MVC just makes it possible to write applications differently. If you have a heap of data, GridView editing, etc. application, then WebForms is still the right solution for you. Also with MVC you will forget about all the problems with URL-Rewriting, maybe it’s not so much a problem with WebForms, of course, but for MVC it’s a native feature.

From theory to practice?

The other day I got a project from a good friend. I need a new website for a portable electronics service center. I have the old one, but it is a bit unsatisfying. In fact, nothing complicated: a few pages of information, a catalog of available accessories with prices and integration with 1C. For the latter and raised the question. All the database is maintained in 1C, I want the customer could go to the site and by entering a number of his receipt, to see the status of repairs: ready, not ready, whether all repaired under warranty or for something will have to pay extra.

Preparing for work

First of all you should have the Microsoft Visual Studio 2008 (if I’m not mistaken, the Express edition should work too), NET Framework 3.5 as well as the ASP.NET MVC (Preview 3 is available at the time of writing). After successfully installing all the goodies, let’s create our project. File ->New -> Project… In the window that will open, choose in Project Types the language in which you are writing and the type of project Web, from the offered templates we need ASP.NET MVC Web Application. My project is called "ITService".
ASP.NET MVCon a real-world example. Theory and Introduction.
Next we will be asked to create a Unit Test Project for our application, we’ll do without it for now.
As a result we have our clean project like this :
ASP.NET MVCon a real-world example. Theory and Introduction.
In addition to the familiar directories, there are some unfamiliar to us. Let’s walk through them in order :
/Properties – standard directory for Web Application, contains the project’s settings.
/References – References to other builds, projects, etc.
/App_Data – Special directory for data storage
/Content – in this directory we will store images, styles and stuff like that. Basically, all staticcontent on the site
/Controllers – Classes responsible for Controller components
/Models – classes with our logic
/Views – Directly the UI of our application. In this directory we create a directory for each controller (/Views/Home in our case). We add an aspx page for each method of the controller.
/View/Shared – contains things we can use for all controllers, like MasterPages and UserControls.
Well, shall we try running it? Voila! We got the result :
ASP.NET MVCon a real-world example. Theory and Introduction.
Click on the links in the top menu and see how the URLs are organized in the default MVC. The About page has the address localhost :55515/Home/About (your port might be different). So we have the following structure mysite {controller}/{action}. Well, that’s pretty good.

What we need

As I said, I need a site with some information pages, catalog of accessories and special page, which will receive and output data from 1C. Okay, let’s first try to implement our staticpages, let’s make up MasterPage, write the necessary styles and make them work. Of course in a more complex application we should start with the development of business logic, think about how we will store data, write all this and only then proceed to the interface. But in our case the project is small, so this sequence can be neglected.

Making our life easier while writing code

If you look at our Site.master, you’ll see that the path of css, e.g., it’s relative, i.e. ../../Content/Site.css. This will not work for us, because our pages will be nested in different ways, and the link will be lost, we need to fix it on the path from the root. For CSS, of course, could be prescribed by hand, but jumping ahead of the curve, I say that we will also have pictures on the site. Each time you have to write a long enough path to them boring, so let’s do Helper. Let’s create a folder Helpers, and then add the classAppHelperwith the following code:

using System.Web;
public static class AppHelper
{
public static string ContentRoot
{
get
{
string contentVirtualRoot = "~/Content" ;
return VirtualPathUtility.ToAbsolute(contentVirtualRoot);
}
}
public static string ImageRoot
{
get { return string Format( "{0}/{1}" , ContentRoot, "Images" ); }
}
public static string CssRoot
{
get { return string Format( "{0}/{1}" , ContentRoot, «Css» ); }
}
public static string ImageUrl( string imageFile)
{
string result = string Format( "{0}/{1}" , ImageRoot, imageFile);
return result;
}
public static string CssUrl( string cssFile)
{
string result = string Format( "{0}/{1}" , CssRoot, cssFile);
return result;
}
}

In it, we declared a static property ContentRoot – the path to our content, paths to the directories with images and css files, and 2 static methods, ImageUrl and CssUrl, which take the file name and return the corresponding path in our application. In order to use our class let’s change the link tag which connects the styles in Site.Master to the following :

< link href ="<%= AppHelper.CssUrl(" Site css ")%>" rel =«stylesheet» type ="text/css" />

And don’t forget to move Site.css to the created directory /Content/Css, we will separate static content by its type.Now if we recompile our project, the path will be spelled quite correctly :

< link href ="/Content/css/Site.css" rel =«stylesheet» type ="text/css" />

At this point we have written our Helper to write the correct path to the images and stylesheets. Next, let’s look at how we can work with HTML in general and what is offered to us.

Working with HTML

Microsoft offers HtmlHelper to make writing code easier. It is a class with a set of static methods that allows you to render the necessary HTML tags. For example, to render a picture, you just need to write

<% =Html.Image( «image.png» , «Alt text» ) %>

On the page it will look like

< img src =«logo.png» alt =«Alt text» />

If we use our AppHelper to calculate the path to the picture, we write :

<% =Html.Image(AppHelper.ImageUrl( "logo.png" ), "Alt text" ) %>

This code will already generate the right picture and spell the right path :

< img src ="/Content/Images/logo.png" alt =«Alt text» />

Another interesting method is Html.ActionLink:

<% =Html.ActionLink( "About us" , "About" , "Home" ) %>

This method will generate a reference to the "About" method of the "Nome" controller with the text "About us"
You can also use more "modern" means to write the same code usingLambda Expressions:

<% =Html.ActionLink<ITService.Controllers.HomeController>(x => x.About(), "About us" ) %>

What’s going on here, I think, is clear from the syntax.

A little hint:to avoid having to write the ITService.Controllers namespaceevery time, let’s write it in web.config in the section < system.web > < pages > < namespaces > :

< add namespace ="ITService.Controllers" />

Such links can now be written shorter :

<% =Html.ActionLink<HomeController> (x => x.About(), "About us" ) %>

Separately, we should mention forms. We now have to work with them quite explicitly (no Postback, remember?). The simplest form will look like this :

<% using (Html.Form<HomeController> (x => x.Index())){ %>
<% = Html.TextBox( «name» ) %>
<% = Html.SubmitButton( «cmdSend» , "Send" ) %>
<% } %>

To work with the from tag, we need to use the using directive and put all the form fields in its scope. This will provide us with a closing tag . The Html.Form(x => x.Index()) declaration also tells us that the form will be sent to the "Index" method of the HomeController. I think that’s a pretty healthy idea. At first, when I saw this mixture of html and server-side code parts, I was horrified. Welcome back to classic ASP, which was full of this noodles. It’s not that bad, though. It’s not at all what it seems at first glance when you start working with it. All of these tools are really powerful.

ASP.NET Routing

What are routers? Routers allow us to work with URLs that don’t point to physical files on our server, instead the path is parsed into parameters that we already use in our application. We can also map a certain part of the path to a certain controller and its method. This model is used by default, but we can define mappings that we are comfortable with. On the one hand it’s similar to good old URL-Rewriting, which has already been written about in detail on the hubra article, but it’s only on one hand. In fact, it’s different. If we use UrlRewriting, a request of the form mysite.com/products/product1 is converted by running to mysite.com/products.aspx?id=product1 Naturally, we can’t generate URLs that match our URL rewriting rules. So if we change the logic somewhere and change the address templates, we’ll have to hand-correct all the places where those URLs are generated. In MVC we don’t need to make any changes, because the MVC itself parses the path it receives without any problems.
All work with Routers in MVC is organized in Global.asax.cs. Let’s look there in our project and see the following :

routes.MapRoute(
«Default» , // Route name
"{controller}/{action}/{id}" , // URL with parameters
new { controller = "Home" action = "Index" , id = "" } // Parameter defaults
);

As you can see, we add our own router to the collection of routers, operated by our application. With the name Default, we write the URL mask and create an anonymous type, in which we write the default parameters. We will make changes here when we go straight to the implementation. In the meantime, if you like this way of generating addresses, why not? You can leave everything as it is and that will work too.

End of the beginning

Well, that was an introductory section in which I tried to cover the most basic concepts about the ASP.NET MVC platform. To what extent I succeeded, you’ll have to judge. I am not an expert in this field. I was just curious to share this information with people because there is very little information on this topic in runet.
I want to point out that I care about your opinion on everything, so any feedback would be appreciated. If criticism, I’m sure it will be constructive 😉
In the following articles I will go directly to the implementation of the intended application. There will most likely be more code. And that doesn’t make me happy with such formatting as on the hubs 🙂
* All the code in the article has been highlighted, as far as it could be, with Source Code Highlighter

You may also like