Sorted By: Month (10) and Year (2011)

Donut Hole Caching In ASP.NET MVC by Using Child Actions and OutputCacheAttribute

This blog post demonstrates how to implement Donut Hole Caching in ASP.NET MVC by Using Child Actions and OutputCacheAttribute
2011-10-30 09:40
Tugberk Ugurlu


homer-and-donut

One of the common issues of web applications is performance and serving the same content over and over again for hours, days, even months is certainly effecting the performance of our web applications. This is where server side caching comes in handy. But sometimes the whole page we are scripting on the server side is going to be static for hours and sometimes some portion of it.

The first one, caching the whole page, is sort of easy with almost any web development frameworks. The second one, caching a portion of your web page, is the tricky one.

Phil Haack blogged about Donut Hole Caching in ASP.NET MVC a while back but it is a little outdated. In this quick blog post, I will try to show you the easiest way of implementing this feature with ASP.NET MVC.

Use Cases

So, where might we need this Donut Hole Caching thing? For example, if you are listing categories on the side bar, you probably gathering those categories from a database. Add the fact that you render this part on every single page of your web application, it is a waste of time if your category list is not so dynamic. So, you may want to cache the category list part of the page so that you don’t go to your database every single time.

How to Do

In ASP.NET MVC framework, we can cache the whole controller action with OutputCacheAttribute which represents an attribute that is used to mark an action method whose output will be cached according to MSDN. This is perfect but wait a second. We do not want to cache the entire action, we just want to cache the portion of it. This is where ChildActionExtensions.Action method, which invokes a child action method and returns the result as an HTML string, plays a huge role. Let me show you how these parts of the framework play nice together.

Have a look at the below controller action :

[ChildActionOnly]
[OutputCache(Duration=60)]
public ActionResult sampleChildAction() {

    //Put the thread at sleep for 3 seconds to see the difference.
    System.Threading.Thread.Sleep(3000);

    //Also pass the date time from here just to see that it is comming from here.
    ViewBag.DateTime = DateTime.Now.ToString("dd.MM.yyyy HH:mm.ss");

    return View();
}

A simple controller action method which returns ActionResult, nothing fancy going on except for ChildActionOnlyAttribute which represents an attribute that is used to indicate that an action method should be called only as a child action. Let’s look at the sampleChildAction view and I will try to explain ChildActionOnlyAttribute function after that.

@{
    Layout = null;
}

<p>
    This portion of the web page was scripted on <strong>@ViewBag.DateTime</strong> and I will be cached for <strong>60</strong> seconds.
</p>

This html will be a part of our web page which will be cached. It doesn’t mean anything by itself but we have created an action for this view which means that we can call this page directly from a browser. ChildActionOnlyAttribute exactly prevent users to call this kind of actions. You do not need to implement this attribute there but it is nice to know that it is there for us.

The controller action which will render the whole page is so simple as below and doesn’t require any special thing for us to implement in order caching to work.

public ActionResult Index() {

    return View();
}

Let’s also look at the view implementation :

@{
    ViewBag.Title = "Donut Hole Caching Sample";
}

<h2>Donut Hole Caching Sample</h2>

<h3>Cached</h3>

<div>
    @Html.Action("sampleChildAction", 
      new { controller = "Sample", Area = "DonutHoleCaching" }
    )
</div>

<h3>Normal</h3>

<div>
    <p>
        This portion of the web page was scripted on <strong>@DateTime.Now.ToString("dd.MM.yyy HH:mm.ss")</strong>
    </p>
</div>

What we are doing here is that rather than putting the part, which we would like to cache, directly here, we are calling it as child action. So, the framework will treat the child action as it does for normal action methods.

When we first call it, we will see something like below :

image

While I was calling this page, I was on hold for 3 seconds because we have put the thread at sleep for 3 seconds on our child action method to feel the difference as you can see on above code in order.

When I make the second call, I got something like this and I wasn’t on hold for 3 seconds :

image

Did you notice the time difference? This proves that if the cache is valid, our child action method won’t be rendered again. It will serve from the cache. Awesome, ha?

I decided to create an ASP.NET MVC project called MvcMiracleWorker for this kind of small samples. You can find the complete source code from GitHub : https://github.com/tugberkugurlu/MvcMiracleWorker

Behave well, use ASP.NET MVC Winking smile

ASP.NET MVC Remote Validation For Multiple Fields With AdditionalFields Property

This post shows the implementation of ASP.NET MVC Remote Validation for multiple fields with AdditionalFields property and we will validate the uniqueness of a product name under a chosen category.
2011-10-24 06:44
Tugberk Ugurlu


why-wont-you-validate-me-hrrrr

I blogged about ASP.NET MVC Remote Validation couple of days ago by showing a simple scenario for how to use it. That blog post simply covers everything about remote validation except for properties of RemoteAttribute Class.

In that blog post, we covered validating user inputs uniqueness for one field in order to alert the user before the form is posted. This is a quite nice built-in feature which takes basically not more 5 minutes to implement.

But we as in all human beings tend not to be happy with the current situation and want more. It is in our nature, we can’t help that. So, as soon as I use this feature I ask myself "What if I would like to check the uniqueness of product name inside the chosen category?". Well, it turns out that ASP.NET MVC team asked this question themselves way earlier than me and added a support for this kind of situations.

RemoteAttribute.AdditionalFields Property gets or sets the additional fields that are required for validation. AdditionalFields property is string property and can be provided for multiple fields.

Probably another question pops up on your mind : "How does ASP.NET MVC Framework relate the fields, which we will provide for AdditionalFields property, with form elements and pass them our controller?" If we need to ask this question in plain English, that would be this : "How the heck does it know in which category I trying to check the uniqueness of the product name?". Here, ASP.NET MVC Model Binding feature plays a huge role here as much as JQuery.

Simple Scenario

Assume that we need to store products under a category inside our database and we need every each product name to be unique under the chosen category.

In order to stick with the topic here, I have already built the necessary stuff (database, repos, etc.). I used SQL Server Compact Version 4 here. As sample database, you won’t believe what I used : Northwind Winking smile I also used Entity Framework to reach out to the data. You can see all of the code from my GitHub Repo : https://github.com/tugberkugurlu/MvcRemoteValidationSample

Our create form looks like below :

image

The product model class looks like this :

public partial class Product
{
    public Product()
    {
        this.Order_Details = new HashSet<Order_Detail>();
    }

    public int Product_ID { get; set; }
    public Nullable<int> Supplier_ID { get; set; }
    public Nullable<int> Category_ID { get; set; }
    public string Product_Name { get; set; }
    public string English_Name { get; set; }
    public string Quantity_Per_Unit { get; set; }
    public Nullable<decimal> Unit_Price { get; set; }
    public Nullable<short> Units_In_Stock { get; set; }
    public Nullable<short> Units_On_Order { get; set; }
    public Nullable<short> Reorder_Level { get; set; }
    public bool Discontinued { get; set; }

    public virtual Category Category { get; set; }
    public virtual ICollection<Order_Detail> Order_Details { get; set; }
    public virtual Supplier Supplier { get; set; }
}

Here is my additional partial class under the same namespace of my Product class :

[MetadataType(typeof(Product.MetaData))]
public partial class Product {

    private class MetaData {

        [Remote(
            "doesProductNameExistUnderCategory", 
            "Northwind", 
            AdditionalFields = "Category_ID",
            ErrorMessage = "Product name already exists under the chosen category. Please enter a different product name.",
            HttpMethod = "POST"
        )]
        [Required]
        public string Product_Name { get; set; }
        
        [Required]
        public int? Supplier_ID { get; set; }

        [Required]
        public int? Category_ID { get; set; }

    }

}

As you see there, we have decorated Product_Name property with RemoteAttribute. What we need to point out here is AdditionalFields property of RemoteAttribute. Simply we are saying here that : 'Pass Category_ID value to the controller action when you try validate the Product_Name'. So, Ajax Request will send two form inputs to our action : Product_Name and Category_ID. As we have already seen on my previous blog post on ASP.NET MVC Remote Validation, Model Binder will bind those inputs to our action parameters in order to allow us to easily pick them.

Our main goal here is to check the uniqueness of the product name under the chosen category and that’s why we need Category_ID value inside our controller action. Check controller action code below and you will get what I am trying to say :

public JsonResult doesProductNameExistUnderCategory(int? Category_ID, string Product_Name) {

    var model = _entities.Products.Where(x => (Category_ID.HasValue) ? 
            (x.Category_ID == Category_ID && x.Product_Name == Product_Name) : 
            (x.Product_Name == Product_Name)
        );

    return Json(model.Count() == 0);

}

Inside this action, we are checking if the user name already exists under the chosen category or not. For the real purpose of this blog post, we only need to focus what we are returning here. The other part of this code mostly depends on your application’s business logic.

We are basically done here. I will run the app and see it in action but please firstly see the below screenshot :

image

This table show the list of products inside our database. On the first row, we see that there is a product named Chai under Category_ID 1 whose Category_Name is Beverages (you don’t see the Category_Name here but don’t worry, just trust me). We will demonstrate our sample with this product values.

First, select the category from the select list :

image

Then, type Chai for Product_Name :

image

Then, simply hit Tab key :

image

All done but I would like to go a little deeper here. Let’s put a break point on doesProductNameExistUnderCategory method and start a debug session.

image

When we follow the above steps again, we should end up like this :

image

Let’s look what we got here :

image

We have all the necessary values to check if the value is legitimate or not.

Again, you can see all of the code from my GitHub Repo : https://github.com/tugberkugurlu/MvcRemoteValidationSample

Hope you enjoy the post Smile

Check Instantly If Username Exists - ASP.NET MVC Remote Validation

This blog post will walk you through on implementation and usage of ASP.NET MVC Remote Validation. As a sample, we will validate the availability of the username for membership registration.
2011-10-19 04:07
Tugberk Ugurlu


On some of our web applications, we require users to register our site in order to perform some special actions. This feature kind of a no-brainer thing thanks to built-in ASP.NET Membership API. It works well with either ASP.NET Web Forms or ASP.NET MVC. In this path, on some cases, we also require each users to have unique username or unique e-mail. The implementation of this feature also does not require our concern either.

Let’s see it in action what I am getting at here.

I created an ASP.NET MVC 3 Web Application project with Visual Studio 2010 (It is also same for Visual Web Developer which is a free version of Visual Studio) and I fired it up by clicking Ctrl + F5. When I navigate to /Account/Register, I get the following view :

image

In order to stick with the topic here, I already registered a user with a username of user1. Look what happens when I try to create another user with a username of user1 :

image

So, the thing ASP.NET offers us out of the box is clever. But there is a little bit a problem here. Well, not a problem but how can I call it, hmmm… I can say lack of creativeness. When I push the register button here, it goes all the way to server to register the user. Inside our controller, built-in register action checks if user already exists or not.

Wouldn’t it be nice if user instantly sees if typed username is valid or not? It certainly would be!

Introduction to ASP.NET MVC Remote Validation

We know that ASP.NET MVC takes advantage of .NET Framework Data Annotations to validate user’s input. By this way, we can check for required fields with RequiredAttribute, length of a string with StringLengthAttribute and so on. Well, it turns out that there is another useful one called RemoteAttribute which we can use, for example, to validate e-mail and username in a registration form and alert the user before the form is posted.

