Mar 24, 2008

Finally its here ...

Skype passport 1.0 is out, you can find the simple html page on Chameleon Bulgaria



Online demo: Here



Download page: Here
>

Mar 20, 2008

World's first Skype Passport is almost out ;)

This is a little javascript which will allow your users to easilly register on your site, by filling their contacts automatically from skype (offcourse only few fields are populated, but most registrations require only few fields after all).
Here is a screenshot of this neat little javascript placed on a page:



Note : This works only if your users are using IE (as this thing depends on ActiveX).

The tool will be available for free download at my site : ChameleonBulgaria so visit it regularly ;)

When I publish it, I will also publish a news on the frontend so you can know.
Just a few more hours ;)
.

Mar 19, 2008

Very simple tool to watch ending Sedo Auctions

Few months ago I was interested in the domain trading business. It was interesting to me as it generated 14.2 million dollars back in 2006. It is based on speculla I think. Something like FOREX but not quite.

I registered two domains and placed them on Sedo Auctions.

I was also interested on how other domains are going so I decided to write a small tool. It will stay in your tray and will show you the auctions which are about to end the next 24 hours. The following information is gathered about each auction:

- Domain for sale
- Price
- Currency
- Time left before the auction is closed
- Google PR for each domain

The program is available for download from Chameleon Bulgaria

I decided to put a banner on this program so my domains
for sale are visible to the users (well, after all I spent some time on this program and I would really like ot have some incomes after all ;).

Here is a direct link to the program page on Chameleon Bulgaria may be found
here

Mar 16, 2008

5 minutes C# to dispose your NotifyIcon object

If you have this problem - try calling .Dispose() method for your NotifyIcon explicitly in the FormClosing event:


    
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
     {
        notifyIcon1.Dispose();
     }

Note : this trick may not work if the Application was terminated abnormally. I will investigate that issue when I have some free time and report back what is the best approach on this.
>

Mar 13, 2008

5 minutes to have your web.config keys in order


This time I will not post any C# codes ;). I will only inform you that I am in the middle of the development of two small tools which will (hopefully) make deployers life easier.
The first one is used to create simple web.config plans - you will be able to create plans for your sites and use those plans in the future to check if everything is in order.
The second one is what I call "the player" it will receive those plans and play their recorded actions against selected sites. This way you can always check if some of your sites is still configured properly. After the check is completed - you will be able to export the results to CSV file so you can use them as a checklist.


Another post will be posted here when the tools come out and you will be able to find them (free of charge) on my site ChameleonBulgaria.com, so check it too (by the way the site is Under Construction but I will complete it too, unfortunatelly I am the only person to work on it, but this is also subject to change).


I also plan to develop the ability those tools to receive the site / host name and output file name as a parameters so they can be scheduled easilly to run on their own, so all you will need to do is take a look at the files from time to time to make sure everything is still working smooth.

Mar 7, 2008

Bulgarian IT Boxing - We (.NET team and fans) lost round 2, waiting for round 3 now ...

Last night the second round of Bulgarian ITBoxing took place.

What is ITBoxing?
ITBoxing is an event where developers using different platforms gather and present the advantages of their platform. After all the technologies are presented the audience votes about their favourite technology.

Last night the following technologies were presented (votes included):

Java 73 votes.
.NET 45 votes.
Ruby on Rails 13 votes.
PHP 11 votes.

This was the second round so now Java and .NET are on the top (the first round was for .NET ;). I was disappointed to understand that my technology wasn't first this time.

Round 3 will be held in about a month or so and the topic will be Enterprise development. Hopefully there will be less Java
developers in the audience this time so we can win again ;). I think we deserve it ;).

NOTE: I wasn't in the .NET team, I was in the audience but tried to help with comments against Java ;).

No matter which technology wins I think those events are very helpful for all develeopers, as after all - our work is to complete our job on time and with less efforts. When you attend such events you can inform yourself about which type of tasks are easier to complete with Java, which with .NET, which with PHP and which with Ruby.

