Sunday, 23 December 2018

Useful attributes in MVC


  • StringLength Attribute :
Used to enforce minimum and maximum length of characters that are allowed in a data field. Let's understand this with an example. 

Namespace: 

System.ComponentModel.DataAnnotations

    [MetadataType(typeof(EmployeeMetaData))]
    public partial class Employee
    {
 
    }
 
    public class EmployeeMetaData
    {
        [StringLength (10,MinimumLength =5)]
        public string Name { get; set; }
    }

  • Range Attribute
Range attribute is used to validate DateTime fields, numeric fields.
    [MetadataType(typeof(EmployeeMetaData))]
    public partial class Employee
    {
 
    }
 
    public class EmployeeMetaData
    {
        [StringLength (10,MinimumLength =5)]
        public string Name { get; set; }
 
        [Range(1,100)]
        public string Age { get; set; }

        [Range(typeof(DateTime),"01/01/2010","01/01/2018")]
        public DateTime? DateofJoin { get; set; }
    }

  • Regular Expression Attribute
Regular expression attribute is used for pattern matching validation.
   [MetadataType(typeof(EmployeeMetaData))]
   public partial class Employee
   {
 
   }
 
   public class EmployeeMetaData
   {
       [RegularExpression(@"^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$")]
       [StringLength (10,MinimumLength =5)]
       public string Name { get; set; }
   }

Or

        [RegularExpression(@"^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$",ErrorMessage = "Only upper and lower case alphabets are allowed")]
        [StringLength (10,MinimumLength =5)]
        public string Name { get; set; }
   
  • Compare Attribute
Compare attribute is used to compare 2 properties of a model. 
   [MetadataType(typeof(EmployeeMetaData))]
   public partial class Employee
   {
     [Compare("Name")]
     public string confirmName { get; set; }
   }
 
   public class EmployeeMetaData
   {
       [RegularExpression(@"^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$",ErrorMessage = "Only upper and lower case alphabets are allowed")]
       [StringLength (10,MinimumLength =5)]
 
       public string Name { get; set; }
   }

  • Required Attribute
This is used to enforce the property is required 
    [MetadataType(typeof(EmployeeMetaData))]
    public partial class Employee
    {
      
    }
 
    public class EmployeeMetaData
    {
        [Required]
        public string Name { get; set; }
 
        [Required]
        public string Designation { get; set; }
    }

  • Display Attribute
This is used to display change the caption (Overrides auto generated name)
[MetadataType(typeof(DepartmentMetaData))] public partial class Department { } public class DepartmentMetaData {     [Display(Name="Department Name")]     public string Name { get; set; } }
  • DisplayName Attribute
Namespace: using System.ComponentModel;

        [DisplayName("Employee Name")]
        public string Name { get; set; }

  • DispalyAttribute Attribute
       [DisplayAttribute(Name="Employee Name")]
       public string Name { get; set; }

  • DisplayFormat Attribute
 If gender is NULL, "Gender not specified" text will be displayed.

    [DisplayFormat(NullDisplayText = "Gender not specified")]
        public string Gender { get; set; }

  • ScaffoldColumn Attribute
If you don't want to display a column use ScaffoldColumn attribute. This only works when you use @Html.DisplayForModel() helper
        [ScaffoldColumn(false)]         public int? Salary { get; set; }

  • datatype Attribute

Used to specify specific data type in the model.
    [DataType(DataType.EmailAddress)]     public string EmailAddress { get; set; }
    [DataType(DataType.Currency)]     public int? Salary { get; set; }
    [DataType(DataType.Url)]     public string PersonalWebSite { get; set; }
    [DataType(DataType.Date)]     public DateTime? HireDate { get; set; }

