Friday, 3 July 2009

C# - Array to Dictionary

Recently I needed to convert an Array of DictionaryEntry<object,object> items into a Dictionary<string,string> object. Here is simple code using LINQ and ToDictionary method for doing that with 1 command:
DictionaryEntry<object,object>[] props = GetSomeProperties();
Dictionary<string,string> dict =
props.ToDictionary(de => (de.Key != null) ? de.Key.ToString() :
string.Empty);
de => (de.Value != null) ? de.Value.ToString() :
string.Empty);

Isn't that simple? :)

Thursday, 18 June 2009

Handling exceptions from multiple UpdatePanels

In one of my previous posts I've already mentioned how to handle exceptions that occur within UpdatePanel on client side (see post). However, this did not cover server side error handling nor multiple UpdatePanels on one page.

Sometimes you may want to have on your ASP page multiple update panels or a large one containing multiple controls. The problem is that when an error occurs on update action you may find hard to localize the actual control that generated the error causing event. This may be required in some situations e.g. to display error message next to the control responsible for the exception.

Let's take a look at some code. Here is a sample ASP page with a ScriptManager and 2 UpdatePanels. Each of the panels contains a button and a label for displaying errors:
<asp:ScriptManager ID="ScriptManager1" runat="server" 
onasyncpostbackerror="ScriptManager1_AsyncPostBackError">
</asp:ScriptManager>

<!-- First Update Panel -->
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="B1" runat="server" Text="B1" onclick="B1_Click" />
<asp:Label ID="Label1" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>

<!-- Second Update Panel -->
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:Button ID="B2" runat="server" Text="B2" onclick="B2_Click" />
<asp:Label ID="Label2" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
As you can see the ScriptManager has an error handler defined (line 2) and both buttons have click handlers assigned. The error labels are empty on entry.
Here is Code Behind for that page:
  protected void B1_Click(object sender, EventArgs e)
{
throw new Exception("Exception from Button1");
}

protected void B2_Click(object sender, EventArgs e)
{
throw new Exception("Exception from Button2");
}

protected void ScriptManager1_AsyncPostBackError(
object sender, AsyncPostBackErrorEventArgs e)
{
// Do smth with the error e.g log it
}
Clicking on any of the buttons will cause an Exception. The exception message varies for each button. In my example the error handler for script manager does nothing but you can do whatever you need with the caught error e.g. log it.

Now, let's handle the error on client side. The following code will register client side error handler, which will display a message from the thrown exception next to appropriate button:
// Register EndRequest handler for ScriptManager
Sys.WebForms.PageRequestManager.getInstance().
add_endRequest(EndRequestHandler);

function EndRequestHandler(sender, args)
{
// If there is an unhandled error
if (args.get_error() != undefined)
{
// Get id of the control that fired the error-causing action
var senderControlId = sender._postBackSettings.sourceElement.id;

// Get Label next to the source control
var errorLabel = document.getElementById(senderControlId).
nextSibling.nextSibling;

// Set error message in appropriate control.
// You may want to remove the user-unfriendly part of the
// message that was added by Script Manager
errorLabel.innerHTML =
args.get_error().message.replace
('Sys.WebForms.PageRequestManagerServerErrorException: ', '');

// Mark the error as handled
args.set_errorHandled(true);
}
}

That's it. To make it work just place the JS code on your ASP page.

Thursday, 11 June 2009

Centering Adsense Ads on blogger pages

Recently I decided to add Adsense ads on my blogger page to earn zillions of $$$$. Blogger dashboard offers easy to use Adsense integration (Monetize tab). It helps you to create Adsense account and automatically places the ads on your blog page. The problem is that it doesn't offer much control over the way the ads are displayed, soe you can't e.g. center your ad, align it in to the right etc. To achieve that you'll need to create the ad manually through the Adsense page (see Adsense help) and then paste the code into your blogger template:
  1. From blogger dashboard got to:  Layout > Edit Html

  2. Check the "Expand Widget Templates" checkbox to see the detailed view of your template

  3. Find the place in the template where you'd like to place the ad.

  4. Create a div element that would store your ad and style it as much as you want (center it, add padding, etc.)

  5. Paste the code generated by Adsense into the div

  6. Change the following characters in the generated Adsense code:

    • < change to &lt;

    • > change to &lt;

    • " change to &quot;

    so the code for your Ad looks somehow like this (changed lines: 1, 2, 3, 5 & 8):
    <script type='text/javascript'>&lt;!--
    google_ad_client = &quot;pub-5***************&quot;;
    google_ad_host = &quot;pub-1***************&quot;;
    /* name of your ad */
    google_ad_slot = &quot;7*********&quot;;
    google_ad_width = 160;
    google_ad_height = 600;
    //--&gt;
    </script>
    <script src='http://some_google_linkto_js_file'
    type='text/javascript'>
    </script>
    It is important that you do this, otherwise you'll get a JS error 'pub is undefined' (or something similar) on the page and the ad will not be displayed.
Solution and automatic converter found here.

Friday, 29 May 2009

JS: Display tooltip over page element

To display a tooltip over a page element:
  1. Create hidden tooltip element:
  2. Create JS scripts for showing/hiding tooltip:
    function show()
    {
    var tooltip = document.getElementById('tooltip');
    tooltip.style.top = event.clientY;
    tooltip.style.left = event.clientX + 10;
    tooltip.style.display = 'block';
    }

    function hide(){
    var tooltip = document.getElementById('tooltip');
    tooltip.style.display = 'none';
    }
  3. Set Javascript events for the chosen page element:

    Element content
Tested on IE7.

Monday, 4 May 2009

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

A piece of code that I've been working on lately started to throw exceptions when calling a web service using a generated client. The logg file contained only the exception message:
"The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state."

Most of the suggestions found in Web blamed the invalid code, giving examples similar to the following one:

using (MyWebServiceClient service = new MyWegServiceClient())
{
service.DoSomeOperation();
service.Close();
service.DoAnotherOperation();
}
Since I was sure this was not the case I had to discover the real exception reason by myself.

Solution:
After debugging the app it came out that solution was quite simple - the service configuration (URL, security settings) was invalid. I found that out by analyzing the InnerException of the main Exception. The logged exception message was rather irrelevant to the actuall error.

Tuesday, 14 April 2009

Join the Java Black Belt community

I'm recently working mainly on .NET projects but would like to stay on top of Java technology stack as well. That's why I've just joined the Java Black Belt community.
It offers many free java exams created by community users. In order to get the black belt you need to contribute to the portal so the amount of testing material is still growing.
It's a great way to refresh your java knowledge. I hope that this belt-system will keep me motivated so I not only prove my current skills but also learn something new.
After I get to the certain level (let's say the blue belt) I'll update my blogger profile to display the belt icon so you can see my progress directly from this page.

Tuesday, 24 March 2009

Debugging .NET applications

Recently I attended C2C conference in Warsaw. I signed up for the .NET track. The session I was really looking forward to was “Hardcore Production Debugging” by Ingo Rammer. I hoped to learn something that I could use right away in my every day work. Remote debugging may be very painful and it is not easy to find the best approach. I was keen to learn about new easy-to-use tools that would make my life much easier. Unfortunately, the word “Hardcore” in session’s title was there for a reason…

The biggest part of the session was dedicated to WinDBG tool. Its interface is very poor and user-unfriendly. However, Ingo demonstrated that once you learn how to use it, it can be very helpful in finding the reason for application failures.

At first Ingo simulated situation where the developer has access to production machine (with no Visual Studio installed) where they can run WinDBG. Once he started this tool he attached it to the process of sample application that was throwing unhandled exceptions. With a few commands he was able to find out the exception message and the reason for failure. With the same tool Ingo was able to find out the reason for unexpected application exit by attaching breakpoint at the end of app’s process.

Ingo showed us also that remote debugging can be achieved with the WinDBG installed on developers machine and its console version – CDB – on client’s machine. After you configure the port for CDB you can access it from outside using WinDBG (option “Connect to remote session”).

Next, Ingo explained what to do when WinDBG and CDB are also not available on the production machine. He proved that we can find the same error as in the first part by studying the memory dump created for that application. To get the memory dump we can ask the client to create it manually using a simple program (Adplus) or OS built-in functionality (only on Vista) immediately after the error occurs. Then, all we need to do is load the dump into WinDBG (option “Open crush dump”) on the developer’s machine and examine it using the same commands as in the first case.

Finally, Ingo presented simple program GFlags for Windows registry keys modifications that would allow launching CMD/WinDBG immediately after specified process is started and attaching the debugger to this process. This can be handy when an error does not occur regularly and it’s not easy to reproduce. He warned us that you have to be very careful when using that tool and change system’s default settings only if you’re absolutely sure what you’re doing. Registry modifications can cause a lot of damage to your OS if the are not done correctly.

To sum up - the pase of presentation was high so it was not possible to learn all the commands that Ingo was using. The goal of this session was to show to the audience what is possible if we use the presented tools and that it doesn't require much work once you learn how to use them.

The session itself came out to be the highlight of the conference. Mixture of Ingo’s knowledge and charm proved to be the formula for perfect presentation. I just wish Ingo had some more time so we could study the examples more carefully.

Some WinDBG commands used by Ingo:

.hh Debugger Help
sxe clr Break on all CLR Exceptions
sxi clr Ignore CLR Exceptions
sxn clr Notify on CLR Exception

.loadby sos mscorwks
Loads SOS Debugging Extension;
Enables use of following options:

!help
!printexception (!pe)
!clrstack

~ list threads
!threads list managed code threads

Some Useful links:
All presented debugg tools for Windows
Ingo's page at Thinktecture
Tess Fernandez blog “If broken it is, fix it you should”

Ingo also recommended book "Debugging .NET" by John Robins.