Understanding Caching in Asp.Net MVC with example
Caching is a most important aspect of
high-performance web application. Caching provides a way of storing
frequently accessed data and reusing that data. Practically, this is an
effective way for improving web application’s performance.
Advantage of Caching
Reduce hosting server round-trips
When content is cached at the client or in proxies, it cause minimum request to server.Reduce database server round-trips
When content is cached at the web server, it can eliminate the database request.Reduce network traffic
When content is cached at the client side, it it also reduce the network traffic.Avoid time-consumption for regenerating reusable content
When reusable content is cached, it avoid the time consumption for regenerating reusable content.Improve performance
Since cached content reduce round-trips, network traffic and avoid time consumption for regenerating reusable content which cause a boost in the performance.
Key points about Caching
- Use caching for contents that are accessed frequently.
- Avoid caching for contents that are unique per user.
- Avoid caching for contents that are accessed infrequently/rarely.
- Use the VaryByCustom function to cache multiple versions of a page based on customization aspects of the request such as cookies, role, theme, browser, and so on.
- For efficient caching use 64-bit version of Windows Server and SQL Server.
- For database caching make sure your database server has sufficient RAM otherwise, it may degrade the performance.
- For caching of dynamic contents that change frequently, define a short cache–expiration time rather than disabling caching.
Output Cache Filter
The OutputCache filter allow you to cache the data that is output of an action method. By default, this attribute filter cache the data till 60 seconds. After 60 sec, Asp.Net MVC will execute the action method again and cache the output again.Enabling Output Caching
You can enable the output caching for an action method or controller by adding an [OutputCache] attribute as shown below:The output of the Index() action method will be cached for 20 seconds. If you will not defined the duration, it will cached it for by default cache duration 60 sec. You can see the cache effect by applying the break point on index method as shown below.
- [OutputCache(Duration=20, VaryByParam="none")]
- public ActionResult Index()
- {
- ViewBag.Message = DateTime.Now.ToString();
- return View();
- }
OutputCache Filter Parameter
Parameter
Type
Description
CacheProfile
string
Specify the name of the output cache policy which is defined with in <outputCacheSettings> tag of Web.config.
Duration
int
Specify the time in sec to cache the content
Location
OutputCacheLocation
Specify the location of the output to be cached. By default location is Any.
NoStore
bool
Enable/Disable where to use HTTP Cache-Control. This is used only to protect very sensitive data.
SqlDependency
string
Specify the database and table name pairs on which the cache content depends on. The
cached data will expire automatically when the data changes in the database.
VaryByContentEncoding
string
Specify the
semicolon separated list of character set (Content encoding like gzip
and deflate) that the output cache uses to vary the cache content
VaryByCustom
string
Specify the list of custom strings that the output cache uses to vary the cache content.
VaryByHeader
string
Specify the semicolon separated list of HTTP header names that are used to vary the cache content.
VaryByParam
string
Specify the semicolon
separated list of form POST or query string parameters that are used to
vary the cache content. If not specified, the default value is none.
Output Caching Location
By default, content is cached in three locations: the web server, any proxy servers, and the user's browser. You can control the content's cached location by changing the location parameter of the OutputCache attribute to any of the following values: Any, Client,Downstream, Server, None, or ServerAndClient.By default, the location parameter has the value Any which is appropriate for most the scenarios. But some times there are scenarios when you required more control over the cached data.
Suppose you want to cache the logged in use information then you should cached the data on client browser since this data is specific to a user. If you will cached this data on the server, all the user will see the same information that is wrong.
You should cache the data on the server which is common to all the users and is sensitive.
Configure Cache Location
For configuring the cache location, you need to add the System.Web.UI namespace on your controller. You can cached the user's personal information in his browser like as below.
- [OutputCache(Duration = 7200, Location = OutputCacheLocation.Client, VaryByParam = "none", NoStore = true)]
- public ActionResult Index()
- {
- ViewBag.Message = "Welcome : " + User.Identity.Name;
- return View();
- }
How to upload a file in MVC4
Posted By : Shailendra Chauhan, 12 Jan 2013
Updated On : 11 Jun 2014
Version Support : MVC4 & MVC3
Keywords : validate file using
jquery,upload file in mvc4 with client side validation,validate file
using jquery before upload in mvc4 mvc3
Uploading a file in Asp.Net MVC application
is very easy. The posted file is automatically available as a
HttpPostedFileBase parameters in the action of the controler. For
uploading a file on the server you required to have a file input control
with in html form having encoding type set to multipart/form-data. The
default encoding type of a form is application/x-www-form-urlencoded and
this is no sufficient for posting a large amount of data to server.
How to do it..
Step 1 : Form for uploading the file
- @using (Html.BeginForm("FileUpload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
- {
- @Html.ValidationSummary();
- <ol>
- <li class="lifile">
- <input type="file" id="fileToUpload" name="file" />
- <span class="field-validation-error" id="spanfile"></span>
- </li>
- </ol>
- <input type="submit" id="btnSubmit" value="Upload" />
- }
Step 2 : Validating the file on client side
- <script type="text/jscript">
- //get file size
- function GetFileSize(fileid) {
- try
- {
- var fileSize = 0;
- //for IE
- if ($.browser.msie)
- {
- //before making an object of ActiveXObject,
- //please make sure ActiveX is enabled in your IE browser
- var objFSO = new ActiveXObject("Scripting.FileSystemObject"); var filePath = $("#" + fileid)[0].value;
- var objFile = objFSO.getFile(filePath);
- var fileSize = objFile.size; //size in kb
- fileSize = fileSize / 1048576; //size in mb
- }
- //for FF, Safari, Opeara and Others
- else
- {
- fileSize = $("#" + fileid)[0].files[0].size //size in kb
- fileSize = fileSize / 1048576; //size in mb
- }
- return fileSize;
- }
- catch (e)
- {
- alert("Error is :" + e);
- }
- }
- //get file path from client system
- function getNameFromPath(strFilepath)
- {
- var objRE = new RegExp(/([^\/\\]+)$/);
- var strName = objRE.exec(strFilepath);
- if (strName == null)
- {
- return null;
- }
- else
- {
- return strName[0];
- }
- }
- $("#btnSubmit").live("click", function ()
- {
- if ($('#fileToUpload').val() == "")
- {
- $("#spanfile").html("Please upload file");
- return false;
- }
- else
- {
- return checkfile();
- }
- });
- function checkfile()
- {
- var file = getNameFromPath($("#fileToUpload").val());
- if (file != null)
- {
- var extension = file.substr((file.lastIndexOf('.') + 1));
- // alert(extension);
- switch (extension) {
- case 'jpg':
- case 'png':
- case 'gif':
- case 'pdf':
- flag = true;
- break;
- default:
- flag = false;
- }
- }
- if (flag == false)
- {
- $("#spanfile").text("You can upload only jpg,png,gif,pdf extension file");
- return false;
- }
- else
- {
- var size = GetFileSize('fileToUpload');
- if (size > 3)
- {
- $("#spanfile").text("You can upload file up to 3 MB");
- return false;
- }
- else
- {
- $("#spanfile").text("");
- }
- }
- }
- $(function ()
- {
- $("#fileToUpload").change(function () {
- checkfile();});
- });
- </script>
Step 3 : Controller's action for receiving the posted file
- [HttpPost]
- public ActionResult FileUpload(HttpPostedFileBase file)
- {
- if (ModelState.IsValid)
- {
- if (file == null)
- {
- ModelState.AddModelError("File", "Please Upload Your file");
- }
- else if (file.ContentLength > 0)
- {
- int MaxContentLength = 1024 * 1024 * 3; //3 MB
- string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".pdf" };
- if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
- {
- ModelState.AddModelError("File", "Please file of type: " + string.Join(", ", AllowedFileExtensions));
- }
- else if (file.ContentLength > MaxContentLength)
- {
- ModelState.AddModelError("File", "Your file is too large, maximum allowed size is: " + MaxContentLength + " MB");
- }
- else
- {
- //TO:DO
- var fileName = Path.GetFileName(file.FileName);
- var path = Path.Combine(Server.MapPath("~/Content/Upload"), fileName);
- file.SaveAs(path);
- ModelState.Clear();
- ViewBag.Message = "File uploaded successfully";
- }
- }
- }
- return View();
- }
How it works...
Understanding ViewModel in ASP.NET MVC
In ASP.NET MVC, ViewModel is a class that contains the fields which are represented in the strongly-typed view. It is used to pass data from controller to strongly-typed view.
Key Points about ViewModel
- ViewModel contain fields that are represented in the view (for LabelFor,EditorFor,DisplayFor helpers)
- ViewModel can have specific validation rules using data annotations or IDataErrorInfo.
- ViewModel can have multiple entities or objects from different data models or data source.
ViewModel Example
Designing ViewModel
- public class UserLoginViewModel
- {
- [Required(ErrorMessage = "Please enter your username")]
- [Display(Name = "User Name")]
- [MaxLength(50)]
- public string UserName { get; set; }
- [Required(ErrorMessage = "Please enter your password")]
- [Display(Name = "Password")]
- [MaxLength(50)]
- public string Password { get; set; }
- }
Presenting the viewmodel in the view
- @model MyModels.UserLoginViewModel
- @{
- ViewBag.Title = "User Login";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- @using (Html.BeginForm())
- {
- <div class="editor-label">
- @Html.LabelFor(m => m.UserName)
- </div>
- <div class="editor-field">
- @Html.TextBoxFor(m => m.UserName)
- @Html.ValidationMessageFor(m => m.UserName)
- </div>
- <div class="editor-label">
- @Html.LabelFor(m => m.Password)
- </div>
- <div class="editor-field">
- @Html.PasswordFor(m => m.Password)
- @Html.ValidationMessageFor(m => m.Password)
- </div>
- <p>
- <input type="submit" value="Log In" />
- </p>
- </div>
- }
Working with Action
- public ActionResult Login()
- {
- return View();
- }
- [HttpPost]
- public ActionResult Login(UserLoginViewModel user)
- {
- // To acces data using LINQ
- DataClassesDataContext mobjentity = new DataClassesDataContext();
- if (ModelState.IsValid)
- {
- try
- {
- var q = mobjentity.tblUsers.Where(m => m.UserName == user.UserName && m.Password == user.Password).ToList();
- if (q.Count > 0)
- {
- return RedirectToAction("MyAccount");
- }
- else
- {
- ModelState.AddModelError("", "The user name or password provided is incorrect.");
- }
- }
- catch (Exception ex)
- {
- }
- }
- return View(user);
- }
Some Tips for using ViewModel
- In ViewModel put only those fields/data that you want to display on the view/page.
- Since view reperesents the properties of the ViewModel, hence it is easy for rendering and maintenance.
- Use a mapper when ViewModel become more complex.
In this way, ViewModel help us to organize and manage data in a strongly-typed view with more flexible way than complex objects like models or ViewBag/ViewData objects.




Asp.net MVC 4 performance optimization with bundling and minification
MVC4 and .Net Framework 4.5 offer bundling and minification techniques that reduce the number of request to the server and size of requested CSS and JavaScript library, which improve page loading time.
System.Web.Optimization class offers the bundling and minification techniques that is exist with in the Microsoft.Web.Optimization dll. Using this dll you can also use this technique with Asp.Net MVC3 and .Net Framework 4.0. Refer the article Bundling and minification in MVC3 and Asp.Net 4.0for more help.
What is Bundle?
A bundle is a logical group of files that is loaded with a single HTTP request. You can create style and script bundle for css and javascripts respectively by calling BundleCollection class Add() method with in BundleConfig.cs file.
Creating Style Bundle
- bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.min.css",
- "~/Content/mystyle.min.css"));
Creating Script Bundle
- bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
- "~/Scripts/jquery-1.7.1.min.js",
- "~/Scripts/jquery.validate.min.js",
- "~/Scripts/jquery.validate.unobtrusive.min.js"));
Above both the bundles are defined with in BundleConfig class as shown below:
- public class BundleConfig
- {
- public static void RegisterBundles(BundleCollection bundles)
- {
- bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.min.css",
- "~/Content/mystyle.min.css"));
- bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
- "~/Scripts/jquery-1.7.1.min.js",
- "~/Scripts/jquery.validate.min.js",
- "~/Scripts/jquery.validate.unobtrusive.min.js"));
- }
- }
Creating Bundle using the "*" Wildcard Character
"*" wildcard character is used to combines the files that are in the same directory and have same prefix or suffix with its name. Suppose you want to add all the scripts files that exist with in "~/Script" directory and have "jquery" as prefix then you can create bundle like below:
- bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include("~/Scripts/jquery*.js"));
You can also add all the css that exist with in "~/Content" directory and have ".css" extension(as suffix) like below:
- bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/*.css"));
Registering Bundle
All bundles are registered with in Application_Start event of Global.asax file of you web application.
- protected void Application_Start()
- {
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- // Other Code is removed for clarity
- }
Minification
Minification is technique for removing unnecessary characters (like white space, newline, tab) and comments from the JavaScript and CSS files to reduce the size which cause improved load times of a webpage. There are so many tools for minifying the js and css files. JSMin and YUI Compressor are two most popular tools for minifying the js and css files.
You can also add WebEssentials2012.vsix extension to your VS2012 for minifying the js and css files. This is a great extension for VS2012 for playing with js and css.
Minification with VS2012 and WebEssentials 2012 extension
I would like to share how can you make minify version of you css file using WebEssentials extension and VS2012. This minify version will updated automatically if you will make change in original css file.
Performance Optimization with Bundling and Minification
I have done a performance test on a MVC4 application with & without bundling and minification. I have noticed the below result.Without Bundling and Minification
I have the below css and js files on the layout page and run the application in chrome browser and test no of request and loding time using chrome developer tools as shown below.
- <link href="~/Content/Site.css" rel="stylesheet"/>
- <link href="~/Content/MyStyle.css" rel="stylesheet"/>
- <script src="~/Scripts/jquery-1.7.1.js"></script>
- <script src="~/Scripts/jquery-ui-1.8.20.js"></script>
- <script src="~/Scripts/jquery.validate.js"></script>
- <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
In this test, I have seen, There are 7 request, total data size is 3.96KB and loading time is approximate 296ms.
With Bundling and Minification
I have run the above application with Bundling and Minification of css and js files and test no of request and loding time using chrome developer tools as shown below.
- @Styles.Render("~/Content/css")
- @Scripts.Render("~/bundles/jquery")
In this test, I have seen, There are only 3 request, total data size is 2.67KB and loading time is approximate 80ms. In this way by using bundling and minification you have reduced the total no of request, size and loading time.
Enabling Bundling and Minification in debug mode
Bundling and minification doesn't work in debug mode. So to enable this featues you need to add below line of code with in Application_Start event of Global.asax.
- protected void Application_Start()
- {
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- //Enabling Bundling and Minification
- BundleTable.EnableOptimizations = true;
- // Other Code is removed for clarity
- }
Busting Browser's Cache by Bundling
As you know browsers cache resources based on URLs. When a web page requests a resource, the browser first checks its cache to see if there is a resource with the matched URL. If yes, then it simply uses the cached copy instead of fetching a new one from server. Hence whenever you change the content of css and js files will not reflect on the browser. For this you need to force the browser for refreshing/reloading.
But bundles automatically takes care of this problem by adding a hashcode to each bundle as a query parameter to the URL as shown below. Whenever you change the content of css and js files then a new has code will be generated and rendered to the page automatically. In this way, the browser will see a different url and will fetch the new copy of css and js.
No comments:
Post a Comment