Thursday, May 24, 2007

A problem with ASP.NET client side validation and IIS host headers

I've just had an interesting issue when deploying an ASP.NET application on to a web site that uses host headers. Host headers is where you can point multiple domains at a single IIS and IIS can resolve them to multiple virtual directories. ASP.NET requires some javascript files in a virtual directory under the root called ‘aspnet_client’ for its client side functionality such as the validation controls. If you’re creating your application in a virtual directory, e.g: http://www.mydomain.com/myapplication/ Then installing the .net runtime will put those files in the right place for that app: http://www.mydomain.com/aspnet_client/ The problem comes when you use host headers to resolve additional subdomains to a virtual directory: http://subdomain.mydomain.com/ ASP.NET looks for its javascript files here: http://subdomain.mydomain.com/aspnet_client/ But it won’t find them unless you remember to manually copy that directory to the root of your application. It’s something to be aware of (especially since it happened to me twice, double duh!)

Tuesday, May 15, 2007

Playing with JSON

I recently had to do some web development work which involved passing an object graph from the ASP.NET server code through to the browser to be consumed by javascript. The last time I had to do something like this was for an intranet application where the browser platform was alwasy going to be IE on Windows. I used XML as the serialization format and consumed it on the browser by instantiating an MSXML DOM. It worked, but it was strictly a Microsoft platform solution and the javascript code was pretty ugly, all that digging around with xpath, urgh! This time the requirement was for an internet application, so I had to choose something that would run on any modern browser. I remembered reading about JSON somewhere as the serialization format of choice for javascript developers, so I decided to give it a whirl. I did a bit of googling and found a couple of .NET JSON libraries, Json.NET by James Newton-King, and Jayrock by Atif Aziz. Atif is also the author of this great introduction to JSON on MSDN, well worth a read. Both of them seemed to fit the bill, but my client was a strictly .NET 1.1 shop, so I had to go with Jayrock since it was the only library with 1.1 support. Jayrock provides quite a comprehensive collection of JSON serialization libraries as well as a JSON RPC IHttpHandler implementation that lets you write JSON 'web serives'. However, all I needed was the serialization function. It worked like a dream for my simple scenario, just one line of code to serialize my object graph to a string:
string jsonText = JsonConvert.ExportToString(myObjectGraph);
Because JSON is effectively native javascript you 'de-serialize' your graph on the client by simply calling 'eval' with your JSON text:
val myObjectGraph = eval(jsonText);
For this simple scenario to work, the objects in your graph have to have a default public constructor and all properties must be settable and gettable, just like when you use the .NET XmlSerializer. But really, so much easier than all that messing around with XML. Of course JSON is extensively used in AJAX applications, even though the 'X' stands for XML :) And there's JSON support built into ASP.NET AJAX (formerly Atlas) in the System.Web.Script.Serialization Namespace, specifically the JavaScriptSerializer class. So if you are doing ASP.NET 2.0 work, you can use that instead of Jayrock. All I need now is an excuse to do some serious Ajax programming.

Monday, May 07, 2007

My new Web Service Test tool, WsdlWorks

I've been working on an open source web service test framework for Visual Studio over the last few months. It's called WsdlWorks. That's why I was blogging about creating new VS project types here and here and problems with WCF and WSDL. I've decided to host it on CodePlex because it seems to be the preferred place for Microsoft related open source projects. I just created a new project for it here and uploaded the source. The CodePlex source control client is a pretty basic command line based thing, but it's prefectly fine for a little project like this. Here's a screen shot of WsdlWorks: As you can see it creates a new Visual Studio project, you right click the project node, select 'Add WSDL from URL', enter your WSDL's URL in the dialog that appears and then WsdlWorks automatically creates nodes for all the services and their operations. It also creates initial requests for each operation, but you can add as many as you want. To execute the request, you just right-click on the request node and select 'Run'. When you create a request it reads the WSDL's XSD for the request types and creates example data in the request. I used XmlSampleGenerator, by Priya Lakshminarayanan to do this. I tried to get it working with WCF multipart WSDLs, but haven't succeeded yet. The error handling, icons and other stuff is also still on the 'to do' list, so it's far from production ready, but I thought I'd release it now in the best open source tradition since it's in its initial working state. You can't release Visual Studio packages without a package load key, and you can't get a package load key without having a homepage for your project. But now I've got a homepage I can get the PLK. Expect an installer pretty soon. For the time being, if you want to play with WsdlWorks you'll need .NET 3.0 and the Visual Studio SDK so that you can run it in the experimental hive.

Thursday, May 03, 2007

Permissions needed to access the IIS metabase remotely using WMI

In my last two posts I've been talking about programatically reading and editing the IIS metabase using WMI via System.Management. In my examples I've assumed that the code has access to an administrator account's username and password. Of course you wouldn't want to do that in real life, putting an admin password as a literal in your managed code is not a good idea. A much better idea would be to have your application run under a low privilege account and just give it the permissions it needs to access the metabase using windows integrated security. To do this you need these permissions:
  1. Create a new account with minimum rights that your application will run under.
  2. On the web server with the metabase you want to access, add the user to the 'Distributed COM Users' group. This is because WMI uses DCOM.
  3. Open 'Administrative Tools' -> 'Computer Management'. Expand 'Services and Applications', right click 'WMI Control' and under the Security tab, expand 'Root'. Find the 'MicrosoftIISv2' node and give the user the required permissions.
  4. Finally you have to give access to the nodes you require in the metabase. Using the metabase explorer (from the IIS Resource Kit), find the node you want to access, right click it and choose permissions. If the node doesn't have any permissions set a dialog will ask you if you want to copy the permissions of the parent node or edit the parent node permissions, make your choice and then set the permissions you require in the permissions dialog.