Google
 

Friday, August 1, 2008

Validating SMTP host information

This is a simple class to check if a connection to SMTP host is possible. It can be useful in case of gathering user input and the user is required to enter a valid smtp host.

The idea is simple, open a TCP connection to the host, and read the initial welcome message sent by the smtp host, it should start with response code 220.
I everything is ok, we need to end the sesion by sending QUIT command and close the connection.
For more information check RFC 821 SIMPLE MAIL TRANSFER PROTOCOL

I used Visual C# 2008 Express edition to build this example. You can check the code below, or download the code with a test application from this link:




public static class SmtpChecker
{
public static bool Check(string host,int port,out string welcomeMessage)
{
try
{
using (TcpClient smtp = new TcpClient(host, port))
using (StreamReader reader = new StreamReader(smtp.GetStream()))
{
welcomeMessage = reader.ReadLine();

//validate the reasponse
if (welcomeMessage.StartsWith("220", StringComparison.InvariantCulture))
{
//Send QUIT as recommended by RFC 821
try
{
using (StreamWriter w = new StreamWriter(smtp.GetStream()))
{
w.WriteLine("QUIT");
w.Flush();
string result =reader.ReadLine();
}
}
catch
{}

return true;
}
else
{
welcomeMessage = "";
return false;
}
}
}
catch (Exception)
{
welcomeMessage = "";
return false;
}
}
}

Friday, June 20, 2008

Converting a colored image to gray scale using C#

This is a simple method that creates a gray scale image from a colored image in C#:

public Image ToGrayScale(Image img)
{
Bitmap bitmap = new Bitmap(img);

for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
Color pixelColor = bitmap.GetPixel(i, j);
byte r = pixelColor.R;
byte g = pixelColor.G;
byte b = pixelColor.B;

byte gray=(byte)(0.299*(float)r+0.587*(float)g+0.114*(float)b);
r = g = b = gray;
pixelColor = Color.FromArgb(r, g, b);

bitmap.SetPixel(i, j, pixelColor);
}
}

Image grayImage = Image.FromHbitmap(bitmap.GetHbitmap());
bitmap.Dispose();
return grayImage;
}


The whole magic is in this line of code:

byte gray=(byte)(0.299*(float)r+0.587*(float)g+0.114*(float)b);

It extracts the Luminance component of the color in the YCbCr color system which represents the intensity of the image.

The rest is easy, all color components (R,G,B) will be the same for the image to be a gray scale.

Monday, June 16, 2008

I'm an Elite member in CodeGuru forums !!

After 2048 posts to the CodeGuru forums, I'm now an elite member :)
My journey with Code Guru has started years ago (I joined on April 5th, 2002) and I'm also an article reviewer.
Proud to be a member of this awesome community!!

BTW: I post using the nickname hspc

Wednesday, May 28, 2008

"Page not found" error after installing IIS

After you install IIS on a machine that has .net framework installed and you open an ASP.NET page, you will probably get a "Page not found - 404" error.
This is because IIS did not (recognize) the installed .net framework. You simply need to run this command line:

aspnet_regiis -i

You can run it by opening the .NET Framework SDK command prompt or by changing the current directory to "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727" and run the command. (The path may differ according to the .net version installed)

Friday, May 16, 2008

How to check query syntax programmatically

A nice feature in MS SQL Server Management studio or the old good query analyzer is the ability to check query syntax before executing it by pressing (Parse) or (Ctrl+F5).

You also can provide this functionality in your application in case your application creates queries on the fly or has a query designer.

This can be done using the PARSEONLY option. Queries that run while PARSEONLY option is ON are parsed but not executed, For example:

SET PARSEONLY ON
Go
Select * from dbo.Books
Go
SET PARSEONLY OFF


The above Select will not be executed, it will only be parsed, the result will be:

Command(s) completed successfully.

Without returning any data.

It's simple, open the database connection, execute "SET PARSEONLY ON", then execute your query, then "SET PARSEONLY OFF"

Saturday, April 26, 2008

EDC: VS2008 New Enhancements

In this post I'll try to shed some light on what Chad Hower covered in his edc2008 session :"VS2008 New Enhancements".

The new keyword "var":
It's both used in LINQ expressions and when using anonymous types (more about them later). It also can be used in any regular variable declaration and initialization, for example:

StringBuilder b = new StringBuilder();
b.Append("abc");
var varB = new StringBuilder();
varB.Append("abc");


In the above example, var keyword was used instead of the StringBuilder class name in the second declaration. And the StringBuilder is used regularly. What worth mentioning is:


  • Some ex-vb developers may think that var is the same as the vb6 Variant datatype, which will cause some performace degradation when calling methods due to late binding. This is not true. The compiler replaces the var with the type initialized in the RHS. So the compiler output of these 2 lines is the same:

    StringBuilder b = new StringBuilder();

    var b = new StringBuilder();
    We just saved some keystrokes :).

  • VS2008 has full intellisense support for var. as you can see in the screenshot:


LINQ:

Using Language Integrated Query with collections can make many of programming tasks easier, like searching for an object or objects in a collection that meet a certain criteria.
For example, if we have a List< string > and we want to find all strings that start with the letter 'S', this is the old way to do this :

List< string > found=new List< string >();
foreach (string s in items)
{
if (s.StartsWith("S"))
found.Add(s);
}

Using LINQ:

var found = from s in items
where s.StartsWith("S")
select s;

Ok, more value can be gained if you need to get them sorted by length:

var found = from s in items
where s.StartsWith("S")
orderby s.Length
select s;


Some people may think that the 'var' keyword is what indicates a LINQ expression, but no, it's actually the 'from'.

A good place to think about using LINQ is where you usually use for and foreach.

LINQ is a new feature of C# v3.0 and VB.NET v9.0

Anonymous types:
I'll talk about Anonymous types usage in LINQ, although there are other cases when are useful.
In the above LINQ example, what if we don't need to get the result as a collection of complete objects of the original collection, and we just need one or two attributes (just as we can select just a few columns from a SQL database, not all columns from the table).
Anonymous types can be used in this case:

var found = from s in items
where s.StartsWith("S")
orderby s.Length
select new { value = s, length = s.Length };


Here, we created a new type on the fly, it has 2 properties: value which is a string and length which is an integer.
But how to iterate on found when we don't know the type of the objects it holds (remember, it's anonymous). This is where var comes to be useful again:

foreach (var s in found)
{
Console.WriteLine(s);
}



Others:
Chad talked about other thinks like OBA (Office Business Applications), WPF. The most important thing is that WPF works fine with Winforms. Winforms can host WPF components.

A very interesting presentation that Chad has shown for us was the History of Microsoft Office Download it and enjoy !!
Besides being funny, it shows how MS Office navigation had to evolve.


Chad just scratched the surface, but left us hungry for more knowledge about the existing new features.

Friday, April 11, 2008

Another place when NULL gets tricky

Dealing with NULLs in SQL causes confusion in many cases. Two good articles cover a lot about NULLs in SQL server: 4 Simple Rules for Handling SQL NULLs and Gotcha! SQL Aggregate Functions and NULL.

I this the latest should have covered another situation, when aggregate functions return NULL in case of not satisfying the where condition.
Let's take this Books table as an example:

ID Title Price
--------------------------------
1 C# 10
2 Database 15
3 VB6 30
3 VB.net 35

When you want to get the sum of all books that start with 'vb', you simply use SUM function like this:

Select sum(Price) from Books where title like 'vb%'

And the result would be 65

One may expect that if he asks for the sum of c++ books prices, the result will be zero (as we have none). for example, this query returns zero:

Select count(Price) from Books where title ='c++'

But with sum:

Select sum(Price) from Books where title ='c++'

The result is NULL. Why? Because, using the same logic described in the above articles, SQL will consider this as an absence of data (It couldn't determine the total price since it did not find any prices) if that makes sense.

This can cause issues when trying to read the value returned by this query in the application which expects a float value. A simple remedy for this would be using COALESCE or ISNULL: (I prefer to use COALESCE since it is standard.)

Select COALESCE(sum(Price),0) from Books where title ='c++'
Select ISNULL(sum(Price),0) from Books where title ='c++'


The result in this case is zero as desired.