Best practices for MVC application

  1. Use CDN
  2. Use both Client-side validation and server-side validation
  3. Use bundling to avoid repetitive call in each view
  4. Use minification for faster load
  5. Check Javascript enabled for the browser or not before loading the page.
  6. Use Partial views for developing reusable components
  7. Use the Razor View engine as it is very light and user-friendly
  8. Use validation summary to show all the errors in on go instead of showing each error separately.
  9. Remove all .pdb files while deploying the code.
  10. Use Release mode instead of Debug mode while deploying the code. It will automatically remove the .pdb files.
  11. Use Browser developer tool and fiddler or Postman like tools to debug the UI/View code.
  12. Use Glimpse like tools available in Nuget to debug the Server side code.
  13. Use strongly typed view
  14. Remove unused references from your code
  15. Use Areas to simplify your code modules
  16. Keep all business logic in models instead of View. Views should only respond to render the HTML page to the browser
  17. Do not mix up the unnecessary code in Controllers. It should only respond to render the different controllers and controller action method to render the appropriate view to the browser.
  18. Use _Layout view for a consistent look and fell through the application.
  19. Keep DisplayTemplates and Editor Templates code in Shared folder for reusability.
  20. Use centralized error handling logic.
  21. Remove/close unused connection which is open by using " Using" Statement.
  22. Use TempData for short-lived instances and use viewBag and ViewData for long-lived and large data.

Saturday, 22 December 2018

How to enable client side validation in asp.net MVC

To enable client side validation in MVC we need to enable ClientValidation and UnobtrusiveJavaScript in the web.config file as below.

<appSettings>
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

Once enabled in web.config we need to refer a set of.JS file in a proper sequence as they are interdependent. 

<script src="~/Scripts/jquery-3.0.0.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>

Else you can add these files in BundleConfig.cs file to avoid the repetition in each view where you want to enable client-side validation as below. With these changes, client-side validation will work. But if Javascript was disabled in your browser it will not work. So it is always suggested to check the browser if Javascript is enabled or not before loading the initial page or we can also apply both client-side validation and serverside validation in your application code.


        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));
 
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery.validate.min.js"));
 
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery.validate.unobtrusive.min.js"));
 
            bundles.Add(new ScriptBundle("~/bundles/jqueryui")
                        .Include("~/Scripts/jquery-ui-{version}.js"));
 
            bundles.Add(new StyleBundle("~/Content/jqueryui")
                            .Include("~/Content/themes/base/all.css"));
 
            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.validate*"));
 
            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));
 
            bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                      "~/Scripts/bootstrap.js"));
 
            bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css"));
        }



What is the use of Area in MVC

To make the modular design, Areas are used in MVC application. When we are working with large applications maintaining the business logic and UI is difficult when the application grows. To make it simple and maintainable Areas are used in MVC application.

When we add an Area it has its own Controler, Model, View, Routes and AreaRegistration.cs folder. We can add a meaningful area in the application and its related contents in that. So in long run, it will be easier to maintain and debug the application. AreaRegistration.cs file contains the code to register a route for the area.

When you add an Area it will add AreaRegistration.RegisterAllAreas() in Application_Start() method.

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

While accessing the areas you need to explicitly define the area name in the View.

@Html.ActionLink("Employee Area Home Page", "Index", "Home", new { area = "YourAreaName" }, null)


What are filters in ASP.NET MVC / Action Filters

Action Filters are the attributes that are applied to the Controller Class or Controller Action Method to add pre and post processing logic. When applied at the controller level, they are applicable for all actions within that controller and when applied on controller action method, they are applicable to that method only. All total action filters provide extra features to the controller class and its action methods.

Examples of few Action Filters are

Authorize: Provides windows and forms authentication
ChildActionOnly: Restricts action methods not to be accessed using URL
HandleError: Used to handle errors
OutputCache: Used to cache data or for partial page postback
RequireHttps: Enforces an HTTP request to pass HTTPS
ValidateInput: Enables and disable HTML encoding.
ValidateAntiForgeryToken: Restricts anti-forgery tokens in your application.

You can also create your own custom filters if filters provided by ASP.Net MVC will not full fill your requirement.

What is Bundling and Minification

Bundling and minification are two techniques you can use in ASP.NET 4.5 to improve request load time. Bundling and minification improve load time by reducing the number of requests to the server and reducing the size of requested assets (such as CSS and JavaScript.)

Bundling is a feature in ASP.NET 4.5 that makes it easy to combine or bundle multiple files into a single file. You can create CSS, JavaScript, and other bundles as single file. Fewer files means fewer HTTP requests and that can improve first page load performance.

JavaScript minification is the process of reducing the size of the JavaScript file, by removing comments, extra white spaces, new line characters and using shorter variable names.

Advantages of JavaScript minification: As the minified JavaScript files are very small, they will be downloaded much faster and consumes less bandwidth. Search engines like Google consider page load time as one of the parameters to rank the pages.

The downside of JavaScript minification is these are harder to read and debug. However, for development and debugging we can use non-minified versions. Just before deployment, minify and use the minified versions on the production environment. 

How to Preventing JavaScript Injection Attacks in MVC application / Cross-site scripting attack / XSS attack

It is a security vulnerability found in Web applications. XSS allows hackers to inject client-side script into Web pages, and later, if that web page is viewed by others, the stored script gets executed. The consequences of XSS may range from a petty nuisance like displaying an alert() box to a significant security risk, like stealing session cookies. 

In MVC [ValidateInput(true)] by default which restricts  and encodes all HTML. This is a security measure in place, to prevent XSS attack. But if for some reason, you want to disablHTMLml encoding you may decorate the Controller Class or Controler Action method [ValidateInput(false)]. At this moment your application is open for an XSS attack. So you need to carefully avoid this attack by designing your application.

You need to tell your application what and all are allowed to encode coming from the request URL.
Let say I want to accept only <b></b> and <u></u> tags. You can design your application 

