MVC Series Part 3: Miscellaneous Issues

Introduction

In my first MVC series post, I discussed how to dynamically add items to a container using an MVC controller. Afterwards, I went through the process of unit testing the AccountController. The main purpose of this series was to explain some troublesome hiccups I ran into considering I did not come from a web development background. In this post I want to highlight a few of the minor issues while developing in MVC. One of them is not even related to MVC specifically, but it still caused enough of a headache that hopefully someone reading this can be spared the confusion.

HttpContext in Unit Tests

When I first started unit testing controllers, the HttpContext would return null when attempting to be accessed. The reason for this is because the controllers never assign the class on creation. Instead, controllers are typically created by the ControllerBuilder class. In my last post about unit testing the AccountController, I described a way to mock out the HttpContext, but in the beginning I wanted to try and keep my test project as lean as possible. Since I had not approached testing the AccountController yet and did not want to include a package to mock out an object I only needed to resolve NullReferenceExceptions, I found this clever post to quickly bypass this issue. By providing the HttpContext with a simple Url I no longer received an exception and was able to test the other components of a controller. I decided to wrap this functionality inside a class:

public class TestHttpContext : IDisposable
{
	public TestHttpContext()
	{
		HttpContext.Current = new HttpContext(
			new HttpRequest( null, "http://tempuri.org", null ),
			new HttpResponse( null ) );
	}

	public void Dispose()
	{
		HttpContext.Current = null;
	}
}

Since I am creating a new controller for each test, I needed the HttpContext to be recreated and destroyed each time. So, I went ahead and placed this inside a base test class that all controller tests will inherit:

public class TestBase
{
	private TestHttpContext _testContext;

	[TestInitialize]
	public void Initialize()
	{
		_testContext = new TestHttpContext();
	}

	[TestCleanup]
	public void TestCleanup()
	{
		_testContext.Dispose();
	}
}

Mocking out the HttpContext would provide better unit testing standards, but my minimalist personality found this solution too good to pass for the time being.

DbContext Non-Thread Safe

After updating my project to use Unity, I decided to take better advantage of the dependency injection design pattern by making the DbContext a singleton to prevent having to constantly re-initialize the connection to our Azure database. Early on after this change it became apparent our website was very inconsistent when trying to write to the database. Since many changes were occurring during this time, I did not immediately presume the DbContext as a singleton was the cause until I ran into this post.

So it seems I could still gain a performance boost by only creating the DbContext once per thread call, but how could I do this implementation using dependency injection? “Fortunately”, a new version of Unity provides a LifetimeManager catered specifically to this called PerRequestLifetimeManager.

This solution dramatically reduced my refactoring costs to close to zero, which was very desirable at this point in the project where time constraints were becoming out of reach. Later, I did a more thorough research into DbContext and you will notice this is why I put ‘Fortunately’ in quotes. As this MSDN post mentions, PerRequestLifetimeManager is bad practice to use when dealing with the DbContext. The reason is because it can lead to hard to track bugs and goes against the MVC principle of registering objects with Unity that will remain stateless. Although our application never ran into issues after implementing this LifetimeManager, in the future it is best to simply create and destroy the DbContext every time.

Ajax Caching in IE

This last problem is not so much an MVC issue, but a cross browser bug. And it is not so much a bug as it is more of understanding there are different specifications for each browser. As I mentioned in my post for creating Dynamic Items, I was using ajax calls to dynamically modify the DOM of a container. Throughout the project though we would intermittently hear bugs when attempting to add an item and trying to save. Each time the bug would re-occur, I would view the problem area, look stupefied at the cause of the issue, check in a fix, and the problem would go away, only to show up again a week later. What was going on here? Especially since the files in this area had been untouched for weeks!

The problem? Internet Explorer and its aggressive caching. The other browsers are not this adamant about caching ajax calls, at least when it comes to developing testing. And the solution to the problem was a bit more demoralizing:

$.ajax({
	async: false,
	cache: false,
	url: '/Controller/Action',
}).success(function (partialView) {
	// do action
});