This Remote Validation thing is what we are looking for. In order to implement this for our scenario, we need to tweak the UserName property of RegisterModel class. Here is the whole RegisterModel class after the modification I made :

    public class RegisterModel {

        [Required]
        [Display(Name = "User name")]
        [Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.")]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }

As you can see, we added Remote attribute for UserName property inside RegisterModel class. RemoteAttribute has several overloads but what we entered here is as follows :

  • doesUserNameExist : It is the name of the Action which will validates the user input by returning true or false as JSON format. We will see how we do that in a minute.
  • Account : It is the name of the controller which doesUserNameExist lives in.
  • HttpMethod : Simply we are telling the remote validation to communicate our mini service over Http POST method (This is not required but I’d like to do it this way).

How our controller action doesUserNameExist looks like is as follows :

[HttpPost]
public JsonResult doesUserNameExist(string UserName) {

    var user = Membership.GetUser(UserName);

    return Json(user == null);
}

As you see, it is a simple controller action which returns JsonResult. What we need to notice here is UserName paramater of this action. We put that parameter there to pick up the user input which will be sent through Ajax request to our action. Remote Validation will send the user input as Form Data which will have the same name as property. So, in this case it is UserName.

Before we give it a try, make sure that you have the following libraries referenced on your registration page :

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

Let’s build our project and fire it up to see it in action.

1. I loaded the page :

image

2. I enter user1 for UserName field (user1 is the username which is already inside our database) :

image

3. Then I just put the mouse cursor inside another text input field and see what happened :

image

Just what we needed. I thought showing this in action like that is a lame approach to do that so I recorded a short video in order to demonstrate this. In this video I also tried to show what is happening behind the scenes. See it below :

I also put the sample project on GitHub so you can get the working sample code if you want :

https://github.com/tugberkugurlu/MvcRemoteValidationSample

Note : 

But there is a donwside for this validation attribute. The remote validation does not validate the user input on server side. So, you need to make sure on the server side that it is valid as it is being done on our sample. We also make sure on the server side that username which is being passed to our controller is unique.

Hope this will help you even a little bit.

Unit Testing With xUnit.net for ASP.NET MVC Web Applications - Part 1

In this blog post, we will see how we set up our environment for xUnit.net Unit Testing Framework. This is the first blog post of the blog post series on Unit Testing With xUnit.net for ASP.NET MVC.
2011-10-16 14:40
Tugberk Ugurlu


you-need-some-tests-yo...

I have been developing web applications with ASP.NET MVC for long time and to be honest, none of them has good Unit Testing backing them up. I don’t know you have realized but I am not even mentioning anything about TDD (Test Driven Development).

This isn’t a big problem for me. It is mainly because I work in a team, which has only one member inside it [yeah, it’s me :)], for my company. But all the cool guys are always talking about how awesome it is to work with Unit Testing.

This made me obsessed about Unit Testing and I stated to spend real quality time on investigating that so that I will be able to sleep without having dreams about a guy who wears an ugly sunglasses and telling me ‘You need some tests yo!’. (No, I am just kidding, I am not insane. At least, not yet.)

Visual Studio has a built-in test environment but I figured that is not enough. So, from now on, I will be using xUnit.net for my unit test applications.

What is xUnit.net?

xUnit.net is a unit testing tool for the .NET Framework. Written by the original inventor of NUnit, xUnit.net is the latest technology for unit testing C#, F#, VB.NET and other .NET languages. Works with ReSharper, CodeRush, and TestDriven.NET.

Set Up Your Environment

First thing is first. Go to http://xunit.codeplex.com/releases/view/62840 to download the latest version of xUnit.net. At the time that I write this blog post, the latest version of xUnit.net is 1.8. Unzip the file inside a path and run the xUnit.installer.exe file.

You will have a window opened in front of you. For the sake of simplicity, I only check Microsoft ASP.NET MVC 3 Unit Testing Templates and click Apply button. After that, here is the screen shots of the result :

imageimage

File > New > Project

After the installation, go to VS 2010 and follow File > New > Project > ASP.NET MVC 3 Web Application. You will see that xUnit is sitting right there.

image

imageGo ahead and create the project. When you create the project you will see the usual HomeController.cs inside your Controllers folder. With xUnit.net project, you will see that we get HomeControllerFacts.cs file out of the box as sample. This file gives us a head start on this new thing for us.

On this blog post, I would like to focus on how things goes for us instead of how we write our unit test code.

As we have seen, we get a sample project and sample test project with some tests written inside it the the sample application. When we build the solution, we should be able to process successfully.

So, the next question is how we run our tests. The xUnit.net framework supports 4 distinct test runners:

  • GUI Test Runner
  • Console Test Runner
  • TestDriven.NET Test Runner
  • Resharper 4.0 Test Runner

I will walk you through how we run our tests with GUI Test Runner for this blog post.

Running xUnit Tests With GUI Test Runner

Navigate to the path which you have installed you xUnit project files and you will notice 4 files there which are green as follows :

image

Firstly, they are not same. I am sure you already understood what is for what but here is the detailed info :

xuit.gui.clr4, xuit.gui.clr4.x86 : This is for CLR 4 projects. .x86 is for x86 compatibility which you already know.

xuit.gui, xuit.gui.x86 : This is for CLR 2 projects. .x86 is for x86 compatibility which you already know.

I have open up the xuit.gui.exe which is suitable for me. Then, from the GUI, select the menu option Assembly > Open (Ctrl + O for keyboard shortcut) and select your test application output dll file (Be careful here. If you don’t build your solution before this process, you won’t be able to find the output dll file).

image

When you make the selection, the runner will be able to pick up all the tests as you can see below :

image

Let’s touch the Run All button on the left side at the bottom :

image

Looks cool. I break one of the tests on purpose so that we can see it failing :

image

So, this is the simplest as it can get. This blog post is supposed to be the first blog post of the blog post series on Unit Testing With xUnit.net for ASP.NET MVC and I will be blogging on further features of xUnit for ASP.NET MVC. Stay tuned!

Tags