All posts by Thiyagu

Donut Caching with Asp.Net MVC

Donut caching used to cache an entire web page except for one or more small portion of the page. In other words, suppose we want to cache a maximum portion of the view except the minimum portion then we can finalize to use DonutCache. I know while start reading this, many questions will arise. Let us discuss this in “What is in Mind”  section.

What is in Mind?

Q1 : At meantime, we think what will  happen when we use Output Caching ?
The output cache will cache the entire web page.

Q2 : However, what can we do when we want to do the inverse of the Donut Caching?
we want to use Donut hole cache instead of the DonutCache to cache the small portion of the view instead of maximum portion (inverse of DonutCache)

When to use Donut Cache?

Let we assume, having a web site which contains the home page with displaying login user name (small portion will be in dynamic) , and the remaining are static content.

Bad Approach:

If you want to cache users by using OutputCache with VaryByParam User ID, then the entire page will be cached every time for each user with a different user name. This is a bad approach because if 5000 users logged into the site, then there will be 5000 pages have been cached.

Good Approach :

In this scenario, we can use DonutCaching. It is useful when page containing most of the information is rarely Changed and few items changing dynamically( based on the parameter).

Including MVCDonutCaching using NuGet Package:

We can install MVCDonutCaching using NuGet or using Package Manager Console Go to Tools -> Library Package Manager -> Package Manager Console, then type the command “Install-package MvcDonutCaching” in the console as shown below image.

donut caching nuget - dotnet-helpers

Example :

Once we installed MvcDonutCaching package, we can add the DonutOutputCache attribute to the action or to the controller. Most of the parameter type of OutputCache attribute are also available in the DonutCache as shown below.

 

Controller :

From the below code, the static content in the Index view has cached for 30 seconds for all users expect dynamic content which is specified inside the view(ie., loading partial view).

public class DonutCacheController : Controller
 {
 [DonutOutputCache(Duration = 30)]
 public ActionResult Index()
 {
 ViewBag.CurrentDataTimeMessage = DateTime.Now.ToString();
 return View();
 }
 public ActionResult LoadUserDetail()
 {
 ViewBag.CurrentDataTimeMessage = DateTime.Now.ToString();
 return View();
 }
 }

Partial view :

Create LoadUserDetail.cshtml partial view and display the time from ViewBag. This partial view has been called in the DonutCache ->Index(view)

<h2> Message from Partial View - LoadUserDetail</h2> 
@ViewBag.CurrentDataTimeMessage<br>

View :

Here i am creating view with displaying current time and render LoadUserDetail partial view in it.

<h2>Index</h2>
<h2>Message from DonutCache -> Index </h2>
@ViewBag.CurrentDataTimeMessage
@Html.Action("LoadUserDetail", "DonutCache", new { name = "test" }, true)

OUTPUT :

While running the application, when we browse DonutCache controller then it will load the index view. If we refresh the page before 30 seconds, then index view will not refresh because it has been cached by the DonutCache (Time remain the same in the view, but time from the partial view had been updated for every refresh as shown below) . But LoadUserDetail has been refreshed every time because it hasn’t caught in cache as show below.

For more detail on caching and output caching.

Keep Happy Coding !!!

Enable Errors of Our ASP.NET MVC Views at Compile Time

In this post, we are going to discuss about how to capture “view” errors at compile time. By default, ASP.NET MVC projects won’t compile the views on the building process of our application. But don’t think Visual studio not handle this. As per below screen shot, it’s showing views error as warning in the Error List window, but we won’t consider the warning while running the application. 

All things are handling her. But many of us really won’t check this warning, as shown above. What we can do here is a fairly simple action to get this blow up on compile time. Let we discuss details about this.

STEP 1:

Right-click on your project’s  solution explorer and click Unload Project as shown in below image

STEP 2: After project unloaded,

After the project unloaded, right-click the project and choose Edit “Your project name” (. csproj) and MvcBuildViews node from false to true (for handlingthe error in compile time) and save the file.

STEP 3:

Reload the project and build the solution. Now we can see the “0 succeed , 1 failed” in the output window.

Handle multiple submit buttons on an ASP.NET MVC

In this post, we will discuss how to handle the multiple submit button event in ASP .NET MVC without using javascript. The form could contain more than one submit button issuing a form post to a different controller action. We can achieve this situation by using ActionNameSelectorAttribute.

Implementing View :

<div>
<form action="" method="post">
<input type="submit" value="Save" name="action:Save" />
<input type="submit" value="Edit" name="action:Edit" />
</form>
</div>

Implement ActionNameSelectorAttribute

Here i am creating a class that inherits from ActionMethodSelectorAttribute. The first parameter is ControllerContext, this parameter will contain the FormValueProvider object. This contains values posted in the form in a NameValueCollection object. Using this parameter we can identify which button clicked/submitted in the form.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class HandleMultipleSubmitAttribute : ActionNameSelectorAttribute { public string FormKey { get; set; } public string FormName { get; set; } public override bool IsValidName(ControllerContext ctrContext, string actionName, MethodInfo methodInfo) { var isValidEvent = false; var keyValue = string.Format("{0}:{1}", FormKey, FormName); var value = ctrContext.Controller.ValueProvider.GetValue(keyValue); if (value != null) { ctrContext.Controller.ControllerContext.RouteData.Values[FormKey] = FormName; isValidEvent = true; } return isValidEvent; } }

Action Method

The next step is to create two action methods, which containing the Save and Edit functionality. To ensure that either of these actions will be invoked, I’m going to decorate them with the HandleMultipleSubmit attribute class.

public class MultipleSubmitController : Controller
{
[HttpPost]
[HandleMultipleSubmit(FormKey = "action", FormName = "Save")]
public ActionResult Save() 
{
return null;
}
[HttpPost]
[HandleMultipleSubmit(FormKey = "action", FormName = "Edit")]
public ActionResult Edit( )
{ return null; }
}

Execution :

  • After Save/Edit button is clicked, the input named Save will be injected into the form and that will be sent in the forms collection. Before executing the action method, attribute will be executed and it will check the values in the FormValueProvider and find the match value specified on the attribute.
  • If posted form contains a value that matches the value in HandleMultipleSubmit then IsValidForRequest method will returns true, so then it will start executing the proper action.

 

Keep Cool Coding…

 

Output Caching Attribute in ASP.NET MVC

The main goal of this post is to explain how we can improve the performance of an ASP.NET MVC web application by using the advantage of the output cache. The output cache enables us to cache the information which is returned by an action. So it will not need to re-generated the action content every when the same action method is invoked. Caching play the main part of the web application, as it improves the performance and load on the server. ASP.NET MVC make is, very simply by adding the OutputCache attribute on the action method to our application.

Why Caching is needed ?

Lest we think of this, if we need to display a record from the database in a view. So if a user tries to view the same page repeatedly, then each and every time that a user invokes the controller action so it hit the database to fetch the record and returns to the user.

By using output cache, we can avoid executing a database every time when user request the same controller action. At that time, it did retrieve the content from the cache instead of fetch them from the controller action. So the main advantage has enabled us to avoid server overload that is performing redundant work on the server.

Required Namespace :

For configuring the cache location, we need to include the below namespace in our controller.
namespace : System.Web.UI

Set Cache Location

We can control the caching location by using the location parameter like following values Any, Client, Downstream, None, Server, or ServerAndClient. By default, the parameter will have the Any parameter for caching the content.

OutputCache parameters

Enabling Output Caching

We can enable output caching by adding an OutputCache attribute to either an action or an entire controller class.

Controller Level Caching

Here in controller level caching, it’s cached all the action content under the control.

[OutputCache(Duration = 10, VaryByParam = “none” , Location = OutputCacheLocation.Client )] public class OutputCacheController : Controller { public ActionResult Index() { return View(); } }

 Action Level Caching

In action level caching, the content has cached alone for that particular action method.

[OutputCache(Duration = 10, VaryByParam = “none” , Location = OutputCacheLocation.Client )] public ActionResult Index() { ViewBag.CurrentDataTimeMessage = DateTime.Now.ToString(); return View(); }

Here I had specified the cache duration as 10 seconds, so the cache content will be maintained up to duration which we specified in the Duration parameter. When we run the application, the Date Time will not change/update up to 10 seconds because it’s already cached from the action and maintain up to 10 seconds. So it won’t hit the action method.

 

Keep Cool Coding…

 

ASP.Net MVC Request Life Cycle / MVC Application Execution Process

Introduction

In this post, we are going to discuss about the each step in the life of an ASP.NET MVC from request to response. Here we will walk through the steps involved in a life of ASP.NET MVC request.There are mainly five main steps that happen when you make a request from an ASP.NET MVC website.

Flow Of MVC Request :

Step 1 – Request

Receive first request for the application. In the Global.asax file, route objects are added to the Route table object. 

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

Step 2 – The Route 

The entry point for every MVC Application begins with Routing. After the application receives the request from the user, it uses URL Routing Module to handle the request. The RouteTable maps URLs to handlers.  Basically routing is a pattern matching system that matches the request’s URL against the URL patterns which is present in the Route Table. The Routing engine redirect the request to the corresponding IRouteHandler when the match found in the pattern. If corresponding requested URL not found in route table then it will return a 404 HTTP status code.

Step 3 – The MvcHandler Executes

It is the responsibility of the RouteHandler to determine the HTTP handler that will serve the request, by looking at the received RequestContext. The RouteHandler object creates an instance of the MvcHandler class and passes the RequestContext instance to the handler.

RequestContext instance is used to identify the IControllerFactory object to create the controller instance.
The MvcHandler method calls the controller’s Execute method.

Step 4 – The Controller Executes

The controller determines which action method to execute. MvcHandler uses IControllerFactory instance and to get IController object. Mvc controllers implement IController interface to execute the method which actually execute your action method.

Step 5 – Action Invoked

After controller gets instantiated ActionInvoker will determines which Action method need to execute. ActionNameSelectorAttribute and ActionMethodSelectorAttribute methods used to select action method. The action method receives user input then executes the result and returning a result type to view. 

The result type can be ViewResult, RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, FileResult, and EmptyResult. At last the view has been render to the browser as response.

Keep Cool Coding…

 

Creating a custom route handler in ASP.NET MVC

ASP .NET MVC has provide more flexible options to extend the functionality to make a programmer easy and smooth.  Custom route handlers are one of them.

How MVC Routing Works?

URLs are very important part of our web based application. Routing will decide which handler will be responsible to handle the incoming request from the browser and responsible  for match the incoming URL with route table to proceed. Let we understand more on routing  here.

Why and Where We Need a Custom Route Handler?

Scenario 1: If we decide to process some data before creating the instance of the controller.

Scenario 2: It will helpful when we need to redirect the user to any external page or shortened the long URLs or making the URLs more user-friendly.

What is Route Handlers ?

From MSDN – ” MvcRouteHandler. This class implements IRouteHandler, therefore it can integrate with ASP.NET routing. The MvcRouteHandler class associates the route with an MvcHandler instance. A MvcRouteHandler instance is registered with routing when you use the MapRoutemethod. When the MvcRouteHandler class is invoked, the class generates an MvcHandler instance using the current RequestContextinstance. It then delegates control to the new MvcHandler instance.”

In simple, it is a class that implements IRouteHandler interface, which provides route handler class instance to process the request. IRouteHandler has only one method that is GetHttpHandler().

Creating A Custom Route Handler

Create CustomeRouteHandler.cs file in Utility folder (It created for placing common functionality) and implement IRouteHandler interface as shown below. IRouteHandler interface contains GetHttpHandler method that returns IHttpHandler

using System.Web;
using System.Web.Routing;
namespace Dotnet_helpers.Utility
{
    public class CustomRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new CustomHttpHandler();
        }
    }
    public class CustomHttpHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        public void ProcessRequest(HttpContext context)
        {
            context.Response.Redirect("https://www.dotnet-helpers.com", true);
        }
    }
}

From the above code, we have returned CustomHttpHandler class. CustomHttpHandleris class which implements two methods IsReusable and ProcessRequest of IHttpHandler.  IsReusable simply instruct the MVC framework whether this instance of IHttpHandler is reusable. The ProcessRequest method in this case simply redirects the user to https://www.dotnet-helpers.com website. 

After defining the MyCustomRouteHandler, we need to add it to the RouteCollection under App_Start -> RouteConfig.cs

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new Route("NonAdminUser", new dotnet_helpers.Utility.CustomRouteHandler()));
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

Run the application , when we hit the URL  http://localhost:8080/NonAdminUser then it will redirect to the https://www.dotnet-helpers.com.

Keep cool coding…

Create Sessionless Controller using SessionState attribute in MVC

The SessionState Attribute helps us to control the session state behavior in ASP.NET MVC. Using properties like state Default/disable/read only, we can control the behavior for the controller. Sessions attribute is a class level so we can only apply at the controller not on action.

Problem with SessionState attribute

We can control session state behavior using Session State attribute but the main drawback is, this can only be applied at the controller level not at the action level. So all action methods inside the controller have the same session state behavior. In some scenario, the action methods of the controller need not to use session behavior. !!

How to over come ?

Bad Practice:

In this scenario, we will think to create a different controller and move all the action methods based on the same behavior. But this is not a good practice.

Good Practice:

Instead of moving an action method to the other controller, we can create a custom action attribute that overwrites the behavior of the session state for the specific action method.

Session State Behaviour:

The SessionState attribute in MVC provide control the behavior of the session state by accessing the value of the behavior property.

SessionStateBehavior.Default– It is a default logic, used to determine the session state behavior for the request.
SessionStateBehavior.Required – Here read-write session state behaviour is enabled.
SessionStateBehavior.ReadOnly – Read only session state is enabled.
SessionStateBehavior.Disabled – Session state is not enabled for processing (session state will be disabled).

Example code

[SessionState(SessionStateBehavior.Disabled)] public class SessionlessController : Controller { // GET: Sessionless public ActionResult Index() { Session["sessionStr"] = DateTime.Now; return View(); } }

OUTPUT :

The following “NullReferenceException” error occur when try to access “Index” action method.

Note:

  • In MVC3 (Beta) SessionState() attribute was refereed as ControllerSessionState()

 

Keep Cool Coding…

Dynamically Adding meta tags in asp.net mvc

In this blog post, I am going to explain how we can create a meta tag dynamically using Asp .Net MVC. We are aware that Meta tag plays very important roles in Search engine optimization. It is necessary to add meta tag for best ranking on search engines. Let we discuss with simple example.

Controller :

From the below code, BindMetaTag method which will return a string with meta tags. This method will create a meta tag string and it will return to the calling method. Here I am using view bag to store the dynamically created meta tag string for binding in the view.

public ActionResult Index()
{
ViewBag.LoadMetaTag = BindMetaTag();
return View();
}
public string BindMetaTag()
{
System.Text.StringBuilder strDynamicMetaTag = new System.Text.StringBuilder();
strDynamicMetaTag.AppendFormat(@"<meta content='{0}' name='Keywords'/>", "Dotnet-helpers");
strDynamicMetaTag.AppendFormat(@"<meta content='{0}' name='Descption'/>", "creating meta tags dynamically in"+ " asp.net mvc by dotnet-helpers.com");
return strDynamicMetaTag.ToString();
}

View :

Here in the below code, @Html.Raw method is used to embed meta tag in _layout.cshtml page. This HTML.Raw method will embed output to head tag section without encoding html.

@Html.Raw(ViewBag.LoadMetaTag)
<h2>Dynamically creating meta tags in asp.net mvc</h2>

OutPut :

Now once you run your application and click on view source you will find meta tag for home page as show below.

 

Keep Cool Coding….

Understanding Attribute Routing in MVC 5

In this post we are going to discuss about the new feature of routing in ASP.NET MVC5 known as Attribute Routing. Attributes Routing are used to define the routes in controller/action directly. The main purpose of attribute routing is to control the URLs by define directly on action and the controller in the application.

When to use?

In some scenario, convention-based routing is complex to support certain URL patterns. This can achieve easily by using Attribute Routing.

For example, if user have ordering books based on authors, items based on color and so on. Then URL will look like /user/1/orders, this type of URL is difficult to match using the convention-based routing. But it can be achieve by convention-based routing but it will take our extra effort for this. By using attribute routing, it can be done much easier, by defining on the controller/action.

Defining Attribute Routing in ASP.NET MVC

Attribute routing can be define in two ways

  • Controller level Attribute Routing
  • Action level Attribute Routing

Register Attribute Routing

Attribute Routing use RoutePrefix and Route attributes to achieve the routing. The RoutePrefix attribute is used on the controller to specify a route prefix for all actions inside the specific controller. The Route attribute used on action method to allows us to specify the route on the action method. Before that we need to register attribute routing in the RouteConfig.cs using routes.MapMvcAttributeRoutes().

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
//Register Attribute Based Routing
routes.MapMvcAttributeRoutes();
//convention-based routing
routes.MapRoute(
name: “Default”,
url: “{controller}/{action}/{id}”,
defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
);
}

Controller level Attribute Routing : [RoutePrefix()]

Controller level attribute will apply to all actions which is present within the controller unless a specific attribute route is added to an action.

[RoutePrefix(“dotnet-helpers”)]
[Route(“{action=index}”)] //default action
public class HomeController : Controller
{
//route: /dotnet-helpers/Index
public ActionResult Index()
{
return View();
}
}

OUTPUT :

Action level Attribute Routing : [Route()]

Action level Attribute routing will be for specific action with in the controller.

[RoutePrefix(“dotnet-helpers”)]
[Route(“{action=index}”)]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[Route(“About”)] 
public ActionResult Contact()
{
ViewBag.Message = “Your contact page.”;
return View();
}
}

OUTPUT :

How to use Attribute Route in Area : [RouteArea()]

RouteArea attribute is used to define attribute routing for a controller which is present within Area.

[RouteArea(“SuperAdmin”)]
[RoutePrefix(“dotnet-helpers”)]
[Route(“{action=index}”)]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[Route(“About”)] //default action
public ActionResult Contact()
{
ViewBag.Message = “Your contact page.”;
return View();
}
}

Note :

  • routes.MapMvcAttributeRoutes() : It will map all the routes that is defined as attributes.
  • The main advantage of using Attribute routing is the flexibility  that give us the excellent control over URL.

Retrieve Views from Different Folders in MVC

In this post we will discuss how to use the view which is placed inside another folder in our application and
how to use that view in our controller. In simple, if we place the view inside the folder views -> Users -> Admin -> index.cshtml instead of views -> Users -> index.cshtml.

When to use?

In the below image, all the views has been placed under Views -> Users. Here we can see there is no structured hierarchy of the views. So we are creating a separate folder for Admin, Non-Admin, Super Admin to create a view based on their role.

Creating View in different folder :

EG :  views -> Users -> Admin -> index.cshtml)

For the default view location the action will be like below

public ActionResult Admin()
{
return View();
}
public ActionResult NonAdmin()
{
return View();
}
public ActionResult SuperAdmin()
{
return View();
}

For the customized view location, the action will be look below. We can’t redirect particular view from here.

public ActionResult Admin()
{
return View(“Admin/AdminHomePage”);
}
public ActionResult NonAdmin()
{
return View(“NonAdmin/NonAdminHomePage”);
}
public ActionResult SuperAdmin()
{
return View(“SuperAdmin/SuperAdminHomePage”);
}

Creating Controller based on the Customized View Location :

Here it can’t redirect to the particular view location by right click -> Go To View option. It will show “Unable to find a matching view.”

 

Keep Cool Coding !!!