One line of code solved weeks of headache Although any fairly seasoned web developer would probably speculate the browser being at fault, as someone who only ever has to deal with one set of specifications (.NET/WCF/EF/WPF/SQL) our team and I were not use to meticulously testing each new feature on every available browser. This meant although someone would find the bug in IE, but in retesting they may have coincidentally retested the feature in Chrome. Or, even worse, republishing the test caused the caching to reset so retesting the feature would get the pass the first time, but would not realize how broken it was until days later. All this means is we need to have a different method for testing web projects and to continue our understanding of how web development can act.

Summary

Working in MVC has been a great learning experience and helped continue my growth in developing in web. Despite my complaints and the hair-splitting, alcohol consuming  problems I do enjoy the breadth and stability MVC provides to the web world. I will continue my progress in the realms of web development and hope these small roadblocks will become less frequent, at the very least for my sanity’s sake.

MVC Series Part 2: AccountController Testing

Introduction

Click here to download code and sample project

In my first post of the series, I explained the perils and pitfalls that I had to overcome with dynamically adding items. One of the next problem I ran into was dealing with unit testing the AccountController. More specifically, attempting to represent the UserManager class. Since unit testing is a fundamental necessity for any server project, testing the controller was a necessity.

Attempting to Test

So, let’s first create a test class for the AccountController and include a simple test for determining if a user was registered. Here is how my class first appeared:

[TestClass]
public class AccountControllerTest
{
	[TestMethod]
	public void AccountController_Register_UserRegistered()
	{
		var accountController = new AccountController();
		var registerViewModel = new RegisterViewModel
		{
			Email = "test@test.com",
			Password = "123456"
		};

		var result = accountController.Register(registerViewModel).Result;
		Assert.IsTrue(result is RedirectToRouteResult);
		Assert.IsTrue( _accountController.ModelState.All(kvp => kvp.Key != "") );
	}
}

When running the unit test I get a NullReferenceException thrown when attempting to access the UserManager. At first I assumed this was due to not having a UserManager created, but debugging at the location of the thrown exception led me to this:

ApplicationUserManager UserManager
{
     get
     {
          return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
     }
     private set
     {
          _userManager = value;
     }
}

The exception is actually getting thrown on the HttpContext property that is part of ASP.Net internals. We cannot assign HttpContext directly on a controller since it is read-only, but the ControllerContext on it is not, which explains how to do that here. We can create this easily enough by installing the Moq NuGet package to help mock this out. We will install the package and place the initialization of our AccountController into a initialize test class that will get called prior to every unit test:

private AccountController _acocuntController;

[TestInitialize]
public void Initialization()
{
     var request = new Mock<HttpRequestBase>();
     request.Expect( r => r.HttpMethod ).Returns( "GET" );
     var mockHttpContext = new Mock<HttpContextBase>();
     mockHttpContext.Expect( c => c.Request ).Returns( request.Object );
     var mockControllerContext = new ControllerContext( mockHttpContext.Object, new RouteData(), new Mock<ControllerBase>().Object );

     _acocuntController = new AccountController
     {
          ControllerContext = mockControllerContext
     };
}

Now when we run our application we no longer have to worry about the HttpContext, but still there is another NullReferenceException being thrown. This time it is from the call to ‘GetOwinContext’.

Alternative Route

At this point, attempting to mock out all of HttpContext’s features seems like a never ending road. All we really want is the ability to use UserManager’s feature to register a user. In order for us to do that we will need to mock out the IAuthenticationManager. This is no easy feat considering how well embedded the UserManager is within the AccountController. Fortunately, a post mentioned here mentions the right direction for substituting the ApplicationUserManager.

What we want to do is create a new class, called AccountManager, that will act as an access to the UserManager. The AccountManager will take in an IAuthenticationManager and also a IdentityDbContext, in casewe need to specify the specific context. I decided to place this class in a separate library that both the MVC and unit test libraries can access. If you decide to do the same and copy the class from the sample project, most of the dependencies will get resolved except for the HttpContextBase extension ‘GetOwinContext’. The reason is because that extension needs Microsoft.Owin.Host.SystemWeb. You can simply install this dependency in your library as a Nuget package through this command:

  • Install-Package Microsoft.Owin.Host.SystemWeb

Now that we have our AccountManager, we need to make sure our AccountController will use this class rather than attempting to create the UserManager from HttpContext. This starts with the constructor, where now we will have it accept our manager rather than passing in a UserManager:

public AccountController( AccountManager<ApplicationUserManager, ApplicationDbContext, ApplicationUser> manager)
{
	_manager = manager;
}

Then we will change the access to AccountController.UserManager to use the AccountManager:

public ApplicationUserManager UserManager
{
	get
	{
		return _manager.UserManager;
	}
}

Dependency Injection

Now the immediate problem with this is that MVC’s controllers are stateless and handle the creation of all the classes, including any objects that are injected into the class. Fortunately, Unity has dependency injection specifically for MVC that will allow us to inject our own objects. As of this writing, I went ahead and installed Unity’s MVC 5, which is referenced here. It’s a very seamless process to integrate Unity into your MVC project. After installing the package, open the Global.asax.cs, where your Application_Start() method is stored and add in ‘UnityConfig.RegisterComponents();’. Afterwards, in the App_Start folder, open the UnityConfig.cs file and register our AccountManager:

container.RegisterType<AccountManager<ApplicationUserManager, ApplicationDbContext, ApplicationUser>>(new InjectionConstructor());

We will also need to override our initialization process for the AccountController to ensure the AccountManager either gets the embedded HttpContext from the AccountController or one we provide during test:

protected override void Initialize( RequestContext requestContext )
{
	base.Initialize( requestContext );
	_manager.Initialize( HttpContext );
}

We will also need to remove the references to AuthenticationManager and instead have our AccountController reference the AccountManager’s AuthenticationManager. This will also cause our SignInAsync method to this:

private async Task SignInAsync( ApplicationUser user, bool isPersistent )
{
	await _manager.SignInAsync( user, isPersistent );
}

Mocking AccountController

Now we can run our application and register a user using our AccountManager. With this implementation in place, we simply need to mock out our IAuthenticationManager. Here is a post that describes a bit of the process. So, following suit, we go ahead and mock out the necessary classes for initializing up our test AccountController, all under the same Initialization class:

private AccountController _accountController;

[TestInitialize]
public void Initialization()
{
	// mocking HttpContext
	var request = new Mock<HttpRequestBase>();
	request.Expect( r => r.HttpMethod ).Returns( "GET" );
	var mockHttpContext = new Mock<HttpContextBase>();
	mockHttpContext.Expect( c => c.Request ).Returns( request.Object );
	var mockControllerContext = new ControllerContext( mockHttpContext.Object, new RouteData(), new Mock<ControllerBase>().Object );

	// mocking IAuthenticationManager
	var authDbContext = new ApplicationDbContext();
	var mockAuthenticationManager = new Mock<IAuthenticationManager>();
	mockAuthenticationManager.Setup( am => am.SignOut() );
	mockAuthenticationManager.Setup( am => am.SignIn() );

	var mockUrl = new Mock<UrlHelper>();

        var manager = new AccountManager<ApplicationUserManager, ApplicationDbContext, ApplicationUser>( authDbContext, mockAuthenticationManager.Object );
	_accountController = new AccountController( manager )
	{
		Url = mockUrl.Object,
		ControllerContext = mockControllerContext
	};

	// using our mocked HttpContext
	_accountController.AccountManager.Initialize( _accountController.HttpContext );
}

Now we can effectively test our AccountController’s logic. It’s unfortunate this process was anything but straight forward, but at least we are able to have better unit test code coverage over our project.

MVC Series Part 1: Dynamically Adding Items Part 3

Collections named with same substring in a Dynamic Item

Click here to download code and sample project

In the second part of the series, I discussed how to include a collection inside a dynamic item. Here is one gotcha that I ran into during development. Let’s say we decide to add a Publisher for every new book and you want the ability to add a few books the publisher has distributed. Here is the PublisherViewModel class I created:

public class PublisherViewModel
	{
		public PublisherViewModel()
		{
			Books = new List<PublisherBookViewModel>();
			for ( int i = 0; i < 3; i++ )
			{
				Books.Add( new PublisherBookViewModel() );
			}
		}
		public string Name { get; set; }

		public IList<PublisherBookViewModel> Books { get; set; }
	}

Here is how the html would look for PublisherViewModel:

<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor( model => @Model.Name )
    </dt>
    <dd>
        @Html.EditorFor( model => @Model.Name )
    </dd>
    <br />

    <dt>
        @Html.DisplayNameFor( model => @Model.Books )
    </dt>
    <dd>
        @for ( int i = 0; i < @Model.Books.Count(); i++ )
        {
            @Html.EditorFor( model => @Model.Books[i] )
        }
    </dd>
</dl>

I went ahead and created a new class for the books collection called PublisherBookViewModel. It simply contains one property for Name. Here is how the Html looks:

@using ( Html.BeginCollectionItem( "Books" ) )
{
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor( model => @Model.Name )
        </dt>
        <dd>
            @Html.EditorFor( model => @Model.Name )
        </dd>
    </dl>
}

But when I go to create one new Book and post back, I actually end up receiving 4 items in my ‘NewBooks’ collection. How did this even happen?

Well, the reason this occurred is again thanks to our BeginCollectionItem HtmlHelper class. The extra logic that we added in the last article seems to merely grab the first occurrence of our collection name:

collectionName = htmlFieldPrefix.Substring( 0, htmlFieldPrefix.IndexOf( collectionName ) + collectionName.Length );

If we look at what the HtmlFieldPrefix string looks like coming in we can start to spot the problem:

"NewBooks[18fe8281-9b41-43ff-bcc9-a14ce3e99dc8].Publisher.Books[0]"

So, our parent dynamic item is being bounded to a collection called ‘NewBooks’, but the PublisherViewViewModel has its own collection of items called ‘Books’. Our Substring method needs to be a little bit smarter by replacing ‘IndexOf’ with ‘LastIndexOf’. And with that, we will no longer have issues with sub collection binding.

This is as far as I took with dynamically adding items in MVC, but at some point it would be nice to be able to add dynamic items to a dynamic item (i.e., instead of pre-populating our Characters collection, we let the user add as many as they need). Perhaps another day I will delve into this.

MVC Series Part 1: Dynamically Adding Items Part 2

Collections in a Dynamic Item

Click here to download code and sample project

In the first part of the series, I discussed how to add items dynamically. So, why don’t we expand on our idea and let’s say we want to add the ability to include another collection into our original dynamic item. We will expand our BookViewModel editor template to include a collection of 5 story Characters a user can insert:

<dl id="booksContainer">
        @foreach ( var classicBook in @Model.ClassicBooks )
        {
            <dl>
                <dt>
                    @Html.DisplayNameFor( model => classicBook.Title )
                </dt>
                <dd>
                    @Html.DisplayFor( model => classicBook.Title )
                </dd>

                <dt>
                    @Html.DisplayNameFor( model => classicBook.Author )
                </dt>
                <dd>
                    @Html.DisplayFor( model => classicBook.Author )
                </dd>
            </dl>
        }
</dl>

And we included a CharacterViewModel editor template that only includes the ability to insert first and last name. But when you attempt to add a book with a characters we run into the same problem originally where the new Characters are not binding correctly. The reason this exists is because our HtmlHelper is not able to uniquely identify sub items inside a recently dynamically added item. Makes sense?

No? Well, let’s discuss first what the BeginCollectionItem Html helper generates when injected into the Html element. Here is the BookViewModel’s partial view for the title:

<dt>
    @Html.DisplayNameFor( model => @Model.Title )
</dt>
<dd>
    @Html.EditorFor( model => @Model.Title )
</dd>

And here is the output that actually gets injected into the Html element after passing through the Html helper:

<dt>
    Title
</dt>
<dd>
    <input class="text-box single-line"
           id="NewBooks_3ad36db7-7685-4c8e-aadd-a2309f65e858__Title"
           name="NewBooks[3ad36db7-7685-4c8e-aadd-a2309f65e858].Title"
           type="text" value="" />
</dd>

Here you can see how the Html helper is inserting a Guid into the id and name fields so MVC can uniquely identify the property back to the item. But if we use the same comparison for Character, here is the partial view for name:

<dt>
    FirstName
</dt>
<dd>
    <input class="text-box single-line"
           id="Characters_dd611290-f64b-4b1a-9add-bad035f7b94f__FirstName"
           name="Characters[dd611290-f64b-4b1a-9add-bad035f7b94f].FirstName"
           type="text" value="" />
</dd>
<dt>
    LastName
