📜 ⬆️ ⬇️

We master ASP.NET MVC together. Introduction

A bit of background


My friend and I are totally interested in web development and everything related to it. This year, the university was given an order to write a web portal for students, in which it will be possible to get the latest information on grades, a schedule ... But more on that later. Of course, the “Design Bureau” (the so-called department which is responsible for developing software at the university), without hesitation, decided to transfer the task to the students. It just so happened that we were among these students and we were offered a choice of ASP.NET Web Forms or PHP Symfony. And in order to complicate the task and learn something new, we asked to allow us to do the task on ASP.NET MVC. The project is now fully developed, and I think as we finish, we will post the source code of the project here. But more about that later. And so, in order to somehow systematize our knowledge and get advice from professionals, we decided to start a series of articles that can help other people begin to learn this wonderful framework. Well? Let's start!

And so, for robots we need at least the following things:

We propose to create a project from scratch, this will allow you to better understand how the ASP.NET MVC project works and is built, and I don’t like the demo code that is present during standard project creation.


Let's start with a clean slate


Let's start by creating a Class Library project for C #. Now let's remove everything unnecessary from it: Class1.cs , AssemblyInfo.cs from the Properties directory and all that is in References . As a result, we get just an empty project.

Types of projects


We all know that Visual Studio supports many different types of projects, with each of which the studio works in different ways. For example, if we try to launch the Class Library project we created (Ctrl-F5), we will receive the following message:
')
A project with an Output Type of Class Library cannot be started directly.

Since our goal is to create an ASP.NET MVC project, we will change the type of our project accordingly. To do this, select the Unload Project item from the context menu of the project, open the project file for editing (right-click on the project - Edit ) and add the Guid for projects of the Class Library type:

< ProjectTypeGuids > {fae04ec0-301f-11d3-bf4b-00c04f79efbc} </ ProjectTypeGuids >

And now add a Guid for the Web Application:

< ProjectTypeGuids > {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} </ ProjectTypeGuids >

Please note that the Guid for Web Application must be first, otherwise VS will not reload the project.

After we reload the project (right click on the project file - Reload Project ), we see that the project icon has changed. If you now try to start the project, the studio will launch the explorer. In addition, since additional settings are required for normal Web Application operation, after the project is restarted, the studio will correct the ProjectExtensions configuration section.

The final step in changing the type of our project will be to adjust the project's Output path to bin \ . To do this, in the project properties, go to the Build tab and change the Output path .
image

Routing Setup


In ASP.NET MVC, as in most other MVC frameworks, URLs do not display the actual path to a file on disk, as implemented by ASP.NET WebForms. In MVC, the URL is more intuitive [controller / action], this transformation is called routing and in order for it to work correctly - we need to make some changes to the project.

First of all, add Web.config . Clean it up and add the following:

< httpModules >
< add name ="UrlRoutingModule" type ="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</ httpModules >


This module is needed to verify that the requested URL matches the specified routes and if a match is found, HttpHandler takes control.

Let's create our first application.


Routing determination is best done at the start of the application ( Application_Start ). To do this, we need to add the Global Application Class ( Global.asax file) to the project. I prefer to replace the Global.asax.cs file (codebehind file) with my Application.cs .
We get the following Global.asax :

<%@ Application Inherits= "Mvc.Application" %>

Route definition


After we added the Global Application Class, Visual Studio added a few references to the project:
image

Add another link to the assembly System.Web.Routing . (This build is installed with NET 3.5 Service Pack 1)
Next, add a call to the RegisterRoutes method in Application_Start :

using System.Web;

namespace Mvc
{
public class Application : HttpApplication
{
public void Application_Start()
{
Router.RegisterRoutes(RouteTable.Routes);
}
}
}


For the definition of routes, I use the class Router , which we will define later. Pay attention to RouteTable. Routes is a collection of type RouteCollection , which will contain all routes of our application, and the RegisterRoutes method fills this collection with data. The route itself (route) contains information about how to handle the request.

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


The UrlRoutingModule matches the current request with the routes we have defined and processes it accordingly. If the request matches one of the routes we specified, then RouteHandler transfers control to HttpHandler .

Now, add a link to the System.Web.Mvc assembly and define the Router class itself. The class Router will be:

using System.Web.Mvc;
using System.Web.Routing;

namespace Mvc
{
public static class Router
{
public static void RegisterRoutes(RouteCollection routes)
{
Route route = new Route( "{controller}/{action}" , new MvcRouteHandler());
routes.Add(route);
}
}
}


MvcRouteHandler will create an instance of MvcHandler that processes requests based on data from RequestContext .
The route (Route) should contain information about which controller to use (instantiate) and what method to call this controller.


Adding Controllers


Add the controller to the Controllers directory, which usually contains all the controllers:

using System.Web.Mvc;

namespace Mvc.Controllers
{
public class HomeController : Controller
{
public string Index()
{
return "Hello World!" ;
}
}
}


This controller has one Index () method defined. Now, when we go to the address ~ / home / index , we will see the inscription "Hello World!".

Next, modify the RegisterRoutes method as follows:

public static void RegisterRoutes(RouteCollection routes)
{
Route route = new Route(
"{controller}/{action}" ,
new RouteValueDictionary( new { Controller = "Home" , Action = "Index" }),
new MvcRouteHandler());
routes.Add( "Default" , route);
}


In fact, we made the Index method, the Home controller, run by default. That is, if we go to the address ~ / we will see the result of running Index () .

Add view


Since returning the entire page as a string is far from the best practice for building a web application, we will add a view that will contain the page design.

Create the following hierarchy of Views / Home folders and add a new GUID that will indicate to the studio that we are working with an MVC project:

< ProjectTypeGuids > {603c0e0b-db56-11dc-be95-000d561079b0};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} </ ProjectTypeGuids >


After restarting the project, new types of MVC-specific elements will become available to us.
image

Views and components (control) inherit System.Web.Mvc (you can verify this by looking at the <% @ Page%> directive). WebFormsViewEngine uses the same compilation principle as WebForms. That is, to work correctly, we need to add a link to this assembly in the web.config :

< compilation debug ="true" >
< assemblies >
< add assembly ="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</ assemblies >


Next, add the MVC View Page Index.aspx to the Views / Home directory and change the type returned by the Index () method:

public ActionResult Index()
{
return View();
}


The last thing we need to do is to prevent direct access to the views that are in the Views folder. (Go to ~ / views / home / index.aspx and you will see the content of this page.) To prevent this from happening, add the following lines to Web.config

<? xml version ="1.0" ? >
< configuration >
< system.web >
< authorization >
< deny users ="*" />
</ authorization >
</ system.web >
</ configuration >


Importing namespaces into an assembly


Just like WebForms, ASP.NET MVC views are compiled in a separate aspnet_compiler process. Until we add links to the assemblies that we use in the application to the configuration file of the web application, the compiler will not know which one to use.

< compilation debug ="true" >
< assemblies >
< add assembly ="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
< add assembly ="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
< add assembly ="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</ assemblies >
</ compilation >


Now the compiler will adequately respond to our attempts to use the types defined in one of these assemblies. Now, for convenience, we will add namespaces in Web.config, which will allow us to use short type names.

< pages >
< namespaces >
< add namespace ="System.Collections.Generic" />
< add namespace ="System.Linq" />
< add namespace ="System.Web.Mvc" />
< add namespace ="System.Web.Mvc.Html" />
</ namespaces >
</ pages >


Many new constructions have been added to the latest version of C #, and of course we would like to use them in our views. To do this, add a few more configurations:

< system.codedom >
< compilers >
< compiler language ="c#;cs;csharp" extension =".cs" type ="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
< providerOption name ="CompilerVersion" value ="v3.5" />
< providerOption name ="WarnAsError" value ="false" />
</ compiler >
</ compilers >
</ system.codedom >


Generalized species


In ASP.NET MVC, it is possible to define a strongly typed view by defining the Inherits attribute of the Page directive using the generic System.Web.Mvc.View class.

Example:

<%@ Page Inherits= "System.Web.Mvc.ViewPage<Object>" %>

In order for the compiler to understand this construction, we need to define a parser in Web.config:

<pages pageParserFilterType= "System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" >
//...
<pages>


That's all for now.


We manually created an ASP.NET MVC project with a minimal set of elements in order to better understand the internal structure (work) of MVC.
Sources can be downloaded here .

Next time we plan to write an article about the principles and methods that are best used for working with ASP.NET MVC.
So to be continued.

PS Oh, yes, if anyone has one extra invite, then my friend, with whom we were engaged in the translation and design of this article, would also like to get on Habr.
This article was taken as the basis.

Source: https://habr.com/ru/post/75346/


All Articles