Sunday, May 17, 2009

Unable to reach NetBIOS name

Just been trying to troubleshoot why I couldn't ping any of the other computers on my network from one of my laptops. I still haven't fully solved the problem but I've managed to get the piece of software to work that I needed to get to work by following an excellent tip from amcmillan after asking "Can ping machine by IP but not by name" on the new Server Fault web site. The tip was a link to this Microsoft troubleshooting guide.
Here is my markedup flowchart that has got me to the next step:



Thursday, May 14, 2009

Professional ASP.NET MVC 1.0

Just bought and now reading Professional ASP.NET MVC 1.0 by Rob Conery, Scott Hanselman, Phil Haack, Scott Guthrie. I don't often buy computer books but I read the first chapter from a PDF that is available online and was suitably impressed with it and since I am working in ASP.NET MVC knew I needed the knowledge so went ahead and got it.

It's well worth it. If you're doing any ASP.NET MVC work and you need a tutorial or reference book on the subject then this one is excellent. I like the Product Team Asides where they describe what they discovered during the development of this framework and why they took certain approaches.

Something which I'm curious about though is why would four Microsoft employees writing about Microsoft technology publish a book through Wrox Press and not through Microsoft Press?

Thursday, May 7, 2009

Setting up a dropdown list in ASP.NET MVC

When adding a dropdownlist to a view in MVC there are two approaches that I've taken so far. Both of these approaches involve the same snippet of code in the view:

<% = Html.DropDownList("ModelData")%>

ModelData is the item in the ViewData[] collection that holds your list. You set this value in the Controller.

The Controller code creates or fetches a collection of items for the drop down and then assigns them to an item in the ViewData collection:

ViewData["ModelData"] = dropDownList;

The drop down list needs to be an IEnumerable. I have taken two approaches to creating this. The first is to create a dictionary of int's and string's which is the logical backing to a dropdown list.

Dictionary<int, string> dictionaryList = FetchDictionaryOfDropDownListItems();
ViewData["ModelData"] = new SelectList(dictionaryList, "Key", "Value");

Note that if you don't supply the "Key" and "Value" fields for the second and third parameters of the SelectList() constructor then both the integer (key) values and the string values from the Dictionary will appear in your dropdown list. By supplying these values you are telling the SelectList which are the values in your dropdown list and which is the data to display.

The second approach was to create a list of SelectListItems:

IEnumerable<SelectListItem> dropDownList = new listOfObjects.Select(a => new SelectListItem { Text = a.MyText, Value = a.MyValue });
ViewData["ModelData"] = dropDownList;

I'm using LINQ on an IEnumerable that I called "listOfObjects" which has objects that have at the minimum a MyText and MyValue public property. I'm assigning these to the SelectListItem's Text and Value properties. The Text property is what you'll see in the dropdown list and the Value is the backing value for each item, usually an ordered list of integers.

Yield return in C#

I was reading some of the sample code that comes with the Professional ASP.NET MVC 1.0 book and came across the yield return statement which I've seen before but never used.

It appears to be mostly syntactic sugar but may make the code more readable so I'm going to try and start using it to see if it improves the code smell.

Here is an example of how you might code something using a "classic" iterator:

        public static IEnumerable<string> FindStringsUsingClassic(string[] stringArray)
        {
            List<string> stringList = new List<string>();
            foreach (string s in stringArray)
            {
                if (s.StartsWith("f"))
                    stringList.Add(s);
            }
            return stringList;
        }

and here is the same code using yield return:

        private static IEnumerable<string> FindStringsUsingYield(string[] stringArray)
        {
            foreach (string s in stringArray)
            {
                if(s.StartsWith("f"))
                    yield return s;
            }
        }

Slightly less code but is it more readable and understandable? I don't know yet...

Those are contrived examples because if you're using C# 3.0 you would or should opt for the following:

        public static IEnumerable<string> FindStringsUsingLINQ(string[] stringArray)
        {
            return stringArray.Where(a => a.StartsWith("f"));
        }

 

Wednesday, April 29, 2009

Security Vulnerability

Can you see the security vulnerability in the following snippet of code?

    string returnValue = String.Empty;
    string sql =
        "select description from products where prodID = '"
        + Request.Params["pid"] + "';";
    SqlCommand sqlcmd = new SqlCommand(sql);
    sqlcmd.Connection = sqlConn;
    SqlDataReader sdr = cmd.ExecuteReader();
    if (sdr.Read())
    {
        returnValue = (string)sdr[0];
    }
    sdr.Close();
    return returnValue;

Thursday, April 9, 2009

Powershell script to remove empty directories

Here's  a Powershell script that I've just created to remove empty folders which I'm sure I'm not going to need again in the future.

$items = Get-ChildItem -Recurse

foreach($item in $items)
{
      if( $item.PSIsContainer )
      {
            $subitems = Get-ChildItem -Recurse -Path $item.FullName
            if($subitems -eq $null)
            {
                  "Remove item: " + $item.FullName
                  Remove-Item $item.FullName
            }
            $subitems = $null
      }
}

 

 

Powershell Copy-Item does not honor the exclude parameter

I've been having a hard time getting Powershell's Copy-Item to work for me. My problem is that the -exclude parameter for the Copy-Item only honors the excluded items for the root directory in the destination but not for sub-directories if you also include the recurse parameter.

I believe that I have finally solved the problem with this snippet of powershell:

$source = 'd:\t1'

$dest = 'd:\t2'

$exclude = @('*.pdb','*.config')

$items = Get-ChildItem $source -Recurse -Exclude $exclude

foreach($item in $items)

{

      $target = Join-Path $dest $item.FullName.Substring($source.length)

      if( -not( $item.PSIsContainer -and (Test-Path($target))))

      {

            Copy-Item -Path $item.FullName -Destination $target

      }

}