Feb 29, 2008

5 minutes C# to build a Zoo with Marker Interfaces.

First of all what is marker interface?
A marker interface is an empty interface which defines no fields, but is only there for reference.

Let's start with the case study and we will go through the example and explain everything.


Case Study : Build a simple Zoo program.
You have a Zoo with few animals - those animals are only fishes and birds. As this Zoo is relatively small it has only one employee to feed all the animals with the appropriate food. The fishes eat food which we will refer to as "fishfood" and the birds eat a food which we will refer to as "grains".

To accomplish this we may create an interface, which identifies the things that are common for both types of animals in the Zoo.

IAnimal.cs

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

namespace MarkerInterface.Objects
{
  
interface IAnimal
   {
    
void Feed(FoodType food);
    
bool Hungry
     {
        
set;
        
get;
     }
   }
}

Ok, we gave the animals the ability to eat, but how will the employee identify what kind of food to feed them with?

Let's first define an enumerator to hold the food types:

Food.cs:

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

namespace MarkerInterface.Objects
{
  
public enum FoodType
   {
     Grains,
     Fishfood
   }
}

Ok, we have the food types now. In order to split the animals in the Zoo in two separate groups we are going to use the Marker Interface, we will define two interfaces to mark which animal is fish and which is bird.

IBird.cs:

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

namespace MarkerInterface.Objects
{
  
interface IBird : IAnimal
   {
    
   }
}

Now let's do the same for the fieshes:

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

namespace MarkerInterface.Objects
{
  
interface IFish : IAnimal
   {
    
   }
}

Now let's have two concrete animals - one for each type:

Heller.cs:

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

namespace MarkerInterface.Objects.Animals
{
  
class Heller : IFish
   {
     #region IFish Members
    
private bool hungry = false;
    
public void Feed(FoodType food)
     {
        
if (food != FoodType.Fishfood)
        {
          
throw new ArgumentException("Heller is a fish and eats only fishfood.");
        }
        
else
        {
          
this.hungry = false;
        }
     }

     #endregion

     #region
IAnimal Members

    
public bool Hungry
     {
        
get
        {
          
return this.hungry;
        }
        
set
        {
          
this.hungry = value;
        }
     }

     #endregion
   }
}

Chicken.cs

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

namespace MarkerInterface.Objects.Animals
{
  
class Chicken : IBird
   {

     #region IBird Members
    
    
bool hungry = false;

    
public void Feed(FoodType food)
     {
        
if (food != FoodType.Grains)
        {
          
throw new ArgumentException("The chicken only eats grains.");
        }
        
else
        {
          
this.hungry = false;
        }
     }

    
public bool Hungry
     {
        
get { return this.hungry; }
        
set { this.hungry = value; }
     }

     #endregion
   }
}

Let's have one employee to feed the animals:

ZooEmployee.cs

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

namespace MarkerInterface.Objects
{
  
class ZooEmployee
   {
    
public delegate void OnAnimalFeeded(string Animal, string FoodType);
    
public event OnAnimalFeeded AnimalFeeded;

    
public void FeedAnimals(List<IAnimal> animals)
     {
        
foreach (IAnimal animal in animals)
        {
          
if (animal is IFish)
           {
             animal.Feed(
FoodType.Fishfood);
            
this.AnimalFeeded(animal.GetType().Name, "fish food");
           }
          
if (animal is IBird)
           {
             animal.Feed(
FoodType.Grains);
            
this.AnimalFeeded(animal.GetType().Name, "grains");
           }
        }
     }
   }
}

NOTE: I added the OnAnimalFeeded delegate and the AnimalFeeded event, so the Zoo employee can report to us when it has feeded an animal.

Let's define the Zoo class:

Zoo.cs

