MVC 5 – OWIN and Katana

OWIN was the first step towards elegant design for the whole asp.net stack. By separating the hosting concerns from the framework, Microsoft was able to build modular services and add it to the stack such as Web API, SignalR and now the whole asp.net core.

Katana was the first implementation for OWIN on IIS, you won’t feel much change as it is still running using the System.Web assembly but at least it enables you to run your middlware under IIS.

To understand more about the motivation, the moving parts and samples of OWIN, you can watch the following video in Arabic.

 

 

Advertisements

Security Options for Asp.Net (Arabic)

This is a series of videos to explain the available options to secure your asp.net application. Although the demonstration is done using MS Stack, it applies to any technology.

In each video, we will take an authentication type, explain its concept and show a demo on an asp.net application. we should cover the following authentication types

  1. Basic
  2. Digest
  3. Windows
  4. Certificate
  5. Forms
  6. Claims
  7. OAuth

 

Here is the link to the YouTube playlist, I will add each video once it is recorded. Feel free to leave any comments or suggestions

How to build a web application on Azure?

Microsoft Azure is one of the leading cloud platforms that enables us to build a scalable and highly performing web applications. In this article,  I will list the available options that allow you to quickly understand what you need in order to build your application and what services to use in each layer.

What do we need to build a web application?

Each web application needs some services in order to work propably. For example, a web server, a database server, queuing system etc..

In the past few years, I have found many people using Azure wrong or inefficiently. Some used virtual machines while they should have used Web Apps, others used a huge size of a virtual machine because they didn’t know they could scale their VM without losing the data. Accordingly, I will do my best to give you a summery of Azure services that you can utilize to build your next fantastic Web App.

Application Life-cycle Management

So, first things first. You need a place to store your use cases, test cases, source code, run unit tests and perform a continuous integration and deployment.

Although it may not be a part from Azure, but Team Services integrates seamlessly with Azure and many Azure Services like Web Apps, Mobile Apps, Azure Functions … support continuous integration with Azure.

Team Services help you to have a central repository for your source code, documents and requirement. It also supports Visual Studio Team Services and Git as a source control. It is free and supports unlimited number of projects with 5 free users.

Hosting

Now, you developed your web application, tested it and it is time to host it. Azure supports hosting for .Net, Java, PHP, NodeJS, and Python built applications.

In this phase you have more than one option:

  1. Virtual Machine: This is the very basic option and should not be used unless you have no other way, ex: migrating a legacy application that cannot work with a PAAS offering, in this case you simply have a virtual machine in the cloud and you can remotely connect to it, install the needed software and deploy your application. Note that this is the most expensive solution.
  2. Cloud Services: This is the same as Virtual Machine except that it offloads some of the work to be done by you such as setting up software and windows updates. It has 2 types, a web role which is setup to host a web application directly, and a worker role which enables you to host an executable application such as a windows service or a console app. The good part about cloud services is that you provide it with a package that has your code and it manages the deployment of the application. If the virtual machine hosting the app went down, Azure will automatically creates another virtual machine and deploy the code to it.
  3. App Service: This is the Platform as a Service or PAAS offering from Azure, all you have to worry about here is your code. It gives you a vitrual directory on cloud and all you have to do is to deploy your App to it either through web deploy, FTP or upload a package. It also offers continous integration and monitoring capabilities. This is the most flexible and cheapest option and you can autoscalre it according to the CPU usage, RAM usage and other factors. So basically, you can start small and scale as you need later. Azure App Service has Web Apps to host your application, Mobile App which is a backend as a service to your mobile apps, Logic Apps which gives you the option to build your businss logic and integration between different systems, and finally API Apps which is used to host your REST api web Apps.

Integration

If your application integrates with other systems, then you can use Azure Logic App, Azure Functions, BizTalk Service and Service Bus

Most services gives you a very nice visual designer that allows you to orchestrate your business logic and it offers out of the box seamless integration with many external systems such Office 365, Dynamic CRM or On-premise system through BizTalk Services

Data Storage

Azure offers many services to store your data, all of it are based on Azure Storage Account which is the main storage system for all services in Azure. Each account has some storage and throughput limitation, you can check these limitation from here

  1. If you need to store text files or video files, you can use Page and Block blobs. Each type is suitable for specific file types, you can read more about it from here
  2. Use Azure Media Services if you have to store and stream media files.
  3. Azure table storage is suitable if you need a NoSQL database, it provides a high throughput storing and retrieving entities that have no referential integrity between them.
  4. Azure DocumentDB is a NoSQL document database similar to MongoDB, it is a born in the cloud database that you can use if you need a low latency high performing database
  5. Azure SQL Database is a SQL Server database in the cloud where you need not to worry about SQL Server installation, Backup and Restore or anything else, you just create a database and use it.
  6. Azure File Share is used to replace any legacy File System Share in any legacy application.

 

Now, you should be able to have some basic knowledge about the features you can use to build your next web application.

Tips and tricks to enhance asp.net security

There are many ways to enhance Asp.Net Web Application security, either on the web, back-end or database level, in this post, I will list some useful tips and tricks that will help you make your web application more secure.

Although the article discusses the concerns in asp.net context, it is applicable to any other framework

Web Level

Connection String

There are 2 ways to configure the security for your database connection in connection string. The first one is  windows authentication, your application connect to the database server using the Application Pool Identity, and this is the recommended way as it doesn’t include writing any User Passwords in your connection string, not to mention the need to edit web.config with the new password if it has expired, which will cause a restart in the IIS application pool.

The second way is to connect through SQL authentication, in this case, you should not have the password added as a plain text, you must secure your connection string by encrypting it, .Net already support this by running the following command

aspnet_regiis -pe “connectionStrings” -app “/MyCustomApplication”

The aspnet_regiis exe can be found in your Microsoft.net folder under C:\Windows\Microsoft.net, you should find a folder with the version of your framework, ex: v2.0.*

the -pe parameter specifies which section of your web.config you want to encrypt and the -app parameter specifies which IIS web site you want to use.

The algorithm used to encrypt is RSA, for more information about how does this work, please refer to https://msdn.microsoft.com/en-us/library/dtkwfdky.aspx?f=255&MSPPError=-2147217396

Service Accounts Privillages

The service account is used to run the application pool which in turn run the web application, and it is the account that you web application uses as identity when it needs to connect to the database if you specified Integrated Security=True or if you need to have an access to file system, for ex: Logging.

This account must have the least privilege, on the file system, only give it a read access to a specific folder if this is all what you need, on the database, don’t just get lazy and give it db_owner, only grant it the permissions it needs, if it only needs read or write on certain tables, then let it be and don’t give it access to everything.

Why is that? because simply, if someone succeeded to get to this service account, they could harm your servers, I have seen many cases where people uses a domain admin as a service account, imaging what a hacker could do with such account.

Cross Site Scripting (XSS)

Imagine you have a web application, and there is the page with the URL: http://somesite/dashboard/pay?amount=1000.

This page is requested using GET and it needs the user to be authenticated, now the user can only access if he is logged in, but think of the following scenario:

You access a site named: http://someothersite, and in this site, there is an image with a src =http://somesite/dashboard/pay?amount=1000&toAccount=123-123-123.

What will happen is that your browser will automatically try to fetch the source of the image and make a get request to the URL, and by design, the browser will automatically send the cookies for somesite domain including the authentication cookie, and the result will be the execution of the URL and pay the amount of 1000 because the request seems legitimate.

To prevent this issue, you must implement something called Anti-Forgery tokens, this simply means that with each request, the site will put a hidden field in the page and store its value in the user session or cookie, and when the user posts the page to the server, the server will validate that the value in the hidden field is equal to the value stored in the session or cookie, then it will clear the value in the session, this way, if the user tried to submit the page again or in our example, another site request the URL on behalf of the user, the server will deny the request because the request will not include the correct value for the anti-forgery token.

MVC has an excellent support for this by calling the @Html.AntiForgeryToken() in the view and annotating the action method by [ValidateAntriForgery] attribute

to read more about it, follow these links Anti-Forgery in asp.net , Anti-Forgery in web API

SQL Injection

Although this is a very old issue and nearly most of the existing ORM solutions handle it, still some people fall into this problem, the danger of this issue, is that the hacker can get to your database, your database server and from there, he can get to all your other servers, so always validate the user input, always use parameterized queries and skip the user strings if you are building a dynamic SQL.

Web.Config Encryption

Same issue as the connection string, but applies also to keys stored in app.config, you can also call the same command and encrypt the appsettings section, you don’t need to worry about the decryption cause .Net makes it automatically for you

HTTPS

If your application has sensitive data and you want to prevent any chance of the network between the user and the web server being spoofed, then enable HTTPS, it works by encrypting the traffic between the browser and the server by a public/private key using certificate.

Cookies

If your site is using cookies for authentication or maintaining client state, then make sure no sensitive data is there, also if you don’t need to access the cookie inside your client browser, then mark the cookie as Http Only, if the cookie has httponly enabled then it will not be accessible through JavaScript and the document.cookie JavaScript object will not contain this cookie.

Another trick is to mark your cookie as secure only, this will make it accessible and the client will send it to the server only if HTTPS was enabled on the web site, this will ensure that your cookie is safe

Files under virtual directory

Don’t leave any backups in your virtual directory, sometimes we make a backup from web.config in the shape of web.bak or some other format, these files may be served to the client and a hacker can use the info inside it to hack your application.

Session Hijacking

If you are using session variables, which is mainly some variables stored on server session or a state server, depending on your configuration, the web server has to has a key for your session in order to be able to retrieve the data for your session, this key is called Session ID, and by default it is stored in a cookie named ASP.NET_SessionId, if someone gets to this cookie value, they will be able to log in to the site, use any cookie editor extension and update the session ID to your ID and from there they will be logged in as you, so if your site has an edit profile page or a page that allows the user to add credit card info, this data will be stolen.

To prevent session hijacking, you have to do the following:

  1. Use SSL, this way no one will be able to capture the traffic between your users and the web application, consequently, they won’t capture the session ID cookie value
  2. Make the session ID value harder to guess, the worst thing to do is to make the session ID as incremental value, if I logged in and found my session ID as 12345, then I can easily edit it to another number and it will be easy to obtain the session for another user
  3. Set the session ID cookie to be always Http Only, this will prevent any JavaScript from reading its value and will make it harder for any XSS
  4. Regenerate the session ID, this will make it harder for the attacker, even if he got the session ID, it won’t be valid for long time
  5. Prevent concurrent sessions, if you have your user logged in from one session, and he tried to login from another session, there is a probability that he is not the same person, you can be more certain by validating the IP and time used, ex: if the user IP is from USA, and at the same time the user is trying to connect from Europe, then most probably this is an attack

Eliminate unneeded headers

Some headers are not necessary in your web page response, such as Server, Asp-Net version and so on, these headers not only add a performance headache, but make the attacker job easier as he already knows what framework, servers and environment he will be attacking, so always edit your web.config or IIS Console and remove these unneeded headers

Database Level

Data Encryption

A very simple case for encrypting the data is the user passwords, never store it in plain text, you have to use a strong algorithm to encrypt the important data in your database, but note that this will affect the performance of the application because the web application will have to do some calculations to encrypt the data before persistence and decrypt it after retrieval, also you will not be able to write queries that include any of the encrypted columns.

SQL Server 2016 has a great feature called Dynamic Data Masking, it allows you to mask the data stored in a column in some predefined formats, ex: Credit Card, Social Security Number or an email address, permissions can be granted for some users and only those users will be able to see the data unmasked.

To read more about the topic, please follow this link

IPSec

This feature blocks all incoming connections to a specific server on all ports and allows you to allow certain IP and certain port, so in this case, the database server will not allow any connections but from the web servers for your application

IPsec Configuration

SQL Server Transparent Data Encryption (TDE)

In case all the above precautions failed to protect your database, at least you can protect the data on rest, TDE allows you to encrypt the database’s data file itself so that no one can open it on another computer without a secret key, to encrypt your database file, you need a master key, certificate protected by this master key, a database encryption key which is protected by the certificate and finally set the database to use encryption.

To read more about it, following this link https://msdn.microsoft.com/en-us/library/bb934049.aspx

MVC 5 Dependency Injection

This is the seventh and last part of building line of business application using MVC 5, the remaining parts will be recorded as videos which will be more effective, you can read the previous parts through the following links

  1. Building a LOB application with MVC 5 – Part 0
  2. Building a LOB application with MVC 5 – Part 1
  3. Building a LOB application with MVC 5 – Part 2 – Models and Generic Repository
  4. Building a LOB application with MVC 5 – Part 3 – EntityFramework
  5. Building a LOB application with MVC 5 – Part 4 – Controllers, Routes and Areas
  6. Building a LOB application with MVC 5 – Part 5 – Views

In the previous part, we talked about Views, Layouts, View Engine and how to pass data from controllers to views and vice versa.

In this part we will talk about Dependency Injection (DI) and Inversion of Control (IoC).

What is DI?

You can find a lot of posts and tutorials about the definition of DI and IoC, so we are not going to detail it here, to summarize, as per our multi-tier architecture, our controllers will need a domain service which will need a repository and finally the repository will need a data context, if we let each object creates its dependencies, we will end up with a big mess, imagine if you tried to create a unit test to test the controller action logic, it will cause lead to the creation of the full chain starting from the controller down to the data context , although we only needed to test the controller logic.

To overcome this issue, all the dependencies must be injected into each depending object either through a constructor parameter or a public property, since the controller is the first object in our chain, we will start with it, but before we proceed, lets first examine how DI works in MVC.

DI in MVC 5

In the previous posts, we created a controller name ServiceTypesController under the Admin area, when we request the path /Admin/ServiceTypes, you will find an empty page as we don’t have any data created yet, but how did MVC created an object of ServiceTypesController?

MVC 5 depends on a ControllerFactory to create new controllers, simply, it instantiate a new controller object and in order for this to work, the controller must have a parameterless constructor because this is the way the default controller factory works.

Enable DI in MVC

Now, we need to inject a domain service into the ServiceTypesController controller, we will add the following code and try to run the application.

   public class ServiceTypesController : Controller
    {
        IService<ServiceType, int> _serviceTypeService;

        public ServiceTypesController(IService<ServiceType, int> serviceTypeService)
        {
            this._serviceTypeService = serviceTypeService;
        }

        // GET: Admin/ServiceTypes
        public ActionResult Index()
        {
            return View(_serviceTypeService.GetAll());
        }
    }

As you can see, our constructor now has a new parameter of type IService<ServiceType, int>, this is the generic domain service that we created and it is enough for all CRUD operations for any of our domain model classes, now try to build and run the application and you will get the following error.

Parameterless Contructor.png

Of course you can remove the parameter from the constructor but then you will have to instantiate the object itself, this means the controller class will have to know which concrete type it should create which is not its responsibility.

Custom Controller Factory

To overcome this issue, we will have to create a custom controller factory that knows how to instantiate an object that implement the IService<ServiceType,int>

To do that, create a folder named Factories under the web project and inside this folder create a class named DIControllerFactory, the code should look like the following

public class DIControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (controllerName.ToLower() == "servicetypes")
                return new ServiceTypesController(new BaseService<ServiceType, int>(new EFRepository<ServiceType, int>(new AppointmentManagerContext())));

            return base.CreateController(requestContext, controllerName);
        }
    }

As you can see, the method CreateController is responsible for creating the controller class and passing all the needed dependencies that the class needs, this will be easy if we have a controller or two, but when the number of controllers grow and the tree of dependencies grows, this will be a nightmare, have a look at the return statement in the above code, we instantiated 4 classes just to create the controller, this is where we need something else to manage that for us, something called the IoC Container.

There are a lot of IoC cotnainer available like, NInject, Microsoft Unity, StructureMap and many others, you can use any framework you like, in my case I will go with StructureMap

So, run the following NuGet Command to install StructureMap package, make sure it is installed in the MVC web project

Install-Package StructureMap

Now, it is time to setup the IoC container and let it know about our interfaces and its implementation, this will help when we ask it for an instance of the controller, then it will be able to resolve all the dependencies for it.

Setup StructureMap

Under App_Start, create a file called StructureMapConfig and add the following code

 public class StructureMapConfig
    {
        public static Container Container;

       public static IContainer Config()
        {
            Container = new Container();

            Container.Configure(c =>
            {
                c.Scan(s =>
                {
                    s.TheCallingAssembly();
                    s.WithDefaultConventions();
                });

                c.For(typeof(IService<,>)).Use(typeof(BaseService<,>));
                c.For(typeof(IRepository<,>)).Use(typeof(EFRepository<,>));
                c.For<ServiceTypesController>();
                c.For<DbContext>().Use<AppointmentManagerContext>();
            });

            return Container;
        }
    }

In the Config method, we created a container that will hold the information about the different interfaces and its implementation, notice that we registered all teh types for the IService and IRepository with only one call, this is why we use typeof(IService<,>), this will enable StructureMap to return any instance requested with the IService, for ex: IService<Appointment,int>, so you don’t have to register all the different combinations.

Call the Config method in the method Application_Start in the file Global.asax.cs

Now, back to the DIControllerFactory class, replace the code with the one below.

public class DIControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (controllerName.ToLower() == "servicetypes")
            {
                return StructureMapConfig.Container.GetInstance<ServiceTypesController>();
            }

            return base.CreateController(requestContext, controllerName);
        }
    }

The difference is huge, only one line to build the object instead of creating 4 objects, but still we have to know the controller name and figure out the type, of course we can append the namespace to the controller name and build the controller type name but this won’t be neat.

MVC Dependency Rresolver

MVC Comes with a dependency resolver that can be replaced by calling the following line at the application start.

 DependencyResolver.SetResolver(new CustomDependencyResolver());

MVC asks the default depdnency resolver to create a new object/service that it may need, if we managed to inject our own depdenecy resolver, then all the controllers will be created automatically without the need for a controller factory, to do that, create a class called StructureMapDependencyResolver under the Factories folder, add the following code to it.

 public class StructureMapDependencyResolver : IDependencyResolver
    {
        private static IContainer _container;

        public StructureMapDependencyResolver(IContainer container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            if (serviceType == null)
                return null;

            try
            {
                return serviceType.IsAbstract || serviceType.IsInterface
                         ? _container.TryGetInstance(serviceType)
                         : _container.GetInstance(serviceType);
            }
            catch
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _container.GetAllInstances(serviceType).Cast<object>();
        }
    }

The class implements two methods, the GetService and GetServices,these methods are use to return instances for services that MVC uses, such as IControllerFactory, IControllerActivator, so this class is the top level for all teh DI work in MVC, the controller Factory class was just a small part of it.

Now update the code in the Application_Start method to register the new dependency resolver as below

 public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            StructureMapConfig.Config();

            //ControllerBuilder.Current.SetControllerFactory(typeof(DIControllerFactory));
            DependencyResolver.SetResolver(new StructureMapDependencyResolver(StructureMapConfig.Container));

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

Notice the first line of the Configure block, it scans the current assembly to find any classes and interfaces and it does what with the default conventions as instructed by teh second line, this will make StructureMap to resolve automatically any reference to an interface that has a name like IService with a class that implements it with a name like Service

If you run the application now, it will work fine and all dependencies will be resolved automatically.

To conclude, always develop against an interface and leave the resolving of the actual implementation to an IoC container which as you can see, it is very easy to setup with MVC 5.

I hope this post was useful, if you have any questions, please leave a comment and you can get the code from the GitHub repository https://github.com/haitham-shaddad/AppointmentManager

Using GenFu to fill your database with dummy data

When you deliver a training or present a session or even start a new project, you want some test data pre-filled in your application instead of having to start with a fresh empty database.

Sometimes you don’t even need a database, you just want to display a list of customers in a grid to show your audience something, so, lets assume you have a Customer class that has the following definition

public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Genger { get; set; }
        public string PhoneNumber { get; set; }
        public string Address { get; set; }
        public DateTime BirthDate { get; set; }
    }

You would normally do the following in your code:

 public ActionResult Index()
        {
            var listOfCustomers = new List<Customer>();

            listOfCustomers.Add(new Customer { Id = 1, FirstName = "John", LastName = "Smith", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });
            listOfCustomers.Add(new Customer { Id = 1, FirstName = "Mark", LastName = "Johnson", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });
            listOfCustomers.Add(new Customer { Id = 1, FirstName = "Jackson", LastName = "Clark", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });
            listOfCustomers.Add(new Customer { Id = 1, FirstName = "Emillia", LastName = "Smith", Address = "Someaddress", BirthDate = DateTime.Now.Subtract(TimeSpan.FromDays(9000)) });

            return View(listOfCustomers);
        }

And the results would be:

list of customers

Seems good but not very satisfying and requires a lot of work specially if you want to show a lot of records to have paging for example.

GenFu is a very exciting library that can save you all this time, it uses code to generate real-time person information including names, address, birth date  and a lot more.

To use GenFu, all you have to do is to install its package using NuGet package manager, so  from VS, select tools -> NuGet Package Manager -> Package Manager Console and type the following command

install-package GenFu

Then replace the code written above to create list of customers with the following code:

  public ActionResult Index()
        {
            var listOfCustomers = A.ListOf<Customer>(20);

            return View(listOfCustomers);
        }

With just one line of code, it will create a 20 records with real data, and the results will be like this:

list of customers with genfu.PNG

 

To use GenFu to pre fill your database with some records, you can add the same line of code inside the Seed method in your Migration class, just like below

 
 internal sealed class Configuration : DbMigrationsConfiguration<GenFuDemo.Models.CustomersContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(GenFuDemo.Models.CustomersContext context)
        {
            context.Customers.AddOrUpdate(c => c.FirstName, A.ListOf<Customer>(20).ToArray());
        }
    }

This method will run when you run the update-database command and the data will be inserted into the Customer table

To read more about GenFu, you can visit its GitHub repository, it offers more features like customizing the way it generates or giving hints about some properties that it may not understand, for ex: if you have a property named NightNumber, which is a phone number, in this case you can instruct GenFu using its Fluent APIs to generate phone numbers for the property NightNumber

Building a LOB application with MVC 5 – Part 5 – Views

This is the sixth part of building line of business application using MVC 5, you can read the previous parts through the following links

  1. Building a LOB application with MVC 5 – Part 0
  2. Building a LOB application with MVC 5 – Part 1
  3. Building a LOB application with MVC 5 – Part 2 – Models and Generic Repository
  4. Building a LOB application with MVC 5 – Part 3 – EntityFramework
  5. Building a LOB application with MVC 5 – Part 4 – Controllers, Routes and Areas

In the previous part, we introduced controllers, routes and areas and we created the needed controllers and areas.

In this part, we will introduce views, so by the end of this post, we will finally have something that we can see.

What are Views?

We talked about the M and C, so we have the V from MVC remaining, in web forms, we mainly have the logic and view in one place (aspx), but in MVC, the presentation of the your data is the responsibility of the View, your controller intercept the request, call the business logic, and select how it wants to display the data.

You can display it as a text, Image, Chart, HTML or a downloadable file, in web forms you would have to create a separate web form for each view, but in MVC, you only have to duplicate the view part.

So, for now, lets just say that Views are this pieces that we see the system through it, it used to display the  information passed to it from the controller to the users and capture information from the users and forward it to the controller for updates

What is View Engine?

When MVC was released, the views were aspx pages and you had to write these annoying opening and closing tags from web forms era, but later you had the option to either use web forms rendering or the new views engine called Razor.

Razor is much more clean way of writing your views, basically it is all HTML unless you started with @ symbol, this is where the compiler assumes that you want to have a server side code

The View Engine is responsible for translating the written code either in aspx or Razor syntax and produce the final HTML, you can access the list of installed view engines by calling the  ViewEngines.Engines property, you can also add a new custom engine to this list by implementing the interface IViewEngine.

As you can see below, MVC 5 is shipped with 2 view engines

  1. WebFormViewEngine which renders the ASPX pages into HTML
  2. RazorViewEngine which renders the .cshtml files used in razor to HTML

view engines.PNG

When you expand the RazorViewEngine, you will see the following:

razor view engine details.PNG

As you can see above and as we stated in previous posts, MVC uses conventions over configuration, so by default the controller action will search for a view with the same action name inside a folder with the same controller name without the word Controller inside the Views folder, you can change these conventions by editing the corresponding property in the view engine and make sure to add this code in the Global.asax to make sure it is executed first thing when the application starts.

Layout Page (Master Page)

MVC has the same concept of Master page in web forms, only it is called Layout page here, by default the layout is set for any view unless you set the property Layout to null as below

layout null

if you didn’t do that, then the view will inherit the default Layout which is by convention again resides in Views\Shared\_Layout.cshtml

You can have more than one layout in your project, and you can set the layout for the view by setting the Layout property to the custom layout path, ex:


Layout = "~/Views/Shared/_CustomLayoutPage.cshtml";

Razor Syntax

Razor syntax is very similar to normal HTML unless when it starts with @ symbol, to have more details about it, please read more from microsoft site Razor Syntax

Passing data from Controllers to views

Since the view will be displaying data to the end users, we nee to pass this data from the controllers into the view, this happens in 2 ways

Strongly Typed Views

With strongly typed views, the view knows what is the data type of the model and you can reference the properties of the model inside your view code by using the Model property, visual studio supports  intellisense for this.

you can set the model type for the view by adding the following lines at the begenning of the view

@model AppointmentManager.Web.Models.AddPhoneNumberViewModel

To see it in action, you can open the file \Views\Manage\AddPhoneNumber.cshtml and examine the code

You can pass the data from your action to the view by adding the model object into the View method as below, if you used View() without any value and tried to access the Model  object inside the view, it will throw a null exception

pass model to view.PNG

Weakly Typed Views

In this type, you don’t specify the type of the model, you just pass the data you need to the view using 3 predefined properties:

  1. ViewBag, this is a dynamic object, so you can simply write ViewBag.Message = “Hello” in your action and in the view you can read it by adding @ViewBag.Message, the ViewBag variables are available only for the current view, so if you have an action called Index and you set a message variable inside it, you can access it only in the Index view, if you navigated to another action, then you can’t access it from there
  2. ViewData, this is the same as the ViewBag except it is a dictionay, so to add a key to it from your controller you either use ViewData.Add(“Key”,”Value”), or you can simply write ViewData[“Key”]=”value” and in your view just write @ViewData[“Key”]
  3. TempData, this is the same as teh ViewBag except that its lifecycle is a little bit longer, you can access it from the next action, so if you set the value of a variable called Message in your Create action that is called when the user post a form then you redirected to the Index action, you can then call teh Message variable from the Index action, this can be used to show a confirmation message when the user is redirected fom a page to another, note that after the redirection, the variable will be lost, so you can’t use it again.

Create Views

To create a view, you can go select the folder inside the Views folder where you want to add your view, right click and select Add -> View

Or you can go to your controller, put the cursor inside the action that you wants to generate view for it, and right click then select Add View.

Lets do that together.

Expand Areas, then Admin, right click Controllers and add an Empty Controller named ServiceTypes, this will be used to administer service types.

Add a project reference to the following projects inside the web project

  1. AppointmentManager.Models
  2. AppointmentManager.Repository
  3. AppointmentManager.Repository.EntityFramework

Right Click inside the Index action and choose Add View, leave the view name as is to avoid writing the name explicitly inside the action, choose the template as List, this will create a listing page, you can find the rest of templates for CRUD operations, select the model class that VS will use to generate the view using scaffolding technique, you can choose the Layout page then click Add

create view
Once done, the generated view file will be opened in VS and you can inspect the code, the first thing you will notice is the word @Html is mentioned a lot

HTML Helpers

If you have a form that accepts a username and password, you can write it as below

<input type="text" name="username" id="username" value="" />
<input type="password" name="password" id="password" value="" />

And if the model property was changed then you have to revist your HTML and update it to be the same as your model, also this is a lot of code to be written, so MVC offrers HTML helpers to save your time, the above code can be replaced by:

 @Html.TextBoxFor(m => m.Email)
 @Html.LabelFor(m => m.Password)

The above code will generate the same code and you can add more properties like css classes and other attributes.

To read more about HTML helpers and how you can create your own helpers, please visit this link

 

Model Binding

Now, the user browsed to your application, clicked register, and he is redirected now to the /Account/Register which means the account controller and register action, we have a register view which draws some input fields to capture the user information, the user adds the required information and clicked Submit.

In web forms, we used to do a lot of person.Name = txtName.Text

But in MVC, we don’t have to do that as MVC does it for us using something called Model Binding

When your action accepts a parameter and the user submit an request to this action, MVC automatically create an instance of this object and start to fill its properties from the request body, query string, route values, all these sources called Value Providers, you can add a custom value provider by going through the following post

MVC fill the object properties with request parameters that has the same name, so, if you have a class called Customer, and inside it you have FirstName and LastName, then MVC inspect the request for a query string or form values with the same names.

If the default model binder doesn’t meet your expectations, you can create your own, to read more please see MVC Model Binders

Scaffolding

Remember when we added a view and chose the template type as List and the model type as ServiceType and suddenly we have a listing screen? this is called Scaffolding and it happens using T4 Templates that visual studio runs.

To customize these templates, you have to do the following:

  1. Open C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates
  2. Create a folder called CodeTemplates in the web project root directory
  3. Copy the template you want into this folder and customize it, ex: MvcControllerEmpty, open it and customize it the way you want.

After that, create a new item from this template by following the same normal procedure, Right Click the project file-> Add -> New

You will see the updates you made applied to the newly created file, VS is smart enough to override the template with the one in your project.

Annotations and Validations

HTML Helpers can use any annotation attributes defined for each class property and it will use it generate the correct input control and add the right validation.

Ex: When we add the Required, MaxLength and Display attribute to the Name property inside the Country class, it will generate an extra validation for the textbox generated in the view, it will make the field required and has a max length of 50 charactres, it will also change the label from Name to Country Name

annotation

Not only this, but it will also impact the EntityFramework code first, when you run the application, EF will compare the model with the database and finds that the Name property has been changed and ti will ask you to add another migration in order to mark the Name column as Required and has a max length of 50

The same will apply when the ViewState.IsValid property is called in the Controller Action, this will make your validation consistent from the UI layer up to the data access layer.

Imagine if you followed the first way of adding just plain HTML code like the example above, you would have to add all the validation yourself, but now HTML helpers removed all this burden

You can now go ahead and generate views and add annotations for all the entities and controllers, if you have any questions, please leave a commant

 

You can get the full source code from GitHub Repository https://github.com/haitham-shaddad/AppointmentManager