[HttpPost]
// Input validation is disabled, so the users can submit HTML
[ValidateInput(false)]
public ActionResult Create(Comment comment)
{
    StringBuilder sbComments = new StringBuilder();
    
    // Encode the text that is coming from comments textbox
    sbComments.Append(HttpUtility.HtmlEncode(comment.Comments));
    
    // Only decode bold and underline tags
    sbComments.Replace("&lt;b&gt;", "<b>");
    sbComments.Replace("&lt;/b&gt;", "</b>");
    sbComments.Replace("&lt;u&gt;", "<u>");
    sbComments.Replace("&lt;/u&gt;", "</u>");
    comment.Comments = sbComments.ToString();

    // HTML encode the text that is coming from name textbox
    string strEncodedName = HttpUtility.HtmlEncode(comment.Name);
    comment.Name = strEncodedName;

    if (ModelState.IsValid)
    {
        db.Comments.AddObject(comment);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(comment);
}

Note: Read MSDN documentation on XSS and it's countermeasures. 

When to User Windows authentication over forms authentication.

When you are building an internal company website (an intranet site) and you want your users to be able to use their standard Windows usernames and passwords when accessing the website use Windows authentication.


If you are building an outwards facing website or Client Facing application where external users need to be authenticated by providing their username/password (an Internet website), use Forms authentication instead.

Authenticating Users with Windows Authentication while deploying an MVC application in production

For a production web application, on the hand, you use IIS as your web server. IIS supports several types of authentication including:

·       Basic Authentication – Defined as part of the HTTP 1.0 protocol. Sends usernames and passwords in clear text (Base64 encoded) across the Internet.
·       Digest Authentication – Sends a hash of a password, instead of the password itself, across the internet.
·       Integrated Windows (NTLM) Authentication – The best type of authentication to use in intranet environments using windows.
·       Certificate Authentication – Enables authentication using a client-side certificate. The certificate maps to a Windows user account.

You can use the Internet Information Services Manager to enable a particular type of authentication. Be aware that all types of authentication are not available in the case of every operating system. Furthermore, if you are using IIS 7.0, you need to enable the different types of Windows authentication before they appear in the Internet Information Services Manager. Open Control Panel, Programs, Programs and Features, Turn Windows features on or off and expand the Internet Information Services node. Select which type of Windows authentication you want to enable. Using Internet Information Services, you can enable or disable different types of authentication. For example, you may disable anonymous authentication and enable Integrated Windows (NTLM) authentication when using IIS.


After you enable Windows authentication, you can use the [Authorize] attribute to control access to controllers or controller actions. This attribute can be applied to an entire MVC controller or a particular controller action.

Authenticating Users with Windows Authentication while developing an MVC application

When you create a new ASP.NET MVC application, Windows authentication is not enabled by default. Forms authentication is the default authentication type enabled for MVC applications. You must enable Windows authentication by modifying your MVC application's web configuration (web.config) file. Find the <authentication> section and modify it to use Windows instead of Forms authentication.

<authentication mode="Windows">
 
</authentication>

When you enable Windows authentication, your web server becomes responsible for authenticating users. Typically, there are two different types of web servers that you use when creating and deploying an ASP.NET MVC application.

First, while developing an MVC application, you use the ASP.NET Development Web Server included with Visual Studio. By default, the ASP.NET Development Web Server executes all pages in the context of the current Windows account (whatever account you used to log into Windows).


The ASP.NET Development Web Server also supports NTLM authentication. You can enable NTLM authentication by right-clicking the name of your project in the Solution Explorer window and selecting Properties. Next, select the Web tab and check the NTLM checkbox. (There may be some minor differences as per the Visual Studio Installed in your local System)

Authenticating Users with Forms Authentication / Role Based Authentication / User Based Authentication

You can use [Authorize] attribute on Controller level or Action Method level to apply forms authentication. When it is applied on Controller level the entire Controller Class is restricted to anonymous users. When it is invoked it will prompt and ask you to validate by providing valid user and password.

When [Authorize] is applied at Action Method level, that method which is decorated with [Authorize] will be restricted to anonymous users and will prompt to enter valid user and password.

You can restrict the forms authentication user level and role level as well. Create some users and their roles.

Apply [Authorize(Users="AG Kumar")] attribute in Action Method. It will allow only the user “AG Kumar” to access that Action Method. Other users are not allowed to access this.

Apply [Authorize(Roles = "Administrators")] attribute in Action Method. It will allow those users who have “Administrators” role. Other roles are not allowed to access.

You can apply all the above on Controller Level or Action Method Level

Example:
namespace MyMvcApplication
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
 
        [Authorize]
        public ActionResult CompanySecrets()
        {
            return View();
        }
 
        [Authorize(Users="AG Kumar")]
        public ActionResult StephenSecrets()
        {
            return View();
        }
 
        [Authorize(Roles = "Administrators")]
        public ActionResult AdministratorSecrets()
        {
            return View();
        }
 
    }

}

ASP.NET MVC Execution Process / ASP.NET MVC Page Life Cycle

Requests to an ASP.NET MVC-based Web application first pass through the UrlRoutingModule object, which is an HTTP module. This module parses the request and performs route selection. The UrlRoutingModule object selects the first route object that matches the current request. If no routes match, the UrlRoutingModule object does nothing and lets the request fall back to the regular ASP.NET or IIS request processing.

First Request à UrlRoutingModule (HTTP Module ) à Check for the route à If found Route à Obtain the Route Handler (IRouteHandler) à Creates an IHttpHandler object and pass it to the IHttpContext object à MvcHandler will select the appropriate View to handle the request

Detail Explanation:
·       Receive the first request for the application
o   In the Global.asax file, Route objects are added to the RouteTable object.
·       Perform routing
o   The UrlRoutingModule module uses the first matching Route object in the RouteTable collection to create the RouteData object, which it then uses to create a RequestContext (IHttpContext) object.
·       Create MVC request handler
o   The MvcRouteHandler object creates an instance of the MvcHandler class and passes it the RequestContext instance.
·       Create a controller
o   The MvcHandler object uses the RequestContext instance to identify the IControllerFactory object (typically an instance of the DefaultControllerFactory class) to create the controller instance.
·       Execute controller - The MvcHandler instance calls the controller’s Execute method.
·       Invoke action
o   ControllerActionInvoker object that is associated with the controller determines which action method of the controller class to call, and then calls that method.
·       Execute result

  • Loads the appropriate View to the complete the request