namespace MarkerInterface.Objects
{
  
class Zoo
   {
    
List<IAnimal> animals = new List<IAnimal>();
    
List<ZooEmployee> employees = new List<ZooEmployee>();

    
public Zoo()
     {
        animals.Add(
new Animals.Chicken());
        animals.Add(
new Animals.Heller());

        
ZooEmployee employee = new ZooEmployee();
        
this.employees.Add(employee);
     }

    
public List<IAnimal> Animals
     {
        
get { return this.animals; }
     }
    
public List<ZooEmployee> Employees
     {
        
get { return this.employees; }
     }
   }
}

Now, in the main form of the program we will instantiate the Zoo class, and call its employee to feed all the animals.

On the form I added one button and one RichTextbox. When I click the button the following code will get executed:

        Objects.
Zoo zoo = new MarkerInterface.Objects.Zoo();
        zoo.Employees[0].AnimalFeeded +=
new MarkerInterface.Objects.ZooEmployee.OnAnimalFeeded(Form1_AnimalFeeded);
        zoo.Employees[0].FeedAnimals(zoo.Animals);

What are we doing here - we are simply creating a Zoo, we are using it's first employee (as we said it will always be exactly one emplyee) AnimalFeeded event to report when what animal is feeded and with what food and we are then asking the employee to feed the animals.

The marker interfaces here are used in the ZooEmployee.FeedAnimals() method to help the employee decide which type of food to give to each animal.

As the Chicken inherits from the IBird the employee will feed it with grains. As the Heller inherits from IFish it will be feeded with fish food.

Here is the Form1_AnimalFeeded which is fired each time the employee feeds animals. It will be used to display in the RichTextBox what is our employee doing at the moment:

    
void Form1_AnimalFeeded(string Animal, string FoodType)
     {
        
this.rtbAnimalsFeeded.AppendText(Animal + " was feeded with " + FoodType + "\n");
     }

Here is how it looks like after it was runed:



Hope you understood it ;).

Feb 10, 2008

businesscatalyser - a game?

Well, after I was too bored today I decided to do something interesting. So I made my own game. I decided to buy a domain and park it on the sedo auction, I also listed it for sale.

So here are the rules:
1. Park the domain and try to get as much clicks as possible (no spam or other black techniques).
2. List it also for sale but don't try to sell it for less then 1K EU (just to be more interesting)
3. You may use only home made software and public sites services in order to promote the site.

Here is the site : BusinessCatalyser.com (don't laugh about the name, I wanted to have some very competitive keyword in the domain(business) so the game can be even harder and more interesting.

You may say this is a madness or losing time, but
as I was wondering how to promote this thing I made a little software which you may use in order to promote your sites. It is a small program which takes the words and searches for a sites with similar content, checks the PR of the sites found and reports you where it will be good to write a post.


Here are the basic stats of BusinessCatalyser.com :

SmartPageRank.com says this site costs 0 USD
Sedo.com says it is for sale and has no content, no PR, no links
It currently has 0.00 EU from the parking affair.


If you are interested in this game I will be happy to exchange information with you, just write a comment ...

Thanks for the attention ;)

Feb 9, 2008

sealed class usage

We recently started an internal academy in our company to improve our software development skills. The first meeting was about OOP fundamentals, it was really interesting (thanks Vesko for your efforts!). This question appeared as interesting for me - when should we use the sealed class.

Some collegues guessed it should be used in the most concrete classes, as they will not be used as a base classses, but I don't think so. After all - why should you say : "Hey, don't use this thing as a base class" explicitly after you know it will not be used anyway.

I did soem research on the net about the sealed class usage, it appeared it's common use is for classes with static methods. The example I've found was about Brush and Pen .NET
objects. They are sealed as they have only static fields like : .Blue and so on.

So when you are doing software you may keep in mind that you have that sealed thing to help you limit the inheritance of your classes.

Feb 6, 2008

Is Microsoft the source of all evil or what?

It is very strange, I was searching for a migration tools, just to see how this market is going. I accidently found this thing here:




What's so strange? Some people choose weird domains to run business under. The strange thing happened after I clicked on the link to see what's behind:



Finally I decided to type the url address in my browser to see actual site behind thesource.ofallevil.com and see where it redirected me:

>

Feb 4, 2008

5 minutes C# code to load CSV file into a DataSet


Step 1 : add button for browsing files, a textbox to hold the file name and paste the followin code in the browse button click handler (this code will basically popup a OpenFileDialog, set up to only open files with .csv extension):

             OpenFileDialog ofd = new OpenFileDialog ();
            ofd.Filter =
"CSV Files|*.csv" ;
            
if (ofd.ShowDialog() == DialogResult .OK)
            {
               
this .textBox2.Text = ofd.FileName;
                GetData();
            }

Then we need to get the file from the textbox2 and load it into data set:

      
private void GetData()
       {
            
FileInfo fi = new FileInfo (textBox2.Text);
            
OleDbConnection con = new OleDbConnection ( @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fi.Directory.FullName + ";Extended Properties='text;HDR=Yes;FMT=Delimited'" );
            con.Open();

            
DataSet dsThings = new DataSet ();
            
OleDbCommand cmd = new OleDbCommand ( "SELECT * FROM " + fi.Name, con);
            
OleDbDataAdapter adapt = new OleDbDataAdapter (cmd);
            adapt.Fill(dsThings);
            
this .dataGridView1.DataSource = dsThings.Tables[0];
            
       }

As you can see we use OleDB provider to load the CSV file into the dataset.

Jan 28, 2008

Job Done!

I think I made it finally. The osCommerce 2 vShop import was made this afternoon. Just waiting QA test now.
>

Jan 22, 2008

.NET C# to parse MySQL queries? Impossible? Pavel can make it ;) (with some ifs and buts offcourse ;)

The most interesting task in my career came the end of the last week. As a Vizibility employee I was asked if I can port osCommerce live site to out vShop solution (http://www.vizibility.co.uk/tmenu/vshop.asp) The interesting thing is that I had no access to osCommerce nor did I ever worked with it. What's even more chalenging - osCommerce database was given to me as SQL queries, something like :

drop table if exists table ;
create table table (
-- Some things here ...
);

insert into table () values ( );

As a normal software developer so there were 3 big chalanges:

1. How to parse this SQL thing (it is MySQL) ?
2. How to figure out
the osCommerce Logic ?
3. How to port all those things as a script so it can be applied to our live servers by the support team?


It's really chalanging don't you think? First I thought it will be a good step to install fresh copy of osCommerce, import the products and try to port them as CSV or something. But then I understood it will take too much time, so I decided to parse the SQL queries on my own and store them in a predefined objects like tables, rows and so on and so on. Then I could easilly transfer them as a text files in the format we needed.

And I almost made it - the parsing methods are done (I was able to parse this thing in a day but some bugs still appear).

Seems the more I work on our shopping solution the more easier I can understand other's shopping solutions.

Great task in a great company!

Jan 21, 2008

5 minutes C# code to open Web.Config from Windows Forms application.

In my previous post about IIS, Virtual Directories and Directory Services you saw how can you obtain the sites per IIS instance as well sa all the root virtual directories. Now it is time to show you how can you obtain the Web.Config file for a root directory.

At first glance I thought it will be easy, I thought I will simply need declare the following:

using System.Web.Configuration;

And / or :

using System.Configuration;

Well it's not quite this way. In order to load web.config file from a windows forms application you need to have some kind of context to be used or, in other words, file mapping.

The following method takes two parameters : path to the root directory and DirectoryEntry, representing the root directory
object (you can see my previous post ( Get IIS sites and virtual directories with .NET / C# / Directory Services ) learn how to obtain DirectoryEntry for a web root directory.
And here is the method:

      
List < string []> GetWebConfigAppSettings( string Path, DirectoryEntry entry)
       {
            
List < string []> items = new List < string []>();
            
if (entry.Properties[ "Path" ].Value != null )
            {
               
FileInfo fiWebConfig = new FileInfo (entry.Properties[ "Path" ].Value + @"\web.config" );
               
if (fiWebConfig.Exists)
                {
                  
WebConfigurationFileMap fm = new WebConfigurationFileMap ();
                   System.Collections.
Hashtable props = new System.Collections. Hashtable ();
                  
foreach (System.DirectoryServices. PropertyValueCollection property in entry.Properties)
                   {
                        
string propertyName = property.PropertyName;
                        props.Add(propertyName, property.Value);
                   }
                  
VirtualDirectoryMapping mapping = new VirtualDirectoryMapping (fiWebConfig.Directory.FullName, true );
                   fm.VirtualDirectories.Add(entry.Properties[
"AppRoot" ].Value.ToString(), mapping);
                   System.Configuration.
Configuration cfg = System.Web.Configuration. WebConfigurationManager .OpenMappedWebConfiguration(fm, entry.Properties[ "AppRoot" ].Value.ToString());
                  
foreach ( KeyValueConfigurationElement elmt in cfg.AppSettings.Settings)
                   {
                        items.Add(
new string [] { elmt.Key, elmt.Value });
                   }
                }
            }
            
return items;
       }



The method above will return a List of all in the web.config file (the appSettings section), you can easilly adjust it to fit your needs.

As you can see the magic begins in :

> System.Configuration. Configuration cfg = System.Web.Configuration. WebConfigurationManager .OpenMappedWebConfiguration(fm, entry.Properties[ "AppRoot" ].Value.ToString());


method. You simply need to make some preparations befor ask it to open the web.config.

Note : this code again is written in few minutes and does not pretend to be optimized, you can again use it at your own will.

Jan 17, 2008

Interesting Apple Ad

Recently I came across this link. It's amazing how creative the Apple marketing team is and how they exploit the Apple vs. MS war.

Have fun :)
.

Jan 13, 2008

How much does your site costs?

Recently I cam accross this site : http://www.smartpagerank.com. What impressed me was that this site can estimate (who knows how exactly) how much does your site costs.
Unfortunatelly my blog was estimated to 0$ but that's subject to change :P. I will also put this code into the left side of my site. You can check it out either.
>

Another 5 minutes with C# to post to Google Blogs (Blogger.com) using Google Blogs SDK (2)

I revised the tool a bit, here is how it looks now:





Also I made some refactoring to the code and it looks better now (no more richTextBox1 names ;).
I plan to release this tool in order to help developers blog code to their blogger accounts easier. The next secret I am going to reveal is that I started a toolkit to help you create blog related programs with C# / .NET / Google Blogs API.

For now I am planning to release the program for free, as a Lite version and I plan to spend some more time to create a better looking version with SEO features in it and distribute it for a small fee (something like 10 EU).
The Toolkit will released for free now.

Well that's it. I am looking forward when I will have some more time to develop those
controls and programs to help the Blogger community grow ;)

Jan 10, 2008

5 minutes with C# - Get your blog in TreeView Control

I played a bit more with the Google Blogs Api and was able to create a custom TreeView control to help you get your blog in Hierarchical View.

Here is a screenshot of the TreeView:



The control will be soon released to my site and new blog post will be published to let you know
.

Another 5 minutes with C# to post to Google Blogs (Blogger.com) using Google Blogs SDK

             // Create service to be used for queries
             Service service = new Service ( "blogger" , "blogger-sample" );
            
AtomEntry createdEntry = new AtomEntry ();
            
// Create credentials you should add your blog username
             // and password here
            service.Credentials = new GDataCredentials ( "your_username" , "your_password" );

            
// As I only have one blog to speed up - I am taking it,
             // You can extend here in order to allow the user to
             // select from mutliple
blogs if he / she has.
             Uri firstBlogUri = GetFirstBlogUri(service);
            
            
// If we have the Uri - it's time to actually post.
             if (firstBlogUri != null )
            {
               
// Create FeedQuery and assign Uri.
                FeedQuery query = new FeedQuery ();
                query.Uri = firstBlogUri;

               
// Create Atom Feed from that query.
                AtomFeed feed = service.Query(query);

               
// Create atom entry for the new post
                AtomEntry newPost = new AtomEntry ();

               
// Fill in the post information
                // You need to have a control named richTextBox2 which will
                // contain the post body and a textBox1 control which will
                // contain the post title.

                newPost.Title.Text = this .textBox1.Text;
                newPost.Content =
new AtomContent ();
                newPost.Content.Content = richTextBox2.Text;
                newPost.Content.Type =
"html" ;
                newPost.Authors.Add(
new AtomPerson ());
                newPost.Authors[0].Name =
"Pavel Donchev" ;

               
// Try to publish and report success / fail:
                try
                {
                   createdEntry = service.Insert(query.Uri, newPost);
                }
               
catch ( Exception ex)
                {
                  
MessageBox .Show(ex.Message);
                }
               
if (createdEntry != null )
                {
                  
MessageBox .Show(newPost.Title.Text + " posted successfully!" );
                }
            }

There is also a helper function to retrieve the blog Uri:

      
Uri GetFirstBlogUri( Service service)
       {
            
FeedQuery query = new FeedQuery ();
            
// Retrieving a list of blogs
            query.Uri = new Uri ( "http://www.blogger.com/feeds/default/blogs" );

            
AtomFeed feed = null ;
            feed = service.Query(query);
            
AtomEntry entry = feed.Entries[0];
            
for ( int i = 0; i < entry.Links.Count; i++)
            {
               
if (entry.Links[i].Rel.Equals( "http://schemas.google.com/g/2005#post" ))
                {
                  
return new Uri (entry.Links[i].HRef.ToString());
                }
            }
            
return null ;
       }

Jan 8, 2008

5 minutes C# code to help you blog source ...

As I was unabled to find a reliable editor to convert my code samples to html, I decided to write one. You need two richTextBox components, named richTextBox1 and richTextBox2 and a Button, named button1.

Here is the code you need to put into the button1 click event handler:
       private void button1_Click(object sender, EventArgs e)
       {
            
string oldColor = "-";
            
string newColor = string.Empty;

            
StringBuilder strHtml = new StringBuilder();

            
for (int i = 0; i < this.richTextBox1.Text.Length; i++)
            {
                richTextBox1.Select(i, 1);
               
newColor = System.Drawing.ColorTranslator.ToHtml(richTextBox1.SelectionColor);
               
if ((newColor != oldColor) && (newColor != string.Empty))
                {
                  
if (!oldColor.Equals("-"))
                   {
                        strHtml.Append(
"");
                   }
                   strHtml.Append(
" + newColor + ";\">");
                   oldColor = newColor;
                }
                strHtml.Append(richTextBox1.SelectedText.Replace(
"<", "<").Replace(">", ">"));
               
Application.DoEvents();
            }
            strHtml.Append(
""
);
            
StringBuilder sbNew = new StringBuilder();
            sbNew.Append(strHtml.ToString().Replace(
"   ", "   "));
            richTextBox2.AppendText(sbNew.ToString());
       }


PLEASE NOTE: this code was written in 5 or 10 minutes, it doesn't pretend to be either clean or readable, it simply works. If you want - you can take it, optimize it, use it or whatever, just have in mind it wasn't written carefully ;).

Dec 28, 2007

Get IIS sites and virtual directories with .NET / C# / Directory Services

       public List GetSites(string serverName)
       {
            List Nodes = new List();
            CustomTreeNode tnResult = new CustomTreeNode();
            try
            {
                DirectoryEntry w3svc = new DirectoryEntry("IIS://" + serverName + "/w3svc");
                foreach (DirectoryEntry entry in w3svc.Children)
                {
                   if (entry.SchemaClassName == "IIsWebServer")
                   {
                        CustomTreeNode Site = new CustomTreeNode(entry.Properties["ServerComment"].Value.ToString());
                        this.ServerLoadStart(entry.Properties["ServerComment"].Value.ToString());
/>                        Site.CurrentEntry = entry;
                        Site.ImageIndex = 1;
                        Site.SelectedImageIndex = 1;
                        Site = GetVirtualDirectories(entry, Site);
                        Site.ImageIndex = 0;
                        Site.SelectedImageIndex = 0;
                        Nodes.Add(Site);
                   }
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
            }
            return Nodes;
       }
       private CustomTreeNode GetVirtualDirectories(DirectoryEntry site, CustomTreeNode Parent)
       {
            string VirDirSchemaName = "IIsWebVirtualDir";
            DirectoryEntry folderRoot = site.Children.Find("Root", VirDirSchemaName);
            foreach (DirectoryEntry deChild in folderRoot.Children)
            {
                CustomTreeNode tnFolder = new CustomTreeNode(deChild.Name);
                this.VirtualDirectoryStart(deChild.Name);
                tnFolder.ImageIndex = 0;
                tnFolder.SelectedImageIndex = 0;
                tnFolder.CurrentEntry = deChild;
                tnFolder.ImageIndex = 1;
                tnFolder.SelectedImageIndex = 1;
                Parent.Nodes.Add(tnFolder);
            }
            return Parent;
       }

Here is the result I get after few more hours of work:


Aug 28, 2007

The silent catch

Another of my interesting phrases (or at least I don't know if someboddy used this phrase). What is silent catch?

Silent catch is a term I use for try .. catch block, where the catch does nothing or at least you don't see it to be doing anything.

The first example:
try
{
some unsafe code here ...
}
catch {}

Another example:
try
{
some unsafe code here ...
}
catch (Exception ex)
{
hide something (for example grid or some other control) ...
return;
}

The second example is as bad as the first. It will be underlined by the Microsoft Visual Studio code editor to warn you that the ex object isn't used anywhere within the body of the catch statement.

Today I spent about two hours to investigate why a page doesn't display
one Grid. It appeared to be beried deep inside the system (I mean it was in an ascx control). The problem appeared to be missing view in the database. Unfortunatelly after I couldn't see the exception I was forced to start from the web user interface, first I checked the settings in the application to see if it is not forbidden or something, then I started to debug, to see where this part of the page comes from. After I found it, I needed to see what's going on in the control. So it took me two hours to trace the problem. What if there were an exception with stack trace? 15 minutes of work would have been enough for me to see that the view is missing.

So:
"Try to avoid silent catch statements as they may cost you a lot of efforts to find the problem later (even if you wrote the code on your own)."

Aug 23, 2007

Settings, they are supposed to help ?!?

Yesterday I had a tricky problem. I client of our company complained he can't upload files on our system. I started troubleshooting the problem. Each time I clicked the "Continue" button exception was thrown as if an assembly can not be found. It was pain in the neck. The assembly was something like "System.Web.UI.MobileControls.Adapters" (I can't remember the exact name now but it doesn't matter as we didn't use that assembly at all). I asked a collegue of mine for help (thanks Vesko!). The problem was in Machine.config file so we decided to back it up and comment that provider to see what will happen. It threw an exception, but this time more reasonable. It said there is no disk space. I logged again onto the server to free some more space
and gues what? There were 60GB of free disk space! I started to think where the problem might be and tried to find solution in Google. It finally appeared that the problem is a setting within the OS. Short explanation below:
Windows 2003 Server uses NTFS file system. This file system is capable of maintaining disk quotas for each user. In other words - the administrator may define how much disk space each user can use. It was set to 1 GB for the user, running the service responsible for the upload. So I set it to 3 GB, tested to see if it works and it worked. Then I left the server and asked the administrator to decide how much disk space will be available to the user running the process.

After this space is used again I will know what to do ;).

So I learned very useful lesson - first check the settings and then try to debug or touch the code. In most cases if the code worked before and you know nothing has changed - this means that some resources available to the application before aren't available now OR someboddy changed some setting which was important for your code to run smoothly.

Aug 9, 2007

Surface Fixing



What is surface fixing?


Surface fixing is a phrase I use for a fix, which is implemented in a layer above the layer where it occurs. If we imagine the standart 3-tier architecture and we have a bug in the Data Access Layer, surface fix will be to implement the fix in the Business layer or the Presentation Layer. It is common for junior developers or companies where the things should happen in a matter of hours or days (companies with short deadlines).



Example of a surface fixing:





Let's say we have a page for registering users (Presentation Layer). On user registration this page creates the User object (Business Layer). Sets its properties as necessary, and calls it's Save() method. The Save() method creates

an instance of the UserDAL object (Data Access Layer) and decides whether the task is to create new user or update existing one. Let's say we will create new user. The User Business Object -> Save() method will probably call something like : UserDAL -> InsertUser(long UserID, string UserLogon ....);

Now let's say that the Data Access Layer doesn't escape the single apostrophe in the UserLogonID. Passing parameter as O'Conner or something like this causes exceptions. The question is where should this be fixed?

I see most of you answering : "In the Data Acess Layer offcourse!". That's the best place but if you are working on a small project.

Now ask yourself what will happen if we fix this in a big enterprise system with hundreds of modules / pages referring to that particular routine? After all the other modules / pages are working they will stop working or at least stop working correctly. With other words - your fix will require the whole system to be redeveloped. And what's worse - the QA team will have a lot of work. They will love you for sure :). And to make the things even worse we will imagine that we are near the deadline (which is almost sure after we are testing already). In such cases the Surface Fixing may help.

Below I am giving the advantages and disadvantages of the Surface Fixing.

Advantages:

  • Your fix will not broke anything in the existing modules
  • The fix will only be tested, not the modules which may be affected
  • Ideal to use near deadlines

  • Disadvantages:

  • The fix isn't applied at the right place
  • Conflicts may appear in the future with modules which are working correctly
  • Against the official software development standarts


  • When to use this approach ?

  • When we are developing module in a big system with lot's of other modules which depend on the bug
  • When we are near deadline
  • When we are sure that there will be new version.


  • Conclusion:

    This approach is perfect to fix some bugs in the current version, but consideration to completely fix it in the next versions should be made. It simply is not right to use this approach as a regular fixing guidance. In the software development and the 3 or more tier models the above layes should only see the previous and depend on it. And what's more important - the above layer should get the data as expected.

    Jul 8, 2007

    New company - new luck :)

    Yep, only in few hours I will be on my new desk in my new company :). I am very excitet about this. The new company is Vizibility and it is developing web modules. At first glance it seemed very very interesting with all the young people there. They were very hospitable on the interview and managed to earn my complete confidence. It seems that I did that too. After I met their requirements they met mine too.

    So it is a big day today :). Wish me luck
    !

    Jun 30, 2007

    Skype API (Skype4COM) + Google MAPS API = ? [3]

    As a part of my Google Maps and Skype API I wanted to add custom icons to represent different objects on the map (currently I made it for the bus stations).

    The picture bellow is the result :



    It was again easy - we simply create GIcon object. Then we assign the URL of the image to be used, size of the icon and point, where the info window will appear :


    Code


    icon = new GIcon();
    icon.image = 'BusFine.gif';
    icon.iconSize = new GSize(39, 60);
    icon.iconAnchor = new GPoint(5, 34);
    icon.infoWindowAnchor = new GPoint(5, 2);




    Then we only need to add this object as a second parameter in the GMarker object constructor.



    Code


    // point is a GPoint object, representing the location the marker
    should be
    // displayed.
    marker = new GMarker(point, icon);



    Note : Some browsers may need some more settings in order to display the custom icon correctly, the example above is for IE.