Wednesday, November 26, 2008

WCF Tracing with SvcTraceViewer

I had a problem with an WCF Service that I'd written that was reading from an MSMQ and would blow up if the message was larger than 64K. Once I'd tracked down the exception that was being thrown (QuotaExceededException) a quick search on Google with "wcf quotaexceededexception" landed me on Hugo Batista's blog site and his WCF: maxReceivedMessageSize and QuotaExceededException post which was exactly what I was experiencing and this solved the problem.

This, however, did not solve the problem of how incredibly difficult I found it to log that QuotaExceededException exception. Like Hugo Batista I'd tried to catch the UnhandledException event from the AppDomain but this was unsuccessful.

Eventually I discovered that I could turn on Message Logging and Tracing in the App.config file and then use the SvcTraceViewer application to look at those files. This worked a charm and the tools make it pretty easy.

First you need to edit the App.config file but Visual Studio 2008 has a utility that makes this very easy for WCF. Right click on the App.config file and you will see an option "Edit WCF Configuration." This brings up the Microsoft Service Configuration Editor which makes editing this much easier. In the Configuration section on the left hand side click on Diagnostics and then click on the links "Enable MessageLogging" and "Enable Tracing" and set the locations for the log files.

Now run the errant web service and once it's faulted the channel open the error file with SvcTraceViewer. I found SvcTraceViewer in the "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\" folder on my XP machine. The tracelog is where you'll find the warnings etc.

Tuesday, November 25, 2008

Jon Skeet is better than Chuck Norris

 A coworker of mine brought the Jon Skeet Facts question to my attention a few days ago and I laughed out aloud when I read it. Subsequently Jeff Atwood blogged about it in Stack Overflow Is you.

The icing on the cake, for me at least, is Jon Skeet's sense of humor in writing the accepted answer in the third person. Very funny.

Friday, November 21, 2008

The difference between Tempuri and Tempura

If you've ever worked with a web service that started off life being generated by a Microsoft tool then you've probably seen the namespace http://tempuri.org/. I've seen this for years and I know it well. I also know that you're supposed to change it immediately but that hardly anybody does.

Until today, I had no idea why it was called http://tempuri.org/. I thought that maybe it was some fictional company like Contoso that a Japanese employee from  Microsoft who loved tempura style deep-fried cooking had made up to stick in the namespace.

The along came a friend of mine and pronounced it as Temp URI, and suddenly it all fell into place.

Monday, November 17, 2008

Microsoft JScript runtime error object expected with jQuery

I was trying to get a simple piece of jQuery to work and was running up against this error in Internet Explorer (IE):

Microsoft JScript runtime error: object expected

The problem turned out to be that I wasn't referencing jQuery to the correct path. The trick I discovered, if you're using Visual Studio, is to just drag the JavaScript file from the Solution Explorer into the <head> element on your page and it will insert the correct reference for you.

UPDATE (9 July 2009):

I am referencing jQuery from the Google CDN now:

<script src="http://www.google.com/jsapi"></script>
    <script>
        google.load("jquery", "1.3.2");
        google.load("jqueryui", "1.7.2");
</script>

Using this technique will also get rid of this error and improve performance.

The first reference to jQuery (1.3.2) is for the core jQuery library. The second reference to (1.7.2) is for the optional jQuery UI library that you will only need if you are using the UI components/elements of the jQuery library. If you are using jQuery to manipulate the DOM only then you won't need the UI reference.

 

Sunday, November 16, 2008

NoIndex NoFollow

I was just using Google to search Stack Overflow and came up with the following search results:




If you click on the second, third, or fourth items in the search results and then search the page for the term jscript you will find that it's not there. That's because when Google indexes the "hottest" part of Stack Overflow the jscript question was on the page but this is a volatile page and the links from this page change frequently.

Personally I find it annoying when I arrive at an dynamic index page on a site (via Google) only to find that the search term has subsequently been bumped off the list.

Should we do anything about this? And if so, what can we do about this?

First off, I think that you should not have Google index this page. If you have this keyword on your site then let Google focus its results on the page that has this keyword and that talks about this keyword. Spreading a keyword widely across a site is going to dilute its effectiveness and degrade user experience when they visit the site looking for that information.

On the Google Toolbar bar in IE there's the option to enable the happy and unhappy faces to vote on a page when you land there. I don't believe that Google uses this information however it does give me satisfaction when I land on an indexed page which doesn't have the search keyword on it to be able to click the unhappy face.

The obvious exception to this is if you have a stable, non-volatile index which will always have the keyword on it. Although this will not be as effective as landing the user on the content page because it will still require the user to find the link on the landing page and click through.

The way that I accomplish this in C# on my ASP.NET web sites is to set the robots meta tag as such:
 <META NAME="ROBOTS" CONTENT="NOINDEX">

I do this by using a common base class for all my pages. Here's a subset of the code from the base class:
public class CommonPageBase : System.Web.UI.Page
{
    public void SetNoIndexNoFollow()
    {
        SetRobots("NOINDEX,NOFOLLOW");
    }
    public void SetNoIndex()
    {
        SetRobots("NOINDEX");
    }
    public void SetNoFollow()
    {
        SetRobots("NOFOLLOW");
    }
    private void SetRobots(string content)
    {
        HtmlMeta robotsMeta = new HtmlMeta();
        robotsMeta.Name = "ROBOTS";
        robotsMeta.Content = content;
        Page.Header.Controls.Add(robotsMeta);
    }
}

Then in the code behind page for the .aspx page the Page_Load function will look something like this:
public partial class MyPage : CommonPageBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SetNoIndex();
    }
}

You may of course want to make the call to the SetNoIndex() function conditional on an isVolatileIndex type variable. 

Podcasts for Developers

I'm now struggling to find good developer focused podcasts to listen to. When I first discovered Hansel Minutes there were already 109 archived episodes so that kept me busy for several months. Thank you Scott Hanselman. At about the time that I ran out of Hansel Minute podcasts, Jeff Atwood and Joel Spolsky started their Stack Overflow Podcasts. At first I was not that impressed (the first couple of episodes) but I have subsequently become a big fan and it has now pushed Hansel Minutes into second place on my favorites list. This is probably because of Spolsky's arrogant and confrontational personality (this is a good thing) along with his sense of humor. He doesn't hold punches when verbally sparring with Atwood. Although Carl Franklin now makes rare appearances on Hansel Minutes when the two of them were on the air they were too polite to each other to make the conversation as engaging as the Spolsky/Atwood combo. This is a relative comparison though - don't misunderstand me because I still think that their conversations are A-grade and would listen to them anytime.

I've been working my way through the "My developer podcast" (link removed because broker) list on Code de Mora but haven't heard anything on that list that really engages me like the other two do. I've also found a number of podcasts on IT Conversations which I've downloaded but not listened to yet.

So here is my current list of podcasts in favorite order (to be edited when I find more or my preference changes):

Scott Hanselman created a List of Podcasts for .NET Programmers on 9 Feb 2009. He also said "If you've created a list of YOUR favorite .NET Podcasts, send me a link to your blog and I'll add it here" - however, if I did that then you'd end up in an infinite loop.

jQuery Select Notes

class: e.g. <p class="me"> text</p>
jQuery: $('.me')

id: e.g. <p id="me">text</p>
jQuery: $('#me')

element: e.g. <p>text</p>
jQuery: $('p')

elements inside id's: e.g. <ul id="me"><li><a>...
jQuery: $('#me a') will select all the anchor elements <a> under that <ul> tag.

elements inside elements (child tags): e.g. <html><p>text</p></html>
jQuery: $('body > p')

elements next to elements (siblings)
jQuery: $('p + div')

elements with attributes: e.g. <img src="..." alt="..." /> 
jQuery: $('img[alt]') will select all <img> tags with an alt attribute
$('a[href]') will select all anchor tags with an href attribute and thereby exclude named anchors: e.g. <a name="jumpToMyLocation">

elements with attributes having specific values
exact value: $('input[type=text]') will select all input tags with an attribute of type set to text.
starts with: $('a[href^=mailto:]') will select all anchor tags that have an href attribute set to a value that starts with 'mailto:'.
ends with: $('a[href$=html]') will select all anchor tags that have an href attribute set to a value that ends with '.html'.
contains: $('a[href*=content]') will select all anchor tags that have an href attribute set to a value that contains the text 'content'.

filter with : (colon)
$('tr:odd') will filter the <tr> selection from a table by the odd rows using a zero based index for the <tr> tags.
$('a:not([href$=html]') will filter the anchor selection by excluding all anchor tags with href attributes that end in 'html'.
$('li:has(a)') will filter the <li> selection by <li> elements that have <a> elements as child elements. This will result in a collection of <li> tags and not <a> tags.
$('a:contains(click here)') will filter the anchor tags which have the text 'click here'.
$('div:hidden') will get all the <div> tags that are hidden.
$('div:visible') opposite of $('div:hidden')