News


Check this out- I was working on a menu for a web site and used a series of ASP:Hyperlink objects to display it.

So here's my menu:

<div id="navigation">
    <asp:HyperLink ID="HyperLinkHome" NavigateUrl="~/Default.aspx" runat="server">Home</asp:HyperLink>
    <asp:HyperLink ID="HyperLinkNewRequest" NavigateUrl="~/Default.aspx" runat="server">New Request</asp:HyperLink>
    <asp:HyperLink ID="HyperLinkMyDepartment" NavigateUrl="~/Default.aspx" runat="server">My Department</asp:HyperLink>
    <asp:HyperLink ID="HyperLinkSearch" NavigateUrl="~/Default.aspx" runat="server">Search</asp:HyperLink>
</div>

And here's my CSS:

#navigation
{
    border: 1px solid #c35f11;
    background-color: #e4a258;
    padding: 2px 0 2px 0;
}
#navigation a
{
    font: bold 13px/1.0em Verdana;
    color: #0e0f09;
    padding: 4px 15px 4px 15px;
    border-right: 1px solid #c35f11;
    text-decoration: none;
}
#navigation a:hover
{
    background-color: #c35f11;
}

 

But by golly, this is what it looks like when I hover over the menu items:

 Menu with pesky space

What the heck is that little light orange vertical line (to the left of where I'm hovering) doing messing up my layout???

I thought that I could fix it in the properties of the ASP:Menu object. No dice. Then I went to the properties of the individual menu entry. No soap. Finally, I tried to hack the CSS with a negative absolute position or negative padding or other such smoke and mirrors. No love. Dejected, I gave up and told myself it was a bug in the control. I became so obsessed with that blasted little line that the quality of style in my code went down. I had inline CSS, unnecessary nested divs within other useless nested divs, and worst of all the formatting went away. Instead of the nice, pretty code you saw above, my menu turned into this monstrosity:

<div id="navigation">
    <asp:HyperLink ID="HyperLinkHome" NavigateUrl="~/Default.aspx" runat="server">Home</asp:HyperLink><asp:HyperLink
        ID="HyperLinkNewRequest" NavigateUrl="~/Default.aspx" runat="server">New Request</asp:HyperLink><asp:HyperLink
            ID="HyperLinkSearch" NavigateUrl="~/Default.aspx" runat="server">Search</asp:HyperLink><asp:HyperLink
                ID="HyperLinkHelp" NavigateUrl="~/Default.aspx" runat="server">Help</asp:HyperLink>
</div>

With a tear in my eye, I moved on to other tasks in the project and abandoned my plan to destroy that blemish. It had beaten me.

But all was not lost, because when I loaded the page, I saw this:

 Menu as it was intended to appear

Free at last, free at last, that blasted bug had worked itself right out of the system. And I had absolutely no idea what fixed it. So I repented of my evil ways and cleaned up my code. And daggummit, the blasted bug came back. Ctrl+z! Save us!

The moral of the story is: messy code works. No, wait, that's not right. The real moral of the story is that... umm... you shouldn't care about formatting? Eh, that doesn't sound right either. OK, forget the moral.

The trick is- if you want your ASP:HyperLink (or ASP:Menu, for that matter) code to look nice and pretty, you might run into an issue with the rendering. The carriage returns in the html get presented as empty space on the browser, which causes the vertical line. Solution: formatting be darned, runitalltogetherinoneuglylineandit'llrenderproperly. Hopefully.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


Several months ago I learned how to use LogParser. I put away my normal responsibilities for part of a day and focused on that neat little tool. Check my previous posts if you want to learn more about that experience.

Last week I wanted to know exactly what I'd need to do to move some of my web services to WCF. So, I pushed aside my duties, turned off Outlook, and spent the day delving into WCF. I don't think I have to tell you how sweet that day was!

Today I went to launch DBArtisan and a feeling of dread came over me. I didn't want to wait for the thing to load just so I could run a very simple query on a database. And SQL Management Studio isn't any better performance-wise. They're both great tools and I take full advantage of both regularly. But I wanted something light-weight. I had heard about SQL*PLUS for Oracle, but we're an MS shop, so I needed something for SQL Server. A little digging around uncovered sqlcmd- a command line tool for SQL Server. It's simple, very light-weight, and already installed. That little utility only took a matter of minutes to muddle through and appreciate.

In the next week or so I plan to get in up to my elbows in WF and I expect a great adventure. I've done a thing or two with LINQ, but one of these days I'm going to have to block off the distractions and plug my brain in on that.

Maybe (through no fault of my own, I assure you) I'm a little behind on some of these technologies, but I'll get to them when I get to them. The point is that I will never stop learning. I promise myself never to stagnate because I don't want to suck. We don't all need to be on the bleeding edge of things, but people who say "the heavens are closed" and that the world needs no new programming advancements should just hurry up and retire. Ha!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


I'm a generally trusting soul, although I have a feeling that will do me harm some day- perhaps even today (oh well, trust anyway). I know nearly nothing about Steve Pavlina, but I choose to link to one of his posts.

I found a very interesting post on Steve's site. It talks about looking at your career goals from a "top-down" perspective by discovering your underlying abilities and strengths. I'm going to put that into action- right now, in fact.

I enjoy teaching- but the term "teaching" doesn't really express what I really mean by the term. I love demonstrating how to do things and seeing how someone's confidence grows from having earned a new skill. I love to share what I know- not to promote myself and not to cheat others from being able to learn, but to save time and thus get more accomplished.

Maybe I'll be a professor some day. Maybe I'll be a trainer some day. Maybe I'll continue to be a senior-level developer and collaborate with my team members. Regardless of what job I hold, I want to work to make sure my career is always focused around sharing information (especially practical, useful information) with others.

Thank you, Steve. That was insightful.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


Just like with the previous entry on C# and telnet, creating an FTP session using C# is not as scary as it sounds. And even if you have to connect to a server that only understands RAW commands, that's not too bad either. Here's how:

Create a socket on port 21:

    //resolve IP address from DNS
    IPHostEntry dns = Dns.GetHostEntry(serverName);
    //create an endpoint to the server on port 21 (ftp default)
    IPEndPoint serverIP = new IPEndPoint(dns.AddressList[0], 21);
    //create a socket to that endpoint
    Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    //connect using the socket
    sock.Connect(serverIP);

If you want to, you can set some other properties of the socket:

    sock.SendTimeout = 2000; //2 seconds to send
    sock.ReceiveTimeout = 10000; //10 seconds to receive

Sending a message (string) and receiving a response through the socket goes like this (I chose to use the Thread.Sleep call because my server couldn't finish responding to my request in time for me to read the response immediately):

    //placeholder for response
    string resp = string.Empty;
    //placeholder for data to be received
    Byte[] bytesReceived = new Byte[1024];
    //track bytes
    int bytes = 0;
    //encode message into clear text
    Byte[] bytesSent = Encoding.ASCII.GetBytes(request);
    //send message
    sock.Send(bytesSent, bytesSent.Length, 0);
    //wait a while
    Thread.Sleep(1000);
    //listen for a response
    bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0);
    //decode the response
    resp = Encoding.ASCII.GetString(bytesReceived, 0, bytes);

Next, here are the strings that I stored in the object "request". Order matters- mostly. And the "\n" parts are the carriage returns to tell the server to process the command. They may not be necessary in your case, they were in mine:

  1. "USER [username]\n"
  2. "PASS [password]\n"
  3. "CWD [path of the folder containing the file I want]\n"
  4. "TYPE I\n"
  5. "PASV\n"
  6. "RETR [file name]\n"

Explanation:
Steps 1 and 2: Simply transmitting credentials. The user name must be a user LOCAL TO THE SERVER, which may or may not be a network or domain account.
Step 3: Change the current directory to the folder containing the file you're going to download.
Step 4: Type I means we're dealing with binary- I want the file, not just the text inside the file. There are also Type A and probably some others. Search if you need them.
Step 5: PASV tells the server to get ready to send or receive. The server opens a port and gets ready for a connection. It then sends a response that looks like this: 227 Entering Passive Mode (127,0,0,1,172,209). The first four numbers (separated by commas) are the IP address of the server: 127.0.0.1, in this case. Then you take the 5th element in the list, multiply it by 256 and then add the 6th element to find the port number.
Between steps 5 and 6, you'll need to create a second socket to the server, this time on the port that you just calculated from the response.
Step 6: Send RETR to the first socket. As soon as you do, the second socket will begin to receive data from the server.

Finally, here's how to receive the file from the ftp server via the second socket.

    byte[] buffer = new byte[25000];
    int bytes = 0; //number of bytes received finally
    bytes = sock2.Receive(buffer);

There is a property of the socket called "Available" and it'll tell you how many bytes are ready to be read from the socket. But from moment to moment that should change as more data is transmitted across the wire. Basically, you can keep checking it until the number stops changing or you can wait a pre-specified amount of time and start receiving from the socket whether it's done or not.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


I subscribe to about 20 feeds (nowhere close to someone like Scoble) and on several of them, I'd noticed the advice to set a rate of posting that is reasonable and can be maintained and then stick with it (Atwood). I'm not trying to gain readership and I'm not trying to compare myself to any of the 20 experts I follow. I am, however, trying to improve myself. So, I'm going to follow the advice- my starting rate (through the end of the year) will be to post at least once every two weeks.

Maybe that seems like a wussy goal to some of you, and I would agree- to a certain extent. But I'm new to blogging, collaboration is not a huge priority where I work (a mistake, I agree) so I'm working against the tide here, and I have 4 kids at home under the age of 6 so I don't have a great deal of computer time at home. Wussy or not, that's my goal.

The post I'm working on now (which I hope to publish by tomorrow) is similar to my last one. C# and telnet can be friends, and so can C# and ftp- in the raw, no less. I had to connect to an ftp server and use RAW FTP commands (RECV, PASV, etc) so I thought I'd pass on a few helpful hints.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


A Telnet session is really nothing but a Socket to a server on port 23 in .NET-speak. This article applies to .NET 1.1, 2.0, and 3.0, I just wrote my version in 2.0.
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


For anyone wondering "Who is this guy and where did he come from?" I have an answer. I have been posting for a few months on Blogger but didn't really see any fruits of my labor- no comments, no way of knowing how many hits I was getting, etc. So, I found GWB and have relocated my stuff here.

So that brings me back to the original question. Part 1: Who am I? I'm a developer with the power company in SC. I love to teach and hope to be able to move into an instructor/evangelist position some day.

Part 2: Where did I come from? I actually opened this account close to a month ago but was trying to figure out how to get my postings migrated nicely. I realized that I was spending more time planning and thinking and scheming than it was going to take me to move the posts themselves. So yesterday I just moved them by hand. There are only about 8, so it didn't take long. But if you were just looking at which posts were new, I probably showed up a time or 8 yesterday. I doubt I'll continue such a marathon pace, but you never know...

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


Given the day of the year and the year (both as ints), return the date in “m/d/yyyy” (string) format without using the System.DateTime namespace or any other built-in date/time handler.

One solution (1858 IL characters)

static string g(int d, int y)
{
int l;
int i = 0;
if (d < 0) { i = 13; }
l = ((y % 400 == 0) | ((y % 100 != 0) & (y % 4 == 0))) ? 1 : 0;
int[] m = new int[13] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
while (i < 13)
{
if (i > 1) { m[i] = m[i] + l; }
if (d <= (m[i])) { return i + "/" + (d - m[i - 1]) + "/" + y; }
i++;
}
return "e";
}

Another solution (1814 IL characters):
public string G(int d, int y)
{
if (d < 1 || y < 1)
return "e";
bool l = y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) ? true : false;
d = l ? d - 1 : d;
int[] m = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int i = 0;
do
{
if (d > m[i])
d -= m[i];
else
break;
} while (++i < 12);
d = l ? i < 2 ? d + 1 : d : d;
return i > 11 ? "e" : String.Format("{0}/{1}/{2}", i + 1, d, y);
}

Another (1718 IL characters):
static string r(int d, int y)
{
int m = 0;
bool l = y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) ? true : false;
int[] c = { 31, l ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
while (d > c[m < 11 ? m : 11])
{
d -= c[m < 11 ? m : 11];
m++;
}
return d < 1 || y < 1 || m > 11 ? "E" : String.Format("{0}/{1}/{2}", m + 1, d, y);
}

Winner (1538 IL characters)
static string D(int d, int y)
{
bool L = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
if (d > (L ? 366 : 365) || d <= 0 || y <= 0)
return null;
int x = 0, t = 3;
string i = string.Format("3{0}3232332323", L ? "1" : "0");
string s = "JFMAMJJASOND";
while (d > t + 28)
{
d -= t + 28;
t = int.Parse(i[++x].ToString());
}
return string.Format("{0}/{1}/{2}", s[x], d, y);
}
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


Given a color string in one of the formats listed below, return an array of the RGB elements that make it up.

For Example:
"RGB(255,255,255)"
"#FFFFFF"
"#FFF"

All of these examples return [255, 255, 255]

- Case does not matter
- #abc translates to #aabbcc
- There will be no spaces in the string

One solution (73 IL):
s = s.Replace("RGB(", "").Replace(")", "").Replace("#", "");
if (s.Contains(",")) { return s.Split(','); }
int[] a = new int[3];
int i = 0;
do { a[i] = (s.Length == 3 ? 17 : 1) * Convert.ToInt32(s.Substring(i * s.Length / 3, s.Length / 3), 16); } while (++i < 3);
return a;

Another (68 IL, I think):
object[] colorMyWorld(string htmlColor)
{
if (htmlColor.StartsWith("#"))
{
Color myColor = ColorTranslator.FromHtml(htmlColor);
return new object[] { myColor.R, myColor.G, myColor.B };
}
else
{
string[] components = htmlColor.Split("(),".ToCharArray());
return new object[] { components[1], components[2], components[3] };
}
}
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati


Implement 2 algorithms and place them in separate methods.
1) Given a sentence, write an algorithm to reverse the order of the words.
Example: “My name is Chris” becomes “Chris name is My”.
2) Given the same sentence as in #1, write an algorithm to reverse each individual word, but not their order.
Example: “My name is Chris” becomes “yM eman si sirhC”.

Winner:
public static string W(string s){
char[] c = s.ToCharArray();
Array.Reverse(c);
return O(new string(c));
}

public static string O(string s){
string[] t = s.Split(' ');
Array.Reverse(t);
return string.Join(" ", t);
}

Another:
static void a(string s)
{
int i = s.LastIndexOf(' ');
c.Write(s.Substring(i + 1) + " ");
if (i < 0)
return;
a(s.Remove(i));
}

static void b(string s)
{
int i = s.LastIndexOf(' ');
if(i > 0)
b(s.Remove(i));
s = s.Substring(i + 1);
i = s.Length;
do
{
c.Write(s[--i]);
} while(i > 0)
c.Write(" ");
}

Another:
static void x(string l)
{
d[] b = l.ToCharArray();
a.Reverse(b);
y(new s(b));
}

static void y(string l)
{
s[] f = l.Split(new d[] { ' ' });
int i = f.Length - 1;
do
{
c.Write(f[i] + " ");
} while (--i > -1);
}

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati