. The
with class
modal-dialog defines a modal using
modal-header, modal-content and
modal-footer. The modal footer contains a button which contains the
data-dismiss attribute. This enables the modal dialog to close when the button is clicked. The script will show the modal dialog when the
Show Modal button is clicked.
Click on the Show Modal button and a Modal box appears
The Close button here is used to close the modal dialog. Similarly you can write some code in the OK button too.
Hence in MVC 5, with native support of the popular Bootstrap JavaScript library, a developer has a wider range of multi-platform CSS and HTML5 options, than ever before.
Attribute based Routing
The beauty of MVC is in its routing feature. Routing is how ASP.NET MVC matches a URL to an action. In earlier versions of MVC, the routing expressions were provided in the Global.asax class in Application_start event. (Note: In MVC 4, a separate class of name RouteConfig is provided in the App_Start folder.) The route expression set in MVC 4 is similar to the following:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
In this code, the defaults are already set to Home controller and its Index action method. This means that when a new URI is requested through the browser addressbar, this expressions has to be re-generated for controller other than Home.
Why to use Attribute Routing?
In MVC 5, to have more control over the URIs of a Web application, we can implement the route definition along with the action methods in the controller class, using attributes. In other words, we use attributes to define routes. To enable attribute based routing, the RegisterRoutes method needs to be changed to the following:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Implementation of Attribute Routing
Step 1: Open Visual Studio 2013 and create a new MVC application, name it as ‘MVC5_Attributebased_Routing’. In the Models folder add a new class file, name it as ‘ModelRepository.cs’ and add the following classes in it:
using System.Collections.Generic;
namespace MVC5_Attributebased_Routing.Models
{
public class Customer
{
public int CustId { get; set; }
public string CustName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Email { get; set; }
public string ContactNo { get; set; }
}
public class CustomerDatabase : List
{
public CustomerDatabase()
{
Add(new Customer() { CustId = 1, CustName = "Amit", Address = "AP Road", City = "Pune", Email = "a.b@ab.com", ContactNo = "1234567" });
Add(new Customer() { CustId = 2, CustName = "Ajit", Address = "BP Road", City = "Yavatmal", Email = "b.b@ab.com", ContactNo = "2234567" });
Add(new Customer() { CustId = 3, CustName = "Abhijit", Address = "CP Road", City = "Nagupr", Email = "c.b@ab.com", ContactNo = "3234567" });
Add(new Customer() { CustId = 4, CustName = "Sumit", Address = "DP Road", City = "Pune", Email = "d.b@ab.com", ContactNo = "4234567" });
Add(new Customer() { CustId = 5, CustName = "Sujit", Address = "EP Road", City = "Yavatmal", Email = "e.b@ab.com", ContactNo = "5234567" });
Add(new Customer() { CustId = 6, CustName = "Rohit", Address = "FP Road", City = "Nagpur", Email = "f.b@ab.com", ContactNo = "6234567" });
Add(new Customer() { CustId = 7, CustName = "Mohit", Address = "GP Road", City = "Pune", Email = "g.b@ab.com", ContactNo = "7234567" });
Add(new Customer() { CustId = 8, CustName = "Ranjit", Address = "HP Road", City = "Yavatmal", Email = "h.b@ab.com", ContactNo = "8234567" });
Add(new Customer() { CustId = 9, CustName = "Kuljit", Address = "IP Road", City = "Nagpur", Email = "i.b@ab.com", ContactNo = "9234567" });
}
}
public class DataAccess
{
public List GetCustomers()
{
return new CustomerDatabase();
}
}
}
Step 2: Enable attribute based routing in the RouteConfig.cs class file as explained above.
Step 3: In the Controller folder, add a new controller with the name CustomerController. In this controller, add an action method with the name GetCustomerByCity:
public class CustomerController : Controller
{
DataAccess objDs;
public CustomerController()
{
objDs = new DataAccess();
}
//
// GET: /Customer/
public ActionResult Index()
{
return View();
}
///
///
[Route("Customers/{city}")]
public ActionResult GetCustomersByCity(string city)
{
var customers = from c in objDs.GetCustomers()
where c.City == city
select c;
return View(customers);
}
}
As you can see, an action method GetCustomersByCity is applied with the Route attribute and a routing expression as Customers/{city}
Step 4: Generate View for the above action method and run the application. In the URL, put the following address:
http://MyServer:6764/Customers/Pune
The routing expression Customers/Pune maps with Customers/{city} and the view will be as shown here:
Defining Optional parameter in the URI
The URI parameter can be made optional by adding a question mark (?) to the route parameter. An example of the action method with attribute routing and optional parameter is shown here:
///
///
[Route("Customers/All/{city?}")]
public ActionResult GetCustomers(string city)
{
//Check if the city is null or empty
//If the city value is entered the filter customers
//for that entered city
if(!string.IsNullOrEmpty(city))
{
var customers = from c in objDs.GetCustomers()
where c.City == city
select c;
return View(customers);
}
//else return all customers
return View(objDs.GetCustomers());
}
In the code we just saw, the GetCustomers action method is applied with an attributing routing as shown here: Customers/All/{city?}
Here the {city?} parameter with question mark is optional. After running the application, if the URL is entered as http://localhost:25418/Customers/All then all Customers will be displayed.
However if the URL is entered as http://localhost:25418/Customers/All/Nagpur then all customers only in Nagpur city will be displayed.
Defining the Default value for the URI Parameter
The default value for the URI parameter can be set using parameter=value. Here’s an example:
///
///
[Route("Customers/City/{city=Nagpur}")]
public ActionResult GetCitywiseCustomers(string city)
{
var customers = from c in objDs.GetCustomers()
where c.City == city
select c;
return View(customers);
}
The action method is applied with the attribute routing: Customers/City/{city=Nagpur}
The city parameter is set to the default value of Nagpur. After running the application, if the URL is specified as: http://localhost:25418/Customers/City, then all customers from Nagpur city will be displayed.
However if the URL is entered as: http://localhost:25418/Customers/City/Yavatmal, then all Customers from the Yavatmal city will be displayed.
Applying with RoutePrefix
Generally if routes in the action methods of the controller start with the same prefix, then we can apply RoutePrefix on the controller class as shown here:
[RoutePrefix("Customers")]
public class CustomerController : Controller
{
[Route("{city}")]
public ActionResult GetCustomersByCity(string city)
{
//Your code here
}
[Route("All/{city?}")]
public ActionResult GetCustomers(string city)
{
//Your Code here
}
[Route("City/{city=Nagpur}")]
public ActionResult GetCitywiseCustomers(string city)
{
//Your code Here
}
}
And with that, we saw how the new Attribute Routing feature in ASP.NET MVC 5 provides more control over a URI in our web application.
Filter Overrides
In previous versions of MVC, in order to override a filter for a single action or controller, you had to apply a filter for each and every action and controller, one by one. MVC 5 introduces Filter Overrides which is defined in the documentation as "You can now override which filters apply to a given action method or controller, by specifying an override filter. Override filters specify a set of filter types that should not run for a given scope (action or controller). This allows you to add global filters, but then exclude some from specific actions or controllers".
Let’s understand this better with an example. We know that Action filters in ASP.NET MVC define execution behaviour of the controller and/or action. Typically an Action filters such as Authorize restricts the access of a controller or action method for an unauthenticated user.
Step 1: Open VS 2013 and create an ASP.NET MVC 5 application. To this application, add a class file with the name DataClasses.cs in the Models folder:
using System.Collections.Generic;
namespace MVC5_External_Auth.Models
{
public class Customer
{
public int CustId { get; set; }
public string CustName { get; set; }
}
public class CustomerList : List
{
public CustomerList()
{
Add(new Customer() { CustId = 1, CustName = "C1" });
Add(new Customer() { CustId = 2, CustName = "C2" });
}
}
public class DataAccess
{
List Customers;
public List GetCustomers()
{
return new CustomerList();
}
}
}
Step 2: Run the application. Create two users of name User1 and User 2 in the application using the Register View.
Step 3: Add a new empty controller in the controller folder with the name CustomerController. Add the following code in it:
[Authorize(Users = "user1")]
public class CustomerController : Controller
{
DataAccess objDs;
public CustomerController()
{
objDs = new DataAccess();
}
public ViewResult Details(int id)
{
var Cust = objDs.GetCustomers().Where(c => c.CustId == id).First();
return View(Cust);
}
//
// GET: /Customer/
public ActionResult Index()
{
var customers = objDs.GetCustomers();
return View(customers);
}
}
Note that the CustomerController is applied with Authorize filter and it is authorized for user1. This means that the controller can be accessed only by user1.
Step 4: Run the application, and in the URL type http://localhost:4403/Customer/Index. A login page will be displayed:
Here enter the user name as user1 and its associated password and the customer details will be displayed as shown:
In the above scenario, consider that you require authorization for all action methods in the CustomerController, except Details. This means that you have to apply the Authorize action filter on the CustomerController, but you want the Details action method to be an exception from using the Authorize filter. So to implement this, the Details method must override the filter applied on the Controller class. In ASP.NET MVC5, this is possible using OverrideAuthorization.
Step 5: In the application, add a new folder with the name CustomActionFilterOverride. Add a new class file of name CustomActionFilterOverride.cs. In the class, add the following code:
namespace MVC5_External_Auth.CustomActionFilterOverride
{
public class CustomOverrideAuthorizationAttribute : FilterAttribute, IOverrideFilter
{
public Type FiltersToOverride
{
get
{
return typeof(IAuthorizationFilter);
}
}
}
}
The class CustomOverrideAuthorizationAttribut is inherited from the FilterAttribute class and implements IOverrideFilter. This interface is used to define the filters applied on the controller. The property FiltersToOverride returns the IAuthorizationFilter type. This means that Authorize filter applied on the parent (controller or Global application class) will be overridden.
Step 6: Now apply this filter on the Details method of the controller class as shown here:
[CustomOverrideAuthorization]
public ViewResult Details(int id)
{
var Cust = objDs.GetCustomers().Where(c => c.CustId == id).First();
return View(Cust);
}
Now run the application, and in address bar type URL as http://localhost:4403/Customer/Details/1. The details for the customer with id as 1 will be displayed without redirecting us to the login page.
Please note that there is a bug in the Filter Override feature (https://aspnetwebstack.codeplex.com/workitem/1315) which has been fixed in ASP.NET MVC 5.1.
And with that, we wrap up this journey of some exciting and new features in ASP.NET MVC 5.
Conclusion:
ASP.NET MVC 5 is the latest version of the popular ASP.NET MVC technology that enables you to build dynamic websites using the Model-View-Controller technology, with an emphasis on a clean architecture, test-driven development and extensibility. This article gave you a quick overview of what's new in ASP.NET MVC version 5 and how best to apply these new features in your projects.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @
maheshdotnet or connect with him on
LinkedIn