Monthly Archives: January 2010

ASP.NET: ListBox Tooltip

The ASP.NET ListBox does not display a horizontal scroll bar by default, which can be a problem if any of your list items are too long to fit. One solution to this problem is to use a tooltip. As the user moves the mouse over the ListBox entries, the full text appears in a tooltip.

image

The code to accomplish this is as follows:

In C#:

private void LB_PreRender(object sender, System.EventArgs e)
{
    foreach (ListItem item in LB.Items) {
        item.Attributes.Add("title", item.Text);
}

In C#, you also need to set up the event handler. In this example, the event handler is set up in the Page_Load event, but you could put it where it makes sense for your application.

LB.PreRender += LB_PreRender;

In VB:

Private Sub LB_PreRender(ByVal sender As Object, _
     ByVal e As System.EventArgs) Handles LB.PreRender
    For Each item As ListItem In LB.Items
        item.Attributes.Add("title", item.Text)
    Next
End Sub

The ListBox, named LB in this example, has a PreRender event. In the PreRender event the code loops through the ListBox items and sets the title attribute to the text of the item.

Use this technique any time you want to display a tooltip over your ListBox items.

Enjoy!

Finding a Node in an XML String

A common requirement with an XML file is to find a particular node. If you are targeting the .NET framework 3.5 or higher, you can find the node using Linq to XML or by using Lambda expressions.

As with many of my prior XML examples, the XML string is as follows:

<States>
  <State name="Wisconsin">
    <Regions>
      <Region name="Milwaukee">
        <Area name="Mukwanago"/>
        <Area name="Germantown"/>
      </Region>
      <Region name="Fox Valley">
        <Area name="Oshkosh" />
        <Area name="Appleton" />
      </Region>    
    </Regions>
  </State>
</States>

The code to find the node for the Milwaukee region is as follows:

In C#:

// Be sure to set a reference to System.Core and System.Xml.Linq
XElement states  = XElement.Load("testXML.xml");

// Using LINQ
XElement foundNode;
var query = from XElement r in states.Descendants("Region")
                   where r.Attribute("name").Value == "Milwaukee"
                   select r;
foundNode = query.FirstOrDefault();

// Using Lambda expressions
foundNode = states.Descendants("Region").
     Where(r => r.Attribute("name").Value ==
                         "Milwaukee").FirstOrDefault();

In VB:

‘ Be sure to set a reference to System.Core and System.Xml.Linq
Dim states As XElement = XElement.Load("testXML.xml")

‘ Using LINQ
Dim foundNode As XElement
Dim query = From r As XElement In states…<Region> _
                  Where r.@<name> = "Milwaukee"
foundNode = query.FirstOrDefault()

‘ Using Lambda expression
foundNode = states…<Region>.Where(Function(r) r.@<name> =  _ 
                                 "Milwaukee").FirstOrDefault

This code first loads the XML file containing the XML. The next set of code can be done using LINQ or using Lambda expressions. Use either one, but not both. :-)

The C# code uses the XElement properties and methods. The VB code uses XML literals.

NOTE: The XElement properties and methods work in VB as well.

Enjoy!

NOTE: This post was created based on a prior post that included both finding a node and adding new nodes. This post separates the first step to provide a more straightforward example.

XML Documentation Comments

You can document your classes, properties, methods, and so on using XML tags. I’m sure all developers know this at this point, but did you know that you can modify the set of valid tags?

If you are not familiar with XML Documentation Comments (or just XML Comments), you create them differently depending on the language you are using.

In C#:

On the line above the class, property, method, or whatever you are documenting, type three forward slashes.

///
public List<Customer> Retrieve(int Id)

Visual Studio automatically inserts the appropriate XML tags:

/// <summary>
///
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public List<Customer> Retrieve(int Id)

In VB:

On the line above the class, property, method, or whatever you are documenting, type three apostrophes.

”’
Public Function Retrive(ByVal id As Integer) As List(Of Customer)

Visual Studio automatically inserts the appropriate XML tags:

”’ <summary>
”’
”’ </summary>
”’ <param name="id"></param>
”’ <returns></returns>
”’ <remarks></remarks>
Public Function Retrive(ByVal id As Integer) As List(Of Customer)

You can then build technical documentation of your API from the XML comments.

In C#:

1. Double-click on Properties for the project in the Solution Explorer.

2. Click on the Build tab.

3. Check the "XML document file" checkbox and ensure  that a file name is specified.

4. Build your project.

All of the XML comments are generated into one XML file.

In VB:

Generating the XML documentation is on by default. To check it:

1. Double-click on My Project for the project in the Solution Explorer.

2. Click on the Compile tab.

3. Check the "Generate XML documentation file" checkbox.

The XML file is generated in the binDebug folder for the project.

You can use a product such as SandCastle to generate your technical documentation from these comments.

But what if you want more or different tags than those that are provided? IF YOU ARE USING VB.NET you can do just that.

NOTE: As far as I have seen, this technique is not available in C#.

In VB:

Locate your XML Comment tag file. Mine was here:

C:Documents and SettingsDeborahApplication DataMicrosoftVisualStudio9.0VBXMLDoc.xml

If you don’t have this file, you can create it following the instructions defined here.

This file contains the definition of the valid XML tags used in XML Comments. You can then add to the contents of this file or edit it as you desire.

For one of my projects, we wanted to add an edit history to each class that included the date, the developer’s name, and a description. So I added the following to the Class code element:

    <CodeElement type="Class">
        <Template>
            <summary/>
            <remarks/>
        <editHistory date="" developer=""/>
        </Template>
        <CompletionList>
            <include file="" path=""/>
            <permission cref=""/>
            <remarks/>
            <summary/>
        <editHistory date="" developer=""/>
        </CompletionList>
    </CodeElement>

We could then create XML comments as follows:

”’ <summary>
”’ Manages a customer class
”’ </summary>
”’ <remarks></remarks>
”’ <editHistory  date="9/14/09" developer="DJK">
”’ Added customer type.
”’ </editHistory>
”’ <editHistory date="10/17/09" developer="DJK">
”’ Added an Email address.
”’ </editHistory>
Public Class Customer

Use this technique any time you want to enhance your XML comment documentation in VB.NET.

Enjoy!

Minimize drawcall functionality

One of the challenges when converting old API macros or COLLADA objects is often how to make them  framerate friendly. It is not uncommon for such objects to use many small texture files. If you for example load an object from the Google 3D warehouse, don’t be surprised to find it uses 40 different texture files.


For some time it was on my ModelConverterX wishlist already to add some functionality that will merge all these textures into one texture sheet and automatically adjust the mapping on your object as well. Today I started coding on this.


I am certainly not finished yet, but the first results are very encouraging already. The image on the right shows my test application, where I loaded a bunch of textures from a KMZ file. All these pieces have been combined into one big texture sheet.


What I still have to do is make the code to update the texture mapping on the object. And of course to make a user interface to access this drawcall minimizer functionality. But that should not be the hardest part.


So hopefully later this weekend I can have the first beta version ready. But now I am first going to enjoy the snow outside and have a walk.

PowerGUI 2.0

While we are on the subject of new releases PowerGUI 2.0 recently became available. An excellent tools with a very good PowerShell editor – it should be part of everyone’s PowerShell toolbox

Technorati Tags: ,

Server Health Checks

I’d like to share some of the things I look at while do a health check on a server.  Its funny how few resources there are out there on the Internet.  I believe people keep this kind of stuff to them self because they are scared they are going to miss something and they will never live it down.  My response to that is, So What!  Heck, I don’t claim to know it all but why not share what I do know and maybe others can share via the Comments!!!

When I’m troubleshooting I like to compartmentalize what I”m looking for.  With that my health checks are set up the same way.  I also believe health checks are quick snapshots of the health of a server.  Sure there are tools that you can use to analyze systems further but in this case we are doing a quick health check.  Not all of these need to be done but some should, you get to decide.

CPU

Occasional high CPU spikes are ok as long as you are aware of the process causing this. A server should maintain 80% CPU utilization for an extended period of time.  If it does it may be time to upgrade.  Its a good idea to keep Task Manager open during the duration of your troubleshooting to see trends.

Check CPU Usage

  1. Open Task Manager

  2. Check the Processes tab, ensure there are no processes consuming excessive CPU

  3. Check the Performance tab, ensure there are no single CPU’s that have excessive CPU usage

Check CPU HW

  1. Open Device Manager (right click computer –> Manage)

  2. Ensure that no CPU’s have red X or yellow ! underneath the Processors

Processes

This is one area that you may not want to do for quick health checks but is something you should be familiar with.  Task Manager only gives you basic info on processes and you will find that you may need to dig a bit deeper.  For that I recommend Process Monitor from the great SysInternal tools.  Process Explorer can also be used.  In fact download and play with all these tools…they will save your bacon, I guarantee it.

In-Depth Check
SysInternals:

Copy Process Monitor locally, then launch it.

  1. Analyze each process and watch what operations open the reg keys, file etc.

Copy Process Explorer locally, then launch it.

  1. Analyze each process based upon the number of threads, handles, loaded DLL’s,etc.

Two great webcasts can be viewed here to see these types of tools in action.

Memory

General rule of thumb is to make sure the general memory utilization does not exceed 80%within a given period of time.

Check Memory Availability

    1. Open Task Manager
    2. Select the Performance tab

    3. Look at the Physical memory box,and multiply the total memory by .2

    4. If the total available memory is less than this number then the box is currently utilizing more than 80 percent of the memory.

Current utilization by process

  1. Select the Process tab

  2. Check the ‘show processes from all users’ box in the bottom left corner

  3. Click the column header ‘Mem Usage’ to sort the processes by memory utilization, highest to lowest. This will help you determine what processes are currently utilizing the memory on the box and can help you narrow your search for memory intensive processes.

Network

Check NIC HW

  1. Verify both ends of the network cable are securely seated in the port

  2. On the back of the server verify you have a green blinking link light on the NIC port

  3. Verify NIC HW is working properly by using Device Manager and ensure the active NICs are showing green

  4. Verify gateway, IP, subnet mask, DNS, DNS suffixes, etc. are properly configured.

  5. If everything is properly configured and HW is working, you should be able to get a ping response from the gateway.

Check Network Connections
Here are some other checks you should perform to ensure proper network connectivity:

  1. ipconfig /all will display all you TCP/IP settings including you MAC address

  2. ipconfig /flushdns will flush your dns resolver cache

  3. ipconfig/displaydns will display what is in your dns name cache

  4. Netstat -an command will show all the connections & ports from a machine

  5. Nbtstat command will show net bios tcp/ip connection stats

  6. Tracert <IP or DNS Name> command will show you the path the packet takes, the routers, and the response time for each hop.

  7. pathping <IP or DNS Name> command combines ping and tracert to the 100th degree.  It pings each hop 100 times and is great for testing wan connectivity

Disk Space

All kinds of bad stuff can happen when your disk space is filling up.  The best way to alleviate this is to write a script to notify you when you reach a certain threshold. In a future post I”ll share a method for you to do just that…however if there is a problem and you need to perform a health check then here is how you check the space the old fashion way.

To check disk space manually:

  1. Right Click on My Computer

  2. Select Manage

  3. Select Disk Management

  4. Validate each disk more than 10 percent free space

Event Logs

Event logs can reveal a more historical perspective on what is going on with the system and applications. Things to look for when troubleshooting event logs is to query either the system or the application logs and look for the presence of events that have a timestamp near the time of the issue you are troubleshooting.

Events have 3 categories in the event viewer:

  • Informational: Noted with a white icon and letter ‘i’. Successful operations are logged as informational. Usually not used in troubleshooting problems or failures

  • Warning: Noted with a yellow icon and exclamation point. These usually are looked up as they serve as predictive future failure indicators, such as disk space running low, dhcp ip address lease renewal failures, etc.

  • Error: Noted with a red circle icon and ‘x’. These are indications that something has failed outright and are a good starting point for troubleshooting.

When looking at event logs, use the information to determine the following:

  • Is the incident tied to a particular time or outage incident?

  • Is this a one-off, or has this particular error occurred multiple times in the past?

  • Does this error appear on other systems or is it unique to the system that has failed?

Also make sure you take a look at eventcombmt from Microsoft.  This tool allows you to search the logs of multiple machines.  The benefit to this is to see if a specific error or warning message is also occurring on other systems.  This can help rule out issues.

Services

Troubleshooting services should be limited to the specific that is affected by the problem being troubleshot. Each server will have specific services varying upon the types of applications running. You should document how your servers services are configured to and compare that to the server in question to see if anything is not configured correctly.

Cluster

Servers that host applications and services that require high availability should be clustered so that if one node fails the other can pick up the workload.  Clustered servers need the same type of health checks as stand-alone systems except you will want to check on the health of the cluster.

Check Cluster Resource Status

  1. Open Cluster Administrator: Log onto server, select Start –> Run –> cluadmin

  2. Check the Resources and ensure all are Online

  3. If Cluster Administrator does not open, ensure that the Cluster Service is running on the node.

  4. Cluster resource status can also be checked from a remote server. From a command prompt, just type – cluster res <cluster name>

Client Side Health

  1. Right click on My Computer, select Manage

  2. Open Device Manage

  3. Drill down to SCSI and RAID Controllers, verify that the HBA HW is visible and does not show any errors

  4. If it does not show up in Device Manager, you may need to re-scan for the HW, re-seat the fiber card, or re-install the driver.

  5. If the HBA is showing healthy in Device Manager, open the tool that you use to view configuration and settings for the fiber card and verify there aren’t any transmit/receive errors on link statistics or counters

Switch Health

  1. Make sure fiber is properly connected to each switch

  2. Make sure switch has no errors

  3. If you’re using zoning verify it is properly configured

Check Fiber and SAN Connectivity

  1. Log onto san appliance and verify that the SAN is in general good health and no major errors are present for the controllers, loops, switches, or ports.

  2. Ensure that the LUNs are presented to the servers in the cluster

NLBS

Some applications will require you to spread the load across multiple servers.  Web servers are a very popular choice to network load balance.  As with clusters we will need to check the status of the load balancing.

Check NLBS Status CMD Line

  1. From a command prompt on the local system, run ‘wlbs query’. This will give you the convergence status of the local node with the nlbs cluster.

  2. Other useful NLBS commands: wlbs stop (stops nlbs), wlbs start (starts nlbs), wlbs drainstop (drains node)

Check NLBS Configurations

  1. Open up the network properties –> Network Load Balancing, right click & select Properties

  2. On the Cluster Parameters tab, verify that the IP address is configured for the shared NLBS IP and that the subnet mask, domain, and operation mode are configured correct1y.

  3. On the Host Paramters tab, make sure each node of the cluster has a unique host identifier. Also verify the IP and subnet mask are configured for the local values.

  4. Also make sure that your switch has a static ARP entry if using multi-cast NLBS. The entry should be that of the virtual MAC of the cluster. To get the virtual MAC of the cluster, you can run the following command: WLBS IP2MAC <virtual IP address>

Name Resolution

To healthcheck name resolution, open a command prompt and enter the following

  • nslookup <servername>

Verify that the servername is correctly entered in DNS

If a record does not show up in the DNS query, or maps to a different name, perform a reverse lookup by IP address to see what name is associated with the IP address * nslookup <IP address>

If no name shows up associated with the IP address, log into the domain controller and check the DNS records for this particular name/ip address

  1. From a Domain Controller go to start–>run–>dnsmgmt.msc

  2. Expand the Forward Lookup Zones

  3. Expand the zone for you primary zone that holds the records for the system/s you are troubleshooting

Validate that the record exists. If it does not exist manually enter the record name and IP address by right clicking on this same zone,

  1. Select new host (a)

  2. Enter the name and IP address

  3. Check the box next to Create associated pointer (PTR) record

  4. Click add Host

Additionally log back into the node that you manually entered the record for and ensure that DNS is registering in DNS

  1. Right click on the My Network Places icon on the desktop and select Properties

  2. Double click on the primary adapter

  3. Select properties

  4. Highlight internet protocol (TCP/IP) and select properties

  5. Validate the IP addresses of the DNS servers are correct

  6. Select Advanced

  7. Select DNS tab

  8. Make sure the box is checked next to Register this connection’s address in DNS

As I wrap this up I realize there is so much more that can be done.  Each application type of server needs its own set off health checks.  For example web servers, terminal servers and database servers.  Remember this is just the baseline for each server and that other components can and should be layered on top of it.  Again I would love to hear from others so please feel free to add you comments below.

The new auto-start feature

Version 4.0 of ASP.NET introduces a new feature called auto-start. The idea is simple: to improve the performance of the web app by allowing apps to run some expensive code before the first request comes. I must say that this is really an interesting concept (and no, I won’t be going into details here because the white paper already explains most of what you should know).

I’m only mentioning this here because this will only work from windows 7 and windows 2008 server R2 onwards. This is something which makes me really sad because people running windows 2008 server won’t be able to use this feature. I really believe that it’s time for MS to change the interaction between IIS and the OS…I mean, am I the only one that is fed with having the IIS version tied up with the OS version???

Routed events in Silverlight

Routed events were introduced by WPF and they’re responsible for enabling several advanced scenarios in that platform:

  • tunneling: in this case, the event is first raised in the root and goes “down the tree” until the source element that generated the event is reached;
  • bubbling: in this case, the event bubbles from the source element to the root element;
  • Direct: the event is only raised in the source element.

Once again, the use of routed events in Silverlight is limited. By default, it only exposes a couple of routed events and it only supports bubbling (ie, there’s no tunneling for routed events in Silverlight).In order to illustrate the bubbling feature, we’ll start running the following example:

<UserControl x:Class="Tests.test"
    x:Name="uc"
    xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:Tests"> <Canvas Width="150" Height="200" x:Name="cv"> <StackPanel x:Name="sp"> <TextBlock Text="Click me" x:Name="bt" /> </StackPanel> </Canvas> </UserControl>


And here’s the code-behind:



public partial class test : UserControl {
    public test() {
        InitializeComponent();
        bt.MouseLeftButtonDown += PrintInfo;
        sp.MouseLeftButtonDown += PrintInfo;
        cv.MouseLeftButtonDown += PrintInfo;
        MouseLeftButtonDown += PrintInfo;
    }
    private void PrintInfo(
Object sender, MouseButtonEventArgs e) { var info = String.Format(
"elemento original: {0} - elemento actual: {1}n", ((FrameworkElement)e.OriginalSource).Name, ((FrameworkElement)sender).Name); MessageBox.Show(info); } }


If you run the previous sample, you’ll notice that the event bubbles from the button until it reaches the root user control. The MouseButtonEventArgs class ends up inheriting from the RoutedEventArgs class. Due to that, we can access the OriginalSource property and find out which object is responsible for the event that is bubbling. Notice that the MouseButtonEventArgs ends up adding the read/write Handled property: when you set it to true,the event won’t be propagated beyond the current element that is responsible for the event that is being fired.



Unfortunately,you can’t really create custom routed events in Siverlight. The reason is simple: there isn’t a public API for letting you do that (if you dig into the code of the MouseLeftButtonDown event instantiation, you’ll notice that routed events are created through the RoutedEvent constructor which is internal). What this means is that you’re limited to creating “normal” events in your custom classes. I’m not sure if this limitation will ever be removed from Silverlight. And I guess this sums it up quite nicely. Stay tuned for more on Siverlight.

PSCX 2.0

I have mentioned  PowerShell Community Extensions many times over the last few years. I have found them a very useful set of utilities to extend the basic PowerShell install. With PowerShell v2 there was an irritation that a few of the cmdlets

Get-Random
Start-Process
Select-Xml

overrode the PowerShell v2 cmdlets of the same name.

That has been fixed with the PSCX v2 beta that is available from http://pscx.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=39405. It is module based so use it on PowerShell 2. It is a simple zip file, so download it, unblock it and unzip it to your module path.

It loads using import-module and looks to be full of goodies.  The PSCX guys have done a good job with this. Time to give it a whirl and see how it works.

Gira Up To Secure 2010 – Las fotos :-)

Llevo unos días de lo más ajetreado y no he podido publicar nada hasta ahora. Sorry :-D


DSC03162 DSC03142 DSC03154


El evento salió muy bien, salvo un pequeño problemilla con la conexión a Internet de unos de los ponentes. Al final se tuvo que tirar de un adaptador 3G –> WIFI que traía Carles de Quest Software (gracias!), al cual le pegaron un tremando palo por el consumo de datos entre paises… pobre :-)


Os dejo algunas de las fotos del evento. Muchas gracias a todos por asistir, espero que os lo pasáseis tan bien como yo.


DSC03140 DSC03141  DSC03143 DSC03147 DSC03148 DSC03149 DSC03151 DSC03152    DSC03156 DSC03157  DSC03163


Un saludo y nos vemos en el próximo evento de AndorraDotNet (el próximo Febrero) sobre las novedades de VS2010.


DSC03155


 @Happy hacking! ;-)


** crossposting desde el blog de Lluís Franco en geeks.ms **

Recent Comments

Archives