and has 0 comments
Just a small mention of a thing I've learned today: what is the FullName of a Type of a class that is nested into another?

Usually, you would use it inside Visual Studio as ParentClass.ChildClass, but if you ever want to use the full name of the ChildClass Type (as when declaring it in web.config) you have to separate them with the + (plus) sign.

So let's assume you have this MyHandler class in the MyNamespace namespace which has a nested class Configuration in it. In the code you do a
var conf = new MyNamespace.MyHandler.Configuration();
while when using the handler type name to declare it in web.config you do it like this:
type="MyNamespace.MyHandler+Configuration"
.

First off, I have to say something about forums: stop copying content from one another, jerks!. I have been trying to find a solution for this problem and I found a zillion forum pages with the same "problems" and the same "solutions" again and again and again!

Much better! Now, I have been trying for an hour to understand why setting customErrors="Off" in the web.config of my ASP.Net application would not work. I tried just about anything, including the bloody forums. customErrors Off did not work!.

In the end I found one little comment for a StackOverflow question: set the retail setting in the machine.config file to "false"!! So, go to %WINDOWS%\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config and set retail to false!. Setting it to true means it will NEVER show you any useful debugging message.

A while ago I wrote a post detailing a fix for Very slow UpdatePanel refresh when containing big ListBoxes of DropDownLists. I have restructured the fix into a ControlAdapter and placed it on Github.

Enjoy!

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

The URL for the project is https://github.com/Siderite/Sift3/ 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.

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;
}
}

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.

and has 4 comments
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.

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.

This is a message I got from the UpdatePanel Shrinker in a site we built:
Shrinkage: from 70000 to 10 = 0.014%.


Almost a year ago I thought of a way of compressing the UpdatePanel asynchronous output based on the previously sent information and created the UpdatePanel Shrinker. I waited all this time to test it and also I've used it in some small projects.

From today, the project is on Github, with an MIT licence, that means do whatever you want with it, but I would appreciate some words from you.

As for the details: it uses a sort of fast and dirty home made diff algorithm to compare the previously sent output for an UpdatePanel with the current one. The problem is that the effect can only be seen from the second async postback on, but when used, it yields fantastic compression rates.

You can use it for sites that are accessed from Internet challenged locations, for sites that have complex Ajax interactions and for sites that you "Ajaxify". And before I get angry comments from purists, yes, I know it is more efficient to use Ajax in a smart way to solve each problem in the best possible way, but if you just want the quick and dirty solution, like a MasterPage with a ScriptManager, an UpdatePanel and the page content in it, the Shrinker is the thing for you.

Take care to look in the Debug Output window. The shrinker will output the compression rate and any warnings it might have.

I have this cool thing I made that needs a HttpHandler to process some commands. Therefore, in the code, I am trying to change the web.config whenever possible. I do it in the usual way:
WebConfigurationManager.OpenWebConfiguration("~");
... .Save();
. That should work fine, unless you don't have writing rights on the web.config file. But you don't need only that! I gave rights to the web.config file, but I got this silly error: "changing web.config An error occurred loading a configuration file: Access to the path 'bla...bla...bla...bla.tmp' is denied.".

In other words, in order to write to the web.config you also need rights to add files to the web folder in order to create temporary files. Hmm, I thought the temporary files folder was used for that... :-|

You are using a PopupControlExtender from the AjaxControlToolkit and you added a Button or an ImageButton in it and every time you click on it this ugly js error appears: this._postBackSettings.async is null or not an object. You Google and you see that the solution is to use a LinkButton instead of a Button or an ImageButton.

Well, I want my ImageButton! Therefore I added to the Page_Load method of my page or control this little piece of code to fix the bug:

private void FixPopupFormSubmit()
{
  var script =
    @"if( window.Sys && Sys.WebForms 
    && Sys.WebForms.PageRequestManager 
	&& Sys.WebForms.PageRequestManager.getInstance) {
  var prm = Sys.WebForms.PageRequestManager.getInstance();
  if (prm && !prm._postBackSettings) {
    prm._postBackSettings = prm._createPostBackSettings(false, null, null);
  }
}";
  ScriptManager.RegisterOnSubmitStatement(
    Page, 
    Page.GetType(), 
    "FixPopupFormSubmit", 
    script);
}



Hope it helps you all.

I wanted to use this Accordion control on a page and so I specified the ContentTemplate and HeaderTemplate and gave it a DataTable as a DataSource and DataBound it. Nothing! No errors, no warnings, no display of any kind. After a few frustrating minutes of trying to solve it I asked buddy Google about it and it turned out that the Accordion control MUST receive a DataView as a DataSource and nothing else. Using datatable.DefaultView solved it.

I've been listening to my favourite podcasts, HanselMinutes and .NetRocks, as usual and I've stumbled upon another gem of a show. It was about Test Driven Development. Why am I talking so much about this, although I don't practice it? Because I am sure I will get around and do practice it. It is not just a hype, it is the only way to do software. And I will explain why. But before that, let's talk about a confusion that has been cleared by the show I have been talking about.

The name Test Driven Development is usually associated with Automated Unit Testing. While this is mostly used only in TDD, it is not required by TDD at all. The badly chosen word Test actually means "meaningful, measurable, goals", in other words, the specifications! If you have those, you can test your application against the requirements and determine what is wrong, if anything. Without a clear view of the specs, you cannot tell if the project is performing as needed.

So if you think about TDD as Specifications Driven Development, you realize that you have been doing it all along! Admittedly, now it sounds even more like STD, but hey, sacrifices must be done in the name of improving code blog readability.

Now, I was saying that this is the only way to do software. Actually, I have explained why just above, but I will get into some personal details. I have been "blessed" with a project where the deadline was set before the specifications were drawn. Worse even, the specs did not come from people that really understand the business process, but from people using another piece of software that they want replaced. In other words, we're pretty much inventing ways of porting a badly designed Windows desktop app into ASP.Net. As this wasn't enough, we are also inventing features that were badly described by the client and starting from a partially functional ASP.Net project written by junior programmers.

What a drag! But that was actually not so bad as realizing that my developer output was slow, bad, and overall smelly and ugly. Why was that? Why couldn't I just stop whining and do what I know had to be done? Because there were no specs!. Without clearly drawn specs of not only what I had to do, but also what the initial project was supposed to do, my hands were tied. I could not refactor the code, because I had no way of telling if I broke anything. Has it ever happened to you to take a piece of code, make it better, then realize it is not working and you don't know why? The fear of that happening is the most important reason why people don't refactor. The next important factor being a manager that thinks refactoring is just a waste of time and has no vision of the future of the project.

But also, having no vision of what is to be done is the reason why developers are not motivated to do their job. Even the lowliest code monkey has to have a glimpse of the future of what they are doing, otherwise they are literally flying blind. Software development is just as much of an art as web design. It is actually strange that people don't understand there are many types of art just as there are many types of scientific thought. Even if we don't actually care how the app is gonna look as long as it does the job, we do feel pride in its functionality and it is nothing that hurts more as not knowing what that software is supposed to do and a clear way of measuring our own performance.

OK, enough of this. The bottom line is that a project needs to have clear specifications. The first test for a software is the compiler! You can even call it an automated test! ...but the last test is running through the spec list and determining if it does the job as required. Another podcast said that the process of creating automated tests has as a side effect the significant improvement of software quality, but not because of the tests themselves, but of the process of designing the tests. If your tests are meaningful, then you know what the app is to do and you have a clear vision of what failure and success mean and in the process of test design, you get to ask yourself the questions that lead to understanding the project. THAT is Test Driven Development!

Update: it has come to my attention that these kind of errors appear only when debug="true" in the web config. In production sites it might work regardless.

You want to programatically load a js in a user control. The user control becomes visible in the page only during async postbacks and it is hidden at page load. So you want to use some method of loading the external javascript file during that asynchronous UpdatePanel magic.

Use ScriptManager.RegisterClientScriptInclude. There is a catch, though. For each script that you want to include asynchronously, you must end it with
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
else the Ajax.Net script loader will throw an error like: Microsoft JScript runtime error: Sys.ScriptLoadFailedException:
The script '...' failed to load. Check for:
Inaccessible path. Script errors. (IE) Enable 'Display a notification about every script error' under advanced settings.
Missing call to Sys.Application.notifyScriptLoaded().
.

For the aspx version, use the ScriptManagerProxy control:
    <asp:ScriptManagerProxy runat="server">
<Scripts>
<asp:ScriptReference Path="~/js/myScript.js" NotifyScriptLoaded="true" />
</Scripts>
</asp:ScriptManagerProxy>

So you did some work in an ASP.Net web site and then you decided to or to add the Ajax extensions to it or switch to ASP.Net 3.5 or whatever and suddenly you get Ajax errors like "Sys is undefined" or you don't see images and the css files are not loaded. And after googling like crazy and finding a zillion possible solutions you decide to enter in the browser address bar the url of the offending image, css file or even ScriptResource.axd files containing the ajax javascript and you see a beautiful ASP.Net error page displaying "Session state is not available in this context.". Huh?

There are some reasons why this might happen, but let's examine the one that actually prompted me to write the article. Someone made a change in global.asax, trying to work with Session there, more precisely in the Application_AcquireRequestState event. The error was returned by the Session property of the HttpApplication object, the one that the global.asax file represents! In fact, this error can only be thrown from there in the current ASP.Net implementations.

First mistake: there was a Session property available in the HttpApplication object and it was immediately assumed that it is the same as Page.Session or HttpContext.Current.Session. It is about the same, except it throws an error if the underlying Session object is null.

Ok, but why is Session null? You are a smart .Net developer and you know that the Session should be available in that event. Any documentation says so! Yes, but it applies to your page, not to all the IHttpHandler implementations, like ScriptResource.axd! Also, the css and image problems occured for me only when opening the site in Cassini, not in IIS, so maybe it opens separate threads to load those resources and ignores the session or something similar, at least at that level.

Well, how does one fix it? Adding in global.asax a condition on Session not being null throws the same error, so you have to add it on HttpContext.Current.Session. In other words:
if (HttpContext.Current.Session!=null) //do stuff with sessions

Maybe this problem occurs in other places as well, but only the Session property of the HttpApplication will throw the "Session state is not available in this context." error.