</dt>
<dd>
    <input class="text-box single-line"
           id="Characters_dd611290-f64b-4b1a-9add-bad035f7b94f__LastName"
           name="Characters[dd611290-f64b-4b1a-9add-bad035f7b94f].LastName"
           type="text" value="" />
</dd>

Although the character model is correctly getting a Guid assigned, there is no way for MVC to know that CharacterViewModel belongs to a NewBooks sub item. In order to solve this, we need to delve into our BeginCollectionItem Html helper and make sure it retains the ‘NewBooks’ guid. This is quite straightforward if we do a comparison on the incoming collection name:

var htmlFieldPrefix = html.ViewData.TemplateInfo.HtmlFieldPrefix;
if ( htmlFieldPrefix.Contains( collectionName ) )
{
        collectionName = htmlFieldPrefix.Substring( 0, htmlFieldPrefix.IndexOf( collectionName ) + collectionName.Length );
}

And let’s take a look again at our injected output:

<dt>
     FirstName
</dt>
<dd>
    <input class="text-box single-line"
           id="NewBooks_1a95a483-e5c7-4696-ac91-bd9f0563b83b__Characters_e3e949f5-aae7-44cd-9aa8-419658c25e75__FirstName"
           name="NewBooks[1a95a483-e5c7-4696-ac91-bd9f0563b83b].Characters[e3e949f5-aae7-44cd-9aa8-419658c25e75].FirstName"
           type="text" value="" />
</dd>
<dt>
    LastName
</dt>
<dd>
    <input class="text-box single-line"
           id="NewBooks_1a95a483-e5c7-4696-ac91-bd9f0563b83b__Characters_e3e949f5-aae7-44cd-9aa8-419658c25e75__LastName"
           name="NewBooks[1a95a483-e5c7-4696-ac91-bd9f0563b83b].Characters[e3e949f5-aae7-44cd-9aa8-419658c25e75].LastName"
           type="text" value="" />
</dd>

Now our character items will get posted back onto our dynamic item.

MVC Series Part 1: Dynamically Adding Items Part 1

Introduction

Recently, I have been exposed to working on a project using ASP.NET MVC 5. My experience working with MVC for the first time was overall positive, but it did run into quite a few hair pulling scenarios. My background up to this point primarily dealt with C# WPF applications, but with a little bit of web development on the side.  In this series, I will discuss some of the major issues that led to many sleepless nights working on this project. And although these scenarios may not seem to be the most difficult to an experienced MVC developer, these are the problems that caused major hiccups to a first timer like myself.

Dynamically Adding Items

Click here to download code and sample project

In one of the first major issues I needed to attempt to solve was trying to add items dynamically to a View. Representing a collection already populated is fairly straight forward using MVC’s Razor, as represented here in my collection of classical books:

<dl class="dl-horizontal" id="booksContainer">
        @foreach ( var classicBook in @Model.ClassicBooks )
        {
            <dl class="dl-horizontal">
                <dt>
                    @Html.DisplayNameFor( model => classicBook.Title )
                </dt>
                <dd>
                    @Html.DisplayFor( model => classicBook.Title )
                </dd>

                <dt>
                    @Html.DisplayNameFor( model => classicBook.Author )
                </dt>
                <dd>
                    @Html.DisplayFor( model => classicBook.Author )
                </dd>
            </dl>
        }
</dl>

We can even go one step further and place this inside a ‘DisplayTemplate’ and push the display content into a partial view:
dynamic img 1

<dl class="dl-horizontal" id="booksContainer">
        @foreach ( var classicBook in @Model.ClassicBooks )
        {
            @Html.DisplayFor(model => classicBook);
        }
</dl>

But how do we add content on the fly?

Well, we could have a button that inserts javascript into our ‘booksContainer’ element and this would provide a seamless experience for the user. But what if we decide to change how the view looks? And how could we get this to post back to MVC server? What about if we decided to take in an image file as well?

Given I did not want to update the view in two places, I managed to find a solution that managed to do all of the above, linked here.

In summary, I was able to use an ajax call to retrieve my BookViewModel’s partial html view from the server and inject it into an html element:

  • Adding an editor partial view for the BookViewModel

dynamic img2

  • Including the html element that will take in new books:
    <div id="newBooks">
        @for ( int i = 0; i < @Model.NewBooks.Count(); i++ )
    
        {
    
            @Html.EditorFor( model => @Model.NewBooks[i] )
    
        }
    
    </div>
  • On the server, the HomeController’s method that simply returns my partial view:
    public ActionResult CreateNewBook()
    {
    
        var bookViewModel = new BookViewModel();
    
        return PartialView( "~/Views/Shared/EditorTemplates/BookViewModel.cshtml", bookViewModel );
    
    }
    
    
  • The ajax call that handles the add book button click and injects the returned partial view:
    @section Scripts {
        <script type="text/javascript">
    
            $("#addbook").on('click', function () {
    
                $.ajax({
                    async: false,
                    url: '/Home/CreateNewBook'
                }).success(function (partialView) {
    
                    $('#newBooks').append(partialView);
    
                });
            });
    
        </script>
    }
    

And now we can dynamically add items on button click! The user is able to add as many books as they want, click submit, and the collection of books will get received on HttpPost. But, when we put a break post on our post method, the NewBooks collection comes back as empty. Why is this happening?

Well the reason is because MVC can only bind back a collection of items if it can uniquely identify each one. This article actually describes how you can get a collection of items to bind appropriately on post back, linked here.

Unfortunately, this does not apply when items are getting added dynamically. Luckily, the previous article also solved this problem by creating a Html Helper class, BeginCollectionItem, that adds a unique identifier to every new inserted item. All we need to do is modify our BookViewModel editor template to include it:

@using ( Html.BeginCollectionItem( "NewBooks" ) )
{
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor( model => @Model.Title )
        </dt>
        <dd>
            @Html.EditorFor( model => @Model.Title )
        </dd>

        <dt>
            @Html.DisplayNameFor( model => @Model.Author )
        </dt>
        <dd>
            @Html.EditorFor( model => @Model.Author )
        </dd>

        <dt>
            @Html.DisplayName( "Book Cover File Image" )
        </dt>
        <dd>
            @Html.TextBoxFor( m => @Model.BookCoverUrl, null, new { type = "file", @class = "input-file" } )
        </dd>

    </dl>
}

And with that we can now dynamically add items and they will uniquely get posted back onto the server.

ASP.NET MVC5 + Twitter Bootstrap

Creating an ASP.NET MVC 5 Project

Model-View-Controller (MVC) is a software architectural pattern that divides software application into three parts.
Model consists of the business logic and functions.
View is the representation of the information. These information can be illustrated through graphs or charts or any of the user interface that the user interacts with.
Controller receives input from view and model.

1. Visual Studio -> New -> Project -> Under Web -> ASP.NET Web Application
2. Choose MVC template — this will create a default template with MVC folders.
Another template is Web API which will add API folder for REST HTTP calls.
ChoosingWebApi
3. Run the app to make sure it’s compiling and building properly.

Twitter Bootstrap 3 Discovery

What is Twitter Bootstrap? Twitter Bootstrap is an open-source tool that helps in creating websites or web applications. This tool includes pre-developed HTML and CSS templates for arranging html components (Grid-System), forms, buttons, charts, and other navigation components that we normally see in a responsive web application.

Some PROS of Twitter Bootstrap:

  • CONSISTENCY
    Who would not want to see a consistent font and style within a web page? Both developers and users would want to see a consistent flow in a project, so Twitter Bootstrap was built to avoid a confusing layout flow in every web page that users will interact.
  • RESPONSIVE
    Whether it is a huge desktop, a really small mobile screen or a phone with a size like a tablet, Twitter Bootstrap got it covered! This tool is developed to have a responsive layout that caters to all the different screen sizes that any user may have.
  • LATEST AND GREATEST
    Twitter Bootstrap was made by really great developers who used the latest libraries out there: CSS3, HTML5, JQuery… etc. The CSS was developed using LESS platform that allows using variables, mixins, functions inside the CSS page to make CSS more themable and extendable.

By default, MVC5 is using the Twitter Bootstrap template by default. That means, the bootstrap.min.js and bootstrap.min.css are already inside the project and we do not need to download it from Twitter Bootstrap’s webpage to use it’s styles.

Grid System

  • Twitter Bootstrap makes the page responsive to phone/tablet/desktop by adding the viewport meta tag:
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
  • Twitter Bootstrap’s grid system scales up to 12 columns.
    This means that all the columns with .col-md-* should add up 12. Any columns after the 12th will be stacked underneath the first 12.
  • Rows are placed inside a class .container for proper alignment.
    <div class="container">...</div>
    
  • Use class .row to create horizontal column groups.
  • Columns are created specifying the number that can add up to twelve. For example, four proportionally sized columns would be: four div with class .col-md-3
    XS = Phones, SM = Tablets, MD = Desktops, LG = Large Desktops
  • GridSystemTable

NOTE: As the browser widens, the smaller-sized classes gets overwritten. As the browser contracts, the larger classes are overwritten.

<div class="row">
    <div class="col-xs-6 col-md-6 col-sm-6">col-xs-6 col-md-6 col-sm-6</div>
    <div class="col-xs-6 col-md-6 col-sm-6">col-xs-6 col-md-6 col-sm-6</div>
</div>
<div class="row">
    <div class="col-xs-4 row-grid">col-xs-4</div>
    <div class="col-xs-4 row-grid">col-xs-4</div>
    <div class="col-xs-4 row-grid">col-xs-4</div>
</div>
<div class="row">
    <div class="col-md-3">col-md-3</div>
    <div class="col-md-3">col-md-3</div>
    <div class="col-md-3">col-md-3</div>
    <div class="col-md-3">col-md-3</div>
</div>
<div class="row">
    <div class="col-xs-8 col-md-8 col-sm-8">col-xs-8 col-md-8 col-sm-8</div>
    <div class="col-xs-4 col-md-4 col-sm-4">col-xs-4 col-md-4 col-sm-4</div>
</div>

Other Good Stuff…

Offsetting columns

To move columns to the right, use “.col-*-offset-*”. The first * depends on the screen size which could be written as “.col-xs-offset-, .col-md-offset-, or .col-sm-offset-“. The second * increases the left margin of column by * columns. For example, “.col-md-offset-4” moves that column over four columns.
offset
As we can see on this example, we could combine the class names “.col-md-4” and “.col-md-offset-3” which defines the width of the column then offsets the column to 3 columns (-offset-3).

Like the grid system example, the offsets follow the 12-column way of how the columns are arranged. An example would be doing “.col-md-4” followed by a div with “.col-md-4 .col-md-offset-4”. Where will the second div be?
nested-offset
So, since the position of the second div (without the -offset-4) is beside the first div, the offset made it so it moved another 4 columns over.

<div class="row">
    <div class="col-md-4">.col-md-4</div>
    <div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
    <div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
    <div class="col-md-3">.col-md-3</div>
</div>

Nesting columns

Inside the .row, we can add a set of .col-md-* inside of an exisiting .col-md-*. To visualize it properly…
nested-row

<div class="row">
    <div class="col-md-9">
        1st row .col-md-9 (Parent Row)
        <div class="row">
            <div class="col-md-6">
                Nested 2nd row .col-md-6
            </div>
            <div class="col-md-6">
                Nested 2nd row .col-md-6
            </div>
        </div>
    </div>
</div>

For this example, the parent row (with a class .col-md-9) has a 9 column-width. Since the next row is nested (with 2 .col-md-6) that add up to 12-columns, their TOTAL WIDTH will only extend up to 9 columns (not 12), but they will be evenly divided because both of them add up to 12 columns.
What I mean by that is…
NestedAndNonNestedRows

<div class="row">
    <div class="col-md-9">
        1st row: .col-md-9
        <div class="row">
            <div class="col-md-6">
                2nd row (Nested): .col-md-6
            </div>
            <div class="col-md-6">
                2nd row (Nested): .col-md-6
            </div>
        </div>
    </div>
</div>
<div class="row">
    <div class="col-md-6">
        (Not Nested) .col-md-6
    </div>
    <div class="col-md-6">
        (Not Nested) .col-md-6
    </div>
</div>

IMPORTANT: Nested rows (even when the column-set adds up to 12 columns) follow the max width of the parent row unlike a non-nested row that can span out to 12-column width.

Push and Pull Columns (Column Ordering)

We use the modifiers .col-md-push-* and .col-md-pull-* to change the order of the grid columns.

<div class="row">
    <div class="col-md-9 col-md-push-3">1st column (col-md-push-3)</div>
    <div class="col-md-3 col-md-pull-9">2nd column (col-md-pull-9)</div>
</div>

This code results to:
pushpullTB

For this example, we can see that we pushed the 1st column to 3 columns to the right and pulled the 2nd column 9 columns to the left. Since the columns are also 9 and 3 column-width respectively, they just switched places.
IMPORTANT: In other words, we use -push- and -pull- to re-organize our column positions. Unlike offsets, when we “push” a column, it does not affect the position of any other column beside it. For example, if there are 2 columns, and only the first column has a “-push-*” class, the 2nd column will stay in the same place and will not be pushed to the right. Offset, on the other hand, pushes everything to the right of the column that has the -offset-* class.

References:

Twitter Bootstrap 2.3.2
Twitter Bootstrap 3

ASP.NET Universal Providers

Earlier this month, I posted about how the ASP.NET membership providers are creating the required database schema for me automagically when I first hit the site.  Here is a quick update to that statement now that I more thoroughly understand what’s going on.

Scott Hanselman does a great job introducing us to the ASP.NET Universal Providers for Session, Membership, Roles and User Profile so I won’t repeat it here.  What I DON’T get from his article is that the Universal Providers are the default for a new ASP.NET MVC3 project (and that they’re not yet supported on Azure).  I hadn’t touched ASP.NET or MVC for multiple years, so I just went along quietly and created a new project, pointed my connection string at a SQL Server and things were all working.  It wasn’t until I published the site to Azure that things fell apart.

The Universal Providers (“DefaultMembershipProvider”) are referenced throughout the web.config for all the different pieces of membership, and here you see it set as the default provider (the one that membership code in the site will look for and use).

  <membership defaultProvider="DefaultMembershipProvider">
    <providers>
      <clear />
      <add name="AspNetSqlMembershipProvider"
            type="System.Web.Security.SqlMembershipProvider"
            connectionStringName="ApplicationServices"
            enablePasswordRetrieval="false"
            enablePasswordReset="true"
            requiresQuestionAndAnswer="false"
            requiresUniqueEmail="false"
            maxInvalidPasswordAttempts="5"
            minRequiredPasswordLength="6"
            minRequiredNonalphanumericCharacters="0"
            passwordAttemptWindow="10"
            applicationName="/" />
      <add name="DefaultMembershipProvider"
            type="System.Web.Providers.DefaultMembershipProvider, 
                   System.Web.Providers, Version=1.0.0.0, Culture=neutral,
                   PublicKeyToken=31bf3856ad364e35"
            connectionStringName="DefaultConnection"
            enablePasswordRetrieval="false"
            enablePasswordReset="true"
            requiresQuestionAndAnswer="false"
            requiresUniqueEmail="false"
            maxInvalidPasswordAttempts="5"
            minRequiredPasswordLength="6"
            minRequiredNonalphanumericCharacters="0"
            passwordAttemptWindow="10"
            applicationName="/" />
    </providers>
  </membership>

This works fine as long as we were developing on our local machines (where the Universal Providers are installed), and even when we’re hitting the SQL Azure database from our local machine (the provider is local, the database is remote – so the code can create the SQL Azure compatible schema on the fly regardless of the DB location).  When the site is deployed to Azure, where the Universal Providers are not installed, you get an error: Unable to find the requested .Net Framework Data Provider. It may not be installed.

It took forever to figure out that this was the problem, and 1 minute to fix it – just switch web.config to use the SQL Providers that are already configured, just not as the default.

  <membership defaultProvider="AspNetSqlMembershipProvider">

 

The bottom line: the Universal Providers are not yet available on Azure servers, so you have to go with the legacy SQL Providers.  These providers, as always, require you to run the ASPNET_REGSQL tool to create the required database schema before you hit the site.

  • Universal Providers: create their required DB schema on first use, do not have the aspnet_xxx prefix on the tables, and do not use any views or stored procedures.
  • SQL Providers: require you to run ASPNET_REGSQL before first use, the tables are namespaced with “aspnet_” in front, and there are views and stored procedures that go along with the tables (all created by the ASPNET_REGSQL tool)