Custom Headers for Content-Type in the web.config file? Don’t do it.

Life’s about lessons learned, and here is one lesson I learned that I hope will save someone else from hours of frustration.  As I scoured the web looking for ways to improve the SEO of one of my sites and conform to standards, I must have run across some article, post, or tip which suggested I add this to the web.config file:

<configuration>
  <httpprotocol>
    <customheaders>
      <add name="Content-Type" value="text/html; charset=utf-8"></add>
    </customheaders>
  </httpprotocol>
</configuration>

I probably did it because I didn’t want to type out:

<head>
  <meta name="Content-Type" value="text/html; charset=utf-8" />
</head>

on every page and because of maintenance reasons.  Well, everything was fine and dandy until I decided to convert one of my .aspx pages to .html and write my own AJAX code.  I didn’t even notice the problem until I tried pulling up my site in Internet Explorer as I do most of my testing on Google Chrome.  Everything displayed fine on Google Chrome, but on Internet Explorer, it broke the CSS of the page and was asking you if you wanted to open or save the default document instead of rendering it.  I pulled my hair out researching and troubleshooting the problem (checked to see if it was a browser compatibility issue, due to caching, settings enabled/disabled, etc.) and almost gave up, but I finally figured it out when I reviewed the console from Google Chrome’s Developer tools and noticed I was getting these strange error messages:

Resource interpreted as Image but transferred with MIME type text/ html
Resource interpreted as Script but transferred with MIME type text/ html
Resource interpreted as Stylesheet but transferred with MIME type text/ html

It was adding HTTP headers to all my links which caused Internet Explorer to interpret them incorrectly.  Once I removed it, my site rendered correctly again on Internet Explorer.  I also learned there is a correct way of adding HTTP headers for charset according to W3C.

For ASP and ASP.Net pages, you can add this line to the page:

< %Response.charset="utf-8"%>

Or you can add this to the web.config file:

<configuration>
  <system .web>
    <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="auto" uiCulture="auto"></globalization>
  </system>
</configuration>

C# Tutorial: Saving the State of a Bootstrap Collapsible Panel Using JavaScript and Cookies

In this tutorial, I will show you how you can cause a browser to remember the state (open or closed) of a Bootstrap collapsible panel using C#, JavaScript, and cookies.  First, open a new project in Visual Studio by navigating to File -> New -> Project… (or hit Ctrl+Shift+N).

Visual Studio New Project

Next, I will select Templates -> Visual C# -> Web -> ASP.NET Empty Web Application and name the project CollapsiblePanelDemo.  I will also check the option to Create a directory for solution and hit the OK button to continue.

CollapsiblePanelDemo Project

Now, I will add an ASP.NET Web Form page to my project by right clicking the project name and selecting Add -> Web Form.  In the Specify Name of Item window, I will type in Default and then click on the OK button.

Add Web Form

In the Source view mode, I will add the following lines of code.  Place this in the HTML header section:

<title>CollapsiblePanelDemo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" type="text/css" />

Source View

And place this code right above the </body> tag of the page:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

These are the Bootstrap libraries which will allow you to create a collapsible panel using relative simple markup.  Let’s start by placing a button on the page.  Place this piece of code in between the <form> tags:

<div class="container">
<button type="button" class="btn btn-primary" data-toggle="collapse" data-target="#Panel1" id="panel1State" onclick="setCookie('Panel1')">Panel 1</button>
</div>

Let’s add another button by placing this piece of code underneath the first button:

<button type="button" class="btn btn-primary" data-toggle="collapse" data-target="#Panel2" id="panel2State" onclick="setCookie('Panel2')">Panel 2</button>

Add a line break and create the panels by adding this code right after the second button:

<br />
<div id="Panel1" class="collapse">This is Panel 1.</div>
<div id="Panel2" class="collapse">This is Panel 2.</div>

Here’s a quick breakdown of how the panels work.  The panels are created using the <div> tag and to differentiate the panels, we use the id attribute.  The data-target attribute in the <button> tag references the id value of the panel it’s supposed to control.  The onclick attribute in the <button> tag will be used later to call a JavaScript function which will place a cookie on the computer for the duration of the session to remember the last “state” of the panel.  Go ahead and hit F5 at this point to compile your application so that you can test out how the buttons currently work.

Test Run 1

Now, let’s write some JavaScript that will help your application remember the last state (open or closed) of the panel.  In the Solution Explorer window and under Solution, right click on “CollapsiblePanelDemo” and navigate to Add -> JavaScript file.  Name the file panelState and click on the OK button.

Add JavaScript File

Enter the following code in the file and save it:

function getCookie(cname) {
  var name = cname + "=";
  var ca = document.cookie.split(';');
  for (var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') c = c.substring(1);
    if (c.indexOf(name) != -1) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

function setCookie(sectionName) {
  var lastState = getCookie(sectionName);
  if (lastState == "" || lastState == "off") {
    document.cookie = sectionName + "=on";
  }
  else {
    document.cookie = sectionName + "=off";
  }
}

function setState() {
  if (getCookie("Panel1") == "" || getCookie("Panel1") == "off") {
    document.getElementById("Panel1").className = "collapse";
  }
  else {
    document.getElementById("Panel1").className = "collapse in";
  }

  if (getCookie("Panel2") == "" || getCookie("Panel2") == "off") {
    document.getElementById("Panel2").className = "collapse";
  }
  else {
    document.getElementById("Panel2").className = "collapse in";
  }
}

One function gets the cookie (i.e. reads the data), another sets it, and the last function is used to determine the last state the panel was in (i.e. open or closed).  Let’s add a reference to this JavaScript file by adding this markup right above the </body> tag of our page:

<script src="panelState.js"></script>

We also add an onload event in the <body> tag to call the setState() function:

<body onload="setState()">

Now, let’s add a Submit button that will initiate a post-back.  Drag an ASP.NET button control on to the form and place it right under the second button.  Change the ID to “submitButton” and Text to “Submit“.  I’ll also add this attribute (CssClass=”btn btn-primary”) to the button control for styling.  And that’s it.  Hit F5 to compile and run your application to test it.  You’ll notice that when you click on a Panel button and then click on the Submit button or if you reload the page that the browser will remember the last state (open or closed) that the panel was in and keep it that way.  This behavior will be in effect for both regular load and post-back operations until the browser is closed.  If you’d like to review the code, you can download the entire Visual Studio project using the link below:

CollapsiblePanelDemo

C# Tutorial: Calling Javascript from the Code Behind (.cs) File

In this short tutorial, I will show you how you can call Javascript from your code behind (.cs) file when programming in C#.  It came about because I was trying to find a way to display content in a new window after clicking a button.  So here it is.  (Please note that I am using Visual Studio 2012 and the ASP.NET 4.5 Framework in my examples.)

First, open a new project in Visual Studio by navigating to File -> New -> Project… (or hit Ctrl+Shift+N).

Visual Studio New Project

Next, I will select Templates -> Visual C# -> Web -> ASP.NET Empty Web Application and name the project SampleCode.  I will also check the option to Create a directory for solution and hit the OK button to continue.

SampleCode Project

Now, I am going to add the App_Code folder to my project because I want to create a helper class for organization reasons.  To add this folder, right click on the project name (SampleCode) in the Solution Explorer window and navigate to Add -> Add ASP.NET Folder -> App_Code.

App_Code Folder

To add the class, right click on the App_Code folder you’ve just created and navigate to Add -> Class…  I’ll go ahead and name this class BrowserUtility.cs and click on the Add button.

BrowserUtility Class

To make sure this class gets compiled into an assembly that I can use later, I’ll highlight the BrowserUtility.cs file under the App_Code folder, and in the Properties window, I will change the Build Action from Content to Compile.

Compile Option

In the class itself, I will import the System.Text namespace so that I can use the Stringbuilder class to create my Javascript string.  My class will just contain one public static method called OpenInNewBrowserWindow which takes one string as a parameter and returns a string as a result.  Here’s what the code looks like:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace SampleCode.App_Code
{
  public class BrowserUtility
  {
    #region Methods
    public static String OpenInNewBrowserWindow(String url)
    {
      StringBuilder sb = new StringBuilder();
      sb.Append("<script type = 'text/javascript'>");
      sb.Append("window.open('");
      sb.Append(url);
      sb.Append("','','width=1024,height=768')");
      sb.Append("</script>");

      return sb.ToString();
    }
    #endregion
  }
}

Now, I will add an ASP.NET Web Form page to my project by right clicking the project name and selecting Add -> Web Form.  In the Specify Name of Item window, I will type in Default and then click on the OK button.

Specify Name of Item Window

This will create a Default.aspx page.  Double click it to load it in your Visual Studio IDE and then switch to Design View.  Drag a button control onto the page, set the text to something like “Open Page“, and set the ID of the button to something like “openPageButton” if you’d like.  Following the same steps above, create another Web Form page called “HelloWorld” and type in “Hello World!” on the page.  Switch back to the Default.aspx page and double click on the openPageButton button to create a button Click event.  This will open the Default.aspx.cs (code behind) file and create a method called protected void openPageButton_Click(object sender, EventArgs e).  On top, place a using statement to load your custom assembly (i.e. using SampleCode.App_Code) and place the following code within this method:

String newWindow = BrowserUtility.OpenInNewBrowserWindow("HelloWorld.aspx");
ClientScript.RegisterStartupScript(this.GetType(), "script", newWindow);

The ClientScript.RegisterStartupScript method will allow you to execute your Javascript code and can be used for other types of scripts as well.  You entire code behind file should look something like this:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using SampleCode.App_Code;

namespace SampleCode
{
  public partial class Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void openPageButton_Click(object sender, EventArgs e)
    {
      String newWindow = BrowserUtility.OpenInNewBrowserWindow("HelloWorld.aspx");
      ClientScript.RegisterStartupScript(this.GetType(), "script", newWindow);
    }
  }
}

Finish building your application by navigating to Build -> Build Solution or hit Ctrl+Shift+B.  Redirect focus to the Default.aspx window and then hit F5 to launch and test your application.  Make sure you disable any pop-up blockers when you click on the “Open Page” button, and you can see your Javascript working in action.