If you go to Build-> Publish Web Site menu on Visual Studio 2005, you will find this publishing screen:

If you UNCHECK the "Allow this precompiled site to be updatable", all the aspx pages within the projects will be generated empty. To be more exact, you will find the following unique line on them:

This is a marker file generated by the precompilation tool, and should not be deleted!

If you compare this screenshot:

with this one:

you will realize how the first was published allowing ASPX pages to be updated and the second not (notice how in second screenshot, all the ASPX files have 1kb file size)

Don't worry!, All HTML markup and inline code is compiled into assemblies on the bin folder, and it is correctly executed and rendered when the page is requested.

This way, nobody would be able to change either code or HTML content after the publishing is done!

AddThis Social Bookmark Button

I am sure you know how to add the predefined TextBox or ComboBox controls to a Windows Forms context Menu:

Just wanted to quickly show you how you can add your own custom controls to that context menu by using the ToolStripControlHost class, like this (the yellow panel is a user control):

Here is a short video:

And here is the code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
    public partial class Form1 : Form
        public Form1()

            //instance my control
            UserControl1 c = new UserControl1();

            //pass as parameter to ToolStripControlHost instance
            ToolStripControlHost host = new ToolStripControlHost(c);

            //add ToolStripControlHost object to context menu. simple!


AddThis Social Bookmark Button

ASP.NET MVC Validation of viewstate MAC failed error

Posted in MVC | ASP.NET | .NET 3.5 at Saturday, 13 December 2008 02:30 GMT Standard Time

If you get a Validation of viewstate MAC failed error on ASP.NET MVC, before trying to hard code your <machineKey attribute in web.config, disabling the keying of viewstate

  <pages enableViewStateMac="false" />

, or any other literature you may want to check if the page you are posting data from has two "<form" attributes (the one hard coded on the page and the one created with Html.BeginForm()). If you play with master templates and have to merge some MVC pages with tradicional ASP.NET you may get to that error.

It took me a while to find the solution...

Did this post save you some time? post it. I'm curious. :) thanks.

AddThis Social Bookmark Button

Dynamic DataGridView filtering in C#

Posted in .NET 2.0 | .NET UI Controls | DataGridView at Wednesday, 03 December 2008 21:31 GMT Standard Time

In a few lines of code, we can convert a DataGridView control in a powerfull fully searchable control with dynamically generated filters for each column of field the DataGridView is binded to.

How does it work?

  1. The DataGridControl is binded to the datasource.
  2. The user hits the button (or shortcut) to start the dynamic filtering feature.
    1. A new form is dinamycally generated on top of the DatagridView control (it has some transparency on it so you can still see the DataGridView data on the background)
    2. The form contains several textboxes, one per each column or field the DataGridView datasource contains (you can change that behaviour)
    3. When the user starts entering text in any of the textboxes, the filter condition is applied to the underlying datasource (for every keystroke) so you can see how the filtered data looks on the DataGridView as you are typing.
    4. You can, of course define filters for one or more textboxes (fields) at the time, so you can work with multiple filters for many columns/fields.
  3. You can choose whatever you create a dynamically generated search form that contains all the fields on DataGridView datasource, or the ones of your choice (video and example code shows both cases).


This screenshot shows the dynamically search form generated with all the fields of the underlying DataGridView

This screenshot shows the dynamically search form generated with some of the fields of the underlying DataGridView

Demo Video

(sorry about the video quality. if you are interested, please download the demo. it may be worthy)

Some code:

        /// Build texbox controls for dinamyc search form based on fields collection
        private void BuildControls(List fields) {
            int top = 10;
            bool focused = false;

            #region Loop for each field
            foreach (field f in fields)
                Label label = new Label();
                label.Text = f.FriendlyName + ":";
                label.Top = top;
                label.Left = 5;
                label.AutoSize = true;

                TextBox textbox = new TextBox();
                textbox.TextChanged += new EventHandler(textBox_TextChanged);
                textbox.Tag = f.Field;
                textbox.Top = top;
                textbox.Left = 68;
                textbox.Width = this.Width - 80;
                if (!focused) {

                    textbox.Focus(); //the first control focused
                    focused = true;
                top += 35;

            this.Height = top + 30;

  // Raise event to parent form if textbox content changes
        private void textBox_TextChanged(object sender, EventArgs e)
            if (TextChanged != null)

        #region Shortcuts
        private void frmSearch_KeyDown(object sender, KeyEventArgs e)
            if ((e.KeyCode == Keys.Escape) || (e.KeyCode == Keys.Enter))

namespace dynamicGridFilter
    /// This struct contains information about each field to be filtered along with filter value, if exists.
    public struct field {
        public string Field;
        public string FriendlyName;
        public string Value;

namespace dynamicGridFilter
    public delegate void SearchContextChangedHandler(List fields);

Complete source code available to download:

Includes full source code and compiled binary (use it at your own risk)
dynamicGridFilter.zip (50,23 KB)

What's next?!

If could have gone all the way up to creating a custom control that inherits from DataGridView and has all the logic embedded. Well, you have here all you need for doing it yourself, so don't call me lazy! :P

Comments are welcome!

AddThis Social Bookmark Button

Simple download protection for files and document using ASP.NET / C#

Posted in .NET 2.0 | Authentication | Security at Monday, 24 December 2007 14:36 GMT Standard Time
Really really simple. Feel free to write your own custom authentication method to fit your project context.

This is download.aspx:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="download.aspx.cs" Inherits="download" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Download Page</title>
    <form id="form1" runat="server">

and this is the code behind that file:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class download : System.Web.UI.Page 

    /// Show error to user and close response object.
    private void WriteError(string error) {

    /// Check authentication ticket
    private bool Authenticated() {
        //whatever is a session ticket, membership provider base, container in a coded URL querystring parameters, etc..
        return true;    

    private string GetRepositoryFolder() {
        System.Configuration.AppSettingsReader r = new AppSettingsReader();
        return r.GetValue("RepositoryFolder", typeof(string)).ToString();                

    protected void Page_Load(object sender, EventArgs e)
        if (!Authenticated()){
            WriteError("You are not allowed to download this file");
        else if (Request.QueryString["id"] == null)
            WriteError("Missing parameter : id");
        string filePath = System.IO.Path.Combine(GetRepositoryFolder(),Request.QueryString["id"]);
        System.IO.FileInfo file = new System.IO.FileInfo(filePath);
        if (!file.Exists)
            WriteError("File doesn't exists");
        else {
            Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
            Response.AddHeader("Content-Length", file.Length.ToString());
            Response.ContentType = "application/octet-stream";
If successfully authenticated, you will be able to directly download the file:

If not, you will get an error message:

You are not allowed to download this file

AddThis Social Bookmark Button

Querying Youtube API using C#

Posted in .NET 2.0 | Google API | YouTube at Thursday, 20 December 2007 22:40 GMT Standard Time

This example shows how to use Google Data API to query and obtain videos from YouTube. There is also a downloadable zip file with the example in ASP.NET / C#.

  1. First of all, you need to download the Google Data APIs Client Libraries.
  2. Secondly, use the following namespaces:
    using Google.GData.Client;
    using Google.GData.Extensions;
  3. Use the service by querying by tag, or by search (you can also query related items, etc..):

        //by tag
        //feel free to change number of items, by there is a limit of 50, I believe. 
        //If you want to retreive more, you have to do a loop (retrieve 1-50, then 51 to 100, etc)
        protected void btoGo_Click(object sender, EventArgs e)
            string url = "http://gdata.youtube.com/feeds/videos/-/" + this.txtTag.Text;
            AtomFeed myFeed = GetFeed(url, 1, 20);
        //by search
        //feel free to change number of items, by there is a limit of 50, I believe. 
        //If you want to retreive more, you have to do a loop (retrieve 1-50, then 51 to 100, etc)
        protected void btoSearch_Click(object sender, EventArgs e)
            string url = "http://gdata.youtube.com/feeds/videos?q=" + this.txtSearch.Text;
            AtomFeed myFeed = GetFeed(url, 1, 15);
  4. Use the following methods, or similars to get and display the Feed:

        /// Create and returns and Google.GData.Client.AtomFee from url with the specific start and number of items
        private static AtomFeed GetFeed(string url, int start, int number)
            System.Diagnostics.Trace.Write("Conectando youtube at " + url);
            FeedQuery query = new FeedQuery("");
            Service service = new Service("youtube", "exampleCo");
            query.Uri = new Uri(url);
            query.StartIndex = start;
            query.NumberToRetrieve = number;
            AtomFeed myFeed = service.Query(query);
            return myFeed;
        /// Renders feed in example aspx page
        private void DisplayFeed(AtomFeed myFeed)
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (AtomEntry entry in myFeed.Entries)
                #region render each
    Title: "); sb.Append(entry.Title.Text); sb.Append("
    Categories: "); foreach (AtomCategory cat in entry.Categories) { sb.Append(cat.Term); sb.Append(","); } sb.Append(RenderVideoEmbedded(getIDSimple(entry.Id.AbsoluteUri))); sb.Append("
    Published on: "); sb.Append(entry.Published); #endregion } this.lblResults.Text = sb.ToString(); } private string RenderVideoEmbedded(string idSimple) { return string.Format("
    ", idSimple); }
Related resources:

Download example web site project in C#:
youtubeAPIExample.zip (65,91 KB)

AddThis Social Bookmark Button

Inheriting from System.Exception or System.ApplicationException?

Posted in .NET quirks at Monday, 17 December 2007 18:02 GMT Standard Time
Yes, there is a bit of confusion about this (also read this post).

I understand that the right way to create your application specific exceptions classes is to inherit from Exception class:
public class MyCustomEx : System.Exception{
   //class implementation
And if in any case you have to throw a general application exception that has not specific type, throw a System.ApplicationException:
throw new System.ApplicationException("Error retrieving data. The web service may be down");

AddThis Social Bookmark Button

Using a RAM drive to compile Visual Studio .NET projects

Posted in .NET 2.0 | Performance | Productivity | Visual Studio 2005 | RAM disk at Saturday, 15 December 2007 10:18 GMT Standard Time
(updated 22 dec 07)

After reading some blog posts like this I decide to test on my computers how important is hard disk speed in order to increase your productivity when compiling Visual Studio solutions with more than a few project.

I also wanted to see the gain if I placed my solution (more than 25 projects) in a RAM drive disk instead of the hard disk (be sure you backup frecuently if you do that, or get one of this things to avoid data lost).

In order to create a RAM drive, I download the trial version of Virtual Hard Drive Pro
 from FarStone.

There are the results:

1. Environment hardware information

My desktop:
  1. CPU: AMD Sempron, 1800 MHz
  2. RAM: 2 x (1 Gb Kingston)
  3. Hard disks (2):
    1. System: ATA-100 40 Gb Barracuda 7200 rpm. Average seek: 8.5 ms. Buffer size: 2Mb. Average read speed: 40 Mb/second (*).
    2. Data and code: SATA 200 Gb Barracuda 7200 rpm. Average seek: 8.5 ms. Buffer size: 8 Mb. Average read speed: 50 Mb/second (*).
  4. RAM drive speed (read): 900 Mb/sec
My laptop (Toshiba Satellite Pro M70):
  1. CPU: Intel Pentium Celeron 1.73 Ghz
  2. RAM: 2 x (512 Mb Toshiba)
  3. Hard disk (1) : Toshiba 5400 rpm. Average read speed: 30 Mb/second (*)
  4. RAM drive speed (read): 1500 Mb/sec
* (Hard disk speed tests have been done with HD_Speed from www.steelbytes.com)

2. The Microsoft Visual Studio solution

A Microsoft Visual Studio .NET 2005 solution with 26 projects (Windows Forms and Windows library projects mainly), in C#.

3. Results


Desktop machine:

a) Compilation on hard disk (no RAM Drive installed yet): 72 seconds*
b) Compilation on a 500 MB RAM Drive : 71 seconds*

Laptop machine:

a) Compilation on hard disk (no RAM Drive installed yet): 65 seconds*
b) Compilation on a 400 MB RAM Drive : 32 seconds*

*(average of three compilations)

4. Conclusions:

Seems like my desktop doesn't have much processor power, and the bottleneck is mainly on the CPU, since there is not much different results on readig from a 50 Mb/seconds hard disk or from a 900 MB/second one (the RAM Drive)

My laptop, instead has a slower disk drive but more processor power, so there is a lot of difference between compiling from hard disk and RAM drive. (it took half the time on the RAM disk - also RAM disk read speed is higher than in the desktop)

I still will do more tests with some other combinations of CPU and hard disk..

Feel free to do the above tests yourself and share the results.

  • 22 dic 07: Added test with laptop. Desktop tests done again.

AddThis Social Bookmark Button


Ivan Loire
Iván Loire (Zaragoza, Spain)

ASP.NET MVC Freelance and Node.js developer

www: home page

View Ivan Loire's profile on LinkedIn
VitaminasDev. Formación software / Software training - Zaragoza
twitter: @ivanloire

On this page...

Recommended books



<2009 January>


Recommended .NET blogs


Feed Icon