Saturday, March 28, 2009

The Sift string distance algorithm is now on Codeplex

I've gathered the strength to defeat my sloth and put another of my projects on Codeplex. I am talking about the Sift3 algorithm, described here.

The URL for the project is http://sift.codeplex.com/ where you can download the library and sources in .Net 3.5 C#. A class that also implements Levenstein and Length string distance algorithms is provided.

Please let me know if you are interested in the project, have any suggestions or are even using the algorithm in your projects.

Wednesday, March 25, 2009

Http error 405: The HTTP verb POST used to access path 'something' is not allowed for IIS5 in Windows XP

This error can happen in several situations. One of them is when you are trying to access a web service, another is when trying to call a classic asp page. Most of the time, this happens in situations related to URL rewriting. It may happen in Windows XP or Windows 2000, on IIS 5.0 or IIS 5.1.

Well, first of all, in order to do URL rewriting you need to make ASP.Net process ALL URLs, not only .aspx pages. To do that in IIS5, you need to go to the ISAPI extensions and add a new one for '*' that maps to the ASP.Net dll (aspnet_isapi.dll). This process is detailed in this Microsoft page: HOW TO: Use ASP.NET to Protect File Types. What that means is that when you see a GIF image, it will pass through the ASP.Net engine, firing all the usual events.

However, after you do that, you see that web services start behaving strangely. Why is that? One explanation says that "405 mostly comes about when you try to POST against a URL that is not considered dynamic by IIS". It doesn't much makes sense to me.

I have searched a lot for an elegant solution. The only one that actually applied was using a piece of code in the BeginRequest event in Global.asax (or maybe in a HttpModule that one has to register in web.config). It came from this forum: HTTP verb POST not allowed. Here is the code:

//The BeginRequest event is fired for every hit to every page in the site
void Application_BeginRequest(Object Sender, EventArgs e)
{
var extensions = new[] {".asmx", ".svc"};
foreach (var ext in extensions)
{
var index = Context.Request.Path.IndexOf(ext, StringComparison.CurrentCultureIgnoreCase);
if (index <0) continue;

var path = Context.Request.Path.Substring(0, index + ext.Length);
var pathInfo = Context.Request.Path.Substring(index + ext.Length);
var query = Context.Request.Url.Query ?? "";
if (query.StartsWith("?")) query = query.Substring(1);
Context.RewritePath(path, pathInfo, query);
break;
}
}

Tuesday, March 24, 2009

ASP.Net Menu in Internet Explorer 8 (and beyond!)

I needed a dynamic menu control for my site. So, of course, I tried to use the ASP.Net Menu control (with its many failings when following CSS standards). It was a painful failure. It didn't work in either Internet Explorer 8 or FireFox 3! That was especially strange since I had used the control in a bunch of sites and it worked back then!

Long story short:
<DynamicMenuStyle CssClass=adjustedCssIndex />
where adjustedCssIndex is a CSS class that specifies the z-index property:
.adjustedCssIndex { z-index:100; }


Long story, it seems that the control assumes there is a default z-index value set by the browsers; Bertrand Le Roy from Microsoft says as much in his blog, and discloses a patch fix.

However, as you can see in that post's comments, there is also a very simple CSS fix to all of this, by specifying the z-index.

Sunday, March 22, 2009

Battlestar Galactica ended in EPIC FAIL!

The finale of what seemed to become my favourite sci-fi series ever (at its beginning) left me with a bitter taste in my mouth. Not only it makes no sense, but it is overall incredibly idiotic. If you haven't watched the end of the series, don't read further, because this is the mother of all ranty spoilers ever.

What makes it so emotional for me is not only that I really liked the show, but that this was not a show that was ended because of lack of planning or budget or the economical crisis, so nothing was rushed or changed. This was "meant to happen". And it sucked! Sucked worse that a vampire caught in the event horizon of a black hole that is falling into another black hole!

Not only did it not explain anything in a manner that would make sense to me, but instead it went completely overboard on all the things that I hated in the show. God exists, he somehow planned all this (oh, yeah, real modesty here, mr. Moore!), the model 6 in Gaiuses head was an angel, so was Kara Thrace, in the end they all reach Earth (this Earth) and decide to leave all technology behind (they throw the ships in the sun!!!) in the hope that starting anew would make them "break the cycle" and Hera became the chromosomal mother of all future humans. I guess leaving all that technology behind wasn't a good survival strategy for the rest of the 38000 people left alive, was it?!

If everything was God's plan, then there was no cycle except in its brain!! Forgetting mistakes is NOT a step towards not repeating them. Leaving behind technology is just as stupid! And ending the show with a couple of angels walking on Earth now and making bets on if we repeat the mistakes again or not, with background videos of the latest developments in robotics was.... there is no word in the English language for it. It is dumber than creationist! And the last half of the last episode was all about people saying goodbye to one another then going to live alone (read DIE!!) somewhere!

There is a glimmer of hope left though. The centurions were given their freedom and the last baseship. I will be looking at the sky hoping for them to return, nuke Moore and then air an all Cylon TV show about how they didn't repeat any mistake and just carried on!! Gods, this was frakking retarded!

And, of course, there is one more good thing in the series, and that is the Bear McCreary's remix of Bob Dylan's/Jimmi Hendrix's All Along the Watchtower. I am embedding the video with the cool transition from simple piano to all the instruments. Pretty cool!.

Guess what? F***ing YouTube removed the video because of a copyright infringement. What? One minute and a half of a movie scene? Geez! Couldn't find the same scene, so I am embedding All Along The Watchtower.

The sound bit of the scene, sans the scene, can be found here. You can also see the live performance of the song here. You might also want to try Bob Dylan's original song.

Friday, March 20, 2009

It is a great day... for science!

This is how Dexter, the animated character in Dexter's Laboratory, begins his days. His enthusiasm for his work is amazing and inspirational, but real people rarely feel this way. Today is one of those great days for me! I woke up late, I took a long shower, I've eaten some good food, I've watched one of my favourite anime shows while getting dressed and I came to work in a beautiful sunny spring morning.

What amazing energy and how great a feeling! I feel I can do anything! Throw your legacy ASP applications at me, make me do stupid changes in even dumber web CRMs, give me the most menial degrading tasks you can think of, I will eat them whole and spit out gold! I am unstoppable!

Monday, March 16, 2009

Authenticating Active Directory

Ok, you first must know that Microsoft added a specific namespace for working with ActiveDirectory in .NET 3.5. It is called System.DirectoryServices.AccountManagement. The principal objects in the Account Management API include computer, group and user objects and it provides a means for applications to extend the object model to include custom schema object types.

Now that this is out of the way, I want to take my simple Authenticate, ListUser and ReadUser methods (working fine with the old DirectoryEntry method) and translate them into this new way of doing things.

I did some code and I got this error message: "80075000". That is the actual error Message property! Even more remarkable, a google for 80075000 resulted in only 246 results!! none of them explaining what I did wrong. Apparently, I had sent a string in the format "LDAP://ComputerName" as the computer name. Maybe it helps someone.

But this didn't solve it. I changed it with just the computer name, with or without a "\\" prefix, and I got a more clear text, but just as vague UnauthorizedAccessException: "General access denied error".

I am still working on it, but damn, how can a programmer not think about the error message he passes to other programmers?!

Ok, made it work, here is the code for the user authentication in an Active Directory domain.
Classic DirectoryEntry:

bool authentic = false;
try
{
var entry = new DirectoryEntry("LDAP://ComputerName",
"Domain\\username", "password");
object nativeObject = entry.NativeObject;
authentic = true;
}
catch (DirectoryServicesCOMException ex){}
return authentic;
As you can see, not the most elegant approach.

The .NET 3.5 way:

using (var context = new PrincipalContext(ContextType.Domain,"ComputerName"))
{
return context.ValidateCredentials("username","password");
}
Much better, isn't it? Pay attention that in the first case you need the domain in the username and in the second you need it not to be part of the username!

There is a third way (System.DirectoryServices.Protocols.LdapConnection), but seems too complicated to address right now.

Saturday, March 14, 2009

Monday, March 09, 2009

How to make a Visual Studio 2008 Sharepoint project

Recently I have been working on this Sharepoint project. I took it more out of curiosity as I didn't know anything about this piece of software. Now I know a lot more, like how hellish it is to code against it :) But it is also not a bad idea.

In case you don't know (as I didn't) Sharepoint is something like an ASP.Net site designed to work within a company, as an internal tool, allowing a lot of customizations and security from the web interface, with no code required. The desired end result is something looking like the IGoogle or Yahoo home pages, with web parts that can be configured, moved around, minimized, closed, made to interact one with another. Sharepoint Services is in itself a free software, but it only works on a Windows 2003 server or higher, so it sucks that way. Also, there is no real Sharepoint support for Visual Studio and most of the tutorials you find online are either too specific (blogs and such) or too vague (Microsoft style).

Also, there is a lot of confusion regarding the use of the interfaces in the Sharepoint dll, most of which have been obsoleted when the web part engine from .Net 2.0 was introduced.

Ok, short list of steps on how to start making a Sharepoint project in Visual Studio, assuming you code in Windows XP:
  1. Install Windows Server 2003 on another machine (virtual or not)
  2. Download and install Sharepoint Services 3.0 SP1 on it
  3. Get the Microsoft.Sharepoint.dll file and copy it on your XP machine somewhere
  4. Download and install the Sharepoint SmartTemplates for Visual Studio
  5. Update the WSPBuilder application and some batch files in the template files
  6. Start Visual Studio and create new project from installed templates
  7. Add a reference to the Microsoft.Sharepoint.dll library
  8. Code!
.

Now for the long list.
In order to install Sharepoint Services 3.0 SP1 you need to also install .Net 3.5 SP1. Actually it is a good idea to install this as well as the Visual Studio 2008 SP1 before you do anything (Sharepointy or not). Here is a link.

The Sharepoint SmartTemplates actually create a folder structure that is then used by the WSPBuilder utility to create the WSP file that installs a web part in Sharepoint. You can either import it in the site (upload) or use the setup that is provided with the templates. The problems I met when using it are linked primarily with the version of WSPBuilder that is included in the templates I've downloaded (version 0.2).
So first locate the installed template files: you can usually find them in My Documents/Visual Studio 2008/Templates/Project Templates/ as two zip files. First step is to download the latest WSPBuilder and replace it in the archives. The next step is to change the WSP/createwsp.bat file like this:
@ECHO OFF
DEL .\$safeprojectname$.wsp
ECHO Copying DLL ...
XCOPY /Y ..\BIN\$safeprojectname$.dll .\80\BIN\
ECHO Copying ASCX files ...
XCOPY /Y ..\*.ascx .\12\TEMPLATE\CONTROLTEMPLATES\$safeprojectname$\
ECHO Building WSP ...
..\WSPBuilder\WSPBuilder.exe -WSPName $safeprojectname$.wsp -BuildCAS false -SolutionID $guid2$ -DLLReferencePath "[the folder path where you copied Microsoft.Sharepoint.dll]" -TraceLevel Verbose
ECHO Copying WSP file ...
XCOPY /Y .\$safeprojectname$.wsp ..\SETUP\

The bold parts you must add to the file. The delete because otherwise you might be able to compile the project using the old WSP file if the WSPBuilder run fails. The others is in order to be able to compile the WSP using the sharepoint library and see any errors that might occur.
Alternatively, you can change the WSPBuilder/WSPBuilder.exe.config file with the DLLReferencePath and TraceLevel options.
Ok, now repack the folders into the archives and copy them back.

Now, after you build the project, you will have a Setup folder in the bin folder. That you must copy to the Windows 2003 computer and run. It will install the web part(s) in the project. In order to add more webparts to the project and make them compile in the setup project you need to alter the WSP\12\TEMPLATE\FEATURES\SmartPartTemplate\manifest.xml file and describe the files you add to the project.

After you run the setup project, you have to open the Sharepoint site and go to Site Settings -> Site collection features and activate the web part. Only then you can actually add it to a page.

Sounds complicated? Well, read more :)

Make sure that when you have finished with a web part you DO NOT DELETE THE SETUP PROJECT, but run it to remove the web part first! In order to remove an install web part from a Sharepoint site you must delve into the hell of command line utilities! Well, it's natural to me, but I am an old guy! ;)

Just supposing that you have done the undoable and you managed to delete a setup project with the part still installed, you must use the stsadm tool.
First find it on the Windows 2003 computer (with Find Files) then add the containing folder to the path. Then run cmd in the Start/Run menu and use the following commands:
stsadm -o enumsolutions
will enumerate the installed solutions. Remember the name of the solutions you want to remove.
stsadm -o retractsolution -name "[name of solution]" -immediate
will retract the web part project and allow you to delete it.
stsadm -o deletesolution -name "[name of solution]" -override
retracting doesn't always work, so the override option will force a delete.

Sometimes you manage to change the GUID of the project and you get an error like A solution with the same name "SomeName.wsp" or id "Some GUID" already exists in the solution store.. You delete it, but you still have this error. Try to install the solution with the setup project. Wait for the error, exit the setup project. Use stsadm -enumsolutions to see what the GUID of the project is, copy it, replace the SolutionId GUID in the setup.exe.config file with this one. The setup should then work.

This is about it. I've wasted a few hours to learn all of this. I know it's not terribly organized, but writing something is better than sharing nothing.

Three little cool utilities!

I haven't been writing for a while, but that is because I was working! Amazingly so, as I am not known for my willingness to work. But that also has its boons, you know, as I will not only gain material wealth for my wife's shoes, but also material for the blog! :) You will have to wait a bit for that, though.

Instead, I will talk about three little gems I found while browsing ShellCity. In case you don't know, ShellCity is a blog dedicated to the tools, not the result. Every day four free utilities are being presented in this retro looking site. Anyway, without further due:

Fences. This allows you to organize your many desktop icons by grouping them into labeled transparent folder like structures. Not only does it make your desktop look better and feel better, but when you change your desktop resolution, it also remembers the location of these groups so that when you revert, you get them in the same position! Great thing to have and my favourite in this post.

MSVDM, or the Microsoft Virtual Desktop Manager. This is pretty old stuff, but I've only recently discovered it. It is NOT an exe file and it will not be installed in the Start menu! Instead it is a taskbar toolbar. It shows four buttons which allow you to switch between four different desktops. The desktop icons remain on all of the desktops, but you can define a different background for each and the opened windows are different from desktop to desktop. So, what you use it for is to open a group of utilities based on context. As an example, open a Visual Studio and some browser windows regarding a certain project, then open another Visual Studio and some other browser windows for another project that you work on simultaneously.

WizMouse. This one is not something you immediately go Wow! about. It sits in the traybar and does only one thing: it scrolls windows when you move the scrollwheel. But it doesn't scroll the active window, but the window directly under the mouse pointer! A lot of annoyance is saved by this.

Hope it helps you all. Till next time!