Using CSS to scale images

December 12th, 2007

Typically you wouldn’t want to do this but if you ever have the need… well, here ya’ go.

The styles max-width and max-height work for images. Just create a style as follows:


.resize400
{
max-width: 400px;
max-height: 400px;
}

Note that the code will only work in Mozilla > 1.5 and IE > 7.0. To make it work in IE 6.0, use a selector and modify the style as follows:

.resize400
{
max-width: 400px;
max-height: 400px;
width: expression(this.width > 400 ? 400 : true);
height: expression(this.height> 400 ? 400 : true);
}

I take no responsibility for how ugly this will make your images.  And forgive the formatting.  I’m fighting with WP at the moment and it seems to be winning.

andy Uncategorized

WSS 3.0 (MOSS/SharePoint), Site Collections, and Server.MapPath

November 15th, 2007

One of my current projects is a Commerce Server/MOSS 2007 integration project.  I had the need to know where to store the configuration of a sub-site within a site collection of the main web application.

For those of you familiar with ASP.NET 2.0, you know that if you want to find the root of the application, you use Server.MapPath.  Turns out the the root directory (~/) and the bin directory (~/bin — typically) are the same as the parent site.  This means that if your sub-site needs to read information from the web.config then you can store it in the web.config of the parent application.

There is one downside to this.  If you have multiple instances of the same site definition within the same web application, there is no way to separate values within the web.config.  As an example, assume you need to email an administrator when a site experiences a problem but the administrator is different for each subsite.  This information cannot be stored in the web.config as both subsites in the site collection will share the configuration.

This may not be news to some, but without years of SharePoint/WSS experience I found this important to share.

andy Commerce Server, Development, SharePoint

XML Validation

November 3rd, 2007

I just recently had to convert a DTD from UPS into an XSD as part of a Commerce Server integration project. Wanting to test my code (imagine that), I needed to validate both the XSD and sample XML against it. To create the schema I used dtd2xsd available on GotDotNet — looks like MS got stuck holding this open for a bit.

I then needed to create a couple small tools to test the output. Ok, I didn’t NEED to do it, but I love to write tools and they help me procrastinate. Anyway, after a couple of tweaks to the generated schema to solve a UPA problem I validated that the schema was valid and could be used to reliable validate the XML. The benefit of the schema is that I can generate the classes to handle this data using xsd.

If anyone is interested in the tools, they are simply two .NET 2.0 console applications that were based on samples available online. I’ve attached the binary versions to this post but if you want the code feel free to disassemble them.

Validate.zip

andy Uncategorized

ASP.NET, WebResource.axd, and Reverse Proxies

October 23rd, 2007

Sometimes it’s necessary to host applications behind a reverse proxy. While the application may appear locally as http://somehost.com/someapp, the outside world would see the application as http://somecompany.com/ — so this is the opposite of the typical scenario, but the premise is the same. This is all fine and good and is easy enough to setup with Apache in the front end on the cheap.

The problem occurs with how ASP.NET tells the client to retrieve embedded resources. Embedded resources are typically returned to the web client by a call to WebResource.axd that exists in the application root (~/) — the file’s not actually there, it’s a handler. From the ASP.NET application’s perspective, ~/ maps to /someapp. However, the web client is assuming that the application root is / because they’re looking at the pages through the reverse proxy, a proxy of which ASP.NET is blissfully unaware.

As stated earlier, the true application root is /someapp and ASP.NET tells the client to access WebResource.axd at /someapp/WebResource.axd. The web client assumes that this is appended to the current root which is http://somecompany.com/ and then tries to retrieve WebResource.axd at http://somecompany.com/someapp/WebResource.axd, a location that the proxy then maps to http://somehost.com/someapp/someapp/WebResource.axd. This isn’t accounted for in the http handler’s mapping and the request returns a 404.

The 404 File Not Found code is problematic in that WebResource.axd is the handler responsible for returning all of the embedded resources in the application — typically JavaScript for ASP.NET user controls, ASP.NET validation controls, and 3rd party controls. The application breaks and it’s bad times for all. Enter UrlRewritingNet.UrlRewrite.

This free open source library will allow rewrites to be performed simply by adding a couple entries in the application’s web.config and including the library in the application’s bin folder. This is perfect for shared hosting environments where access to the actual server to install isapi rewrite is not possible.

The documentation is pretty clear, though the English is a bit broken, and contains the enumerated steps for installation into the application. Once the library has been installed, all that’s left is to write some simple rewrite rules.

Inside the web.config, for this application, we would add the following rewrite rules

<urlrewritingnet xmlns="http://www.urlrewriting.net/schemas/config/2006/07" >
<rewrites>
<add name="WebResourceFix" virtualUrl="^~/WebResource.axd(.*)" rewriteUrlParameter="IncludeQueryStringForRewrite" destinationUrl="~/WebResource.axd$1" ignoreCase="true"/>
<add name="ScriptResource" virtualUrl="^~/(.*)/ScriptResource.axd(.*)" rewriteUrlParameter="IncludeQueryStringForRewrite" destinationUrl="~/ScriptResource.axd$2" ignoreCase="true"/>
<add name="ReplaceRoot" virtualUrl="^~/(.*)/(.*)" rewriteUrlParameter="IncludeQueryStringForRewrite" destinationUrl="~/$2" ignoreCase="true"/>
</rewrites>
</urlrewritingnet>

This rewrite rule will take any inbound request to /someapp/WebResource.axd and map it to /WebResource.axd. This ends the 404 and its good times for all.

So far, I’ve had nothing but success with this approach and have extended it to handle the ASP.NET Ajax resource tool ScriptResource.axd that suffers from the same fate. Additionally, if Web Service callbacks are used in the application for Ajax invocation, the same rules will need to be applied to the page and it may be easier to simply remap anything that comes in for /someapp to /.
Note, there are other methods that will allow you to fix some of these issues, but they’re not always achievable in shared hosting environments or in environments where configuration is tightly controlled. Further, this does not handle problems with using web.sitemap in an application that is behind a reverse proxy but that will be left as an exercise to the reader.

andy ASP.NET, Ajax, Development

Been a while

October 23rd, 2007

Not that anyone is reading this at the moment, but I’m going to try and start updating this regularly.  Here’s hoping.

andy Announcements

New Business and Postponed Shareware

April 4th, 2006

Last week, and this, have been exceptionally busy here at Meadows Design.  In the last 10 days I’ve landed 3 new contracts with the possibility of adding two more.  These contracts include the addition of two new clients for our web design and hosting services: Canes Crossing and Pine Pointe — both new housing developments in the South East.  The other guaranteed contract and the two possible additions are with Thoughtmill, an existing client.  All of the Thoughtmill work will be ASP.NET work.

With the addition of the new work, I must personally make some sacrifices.  As such, I’ve put the Event Viewer shareware application — my personal project — on hold until I can dedicate the time to it that it deserves.  I’ll probably spin back up on it in 6 weeks or so.

I’d love to write a little more but work calls.

andy Announcements, Clients, Shareware

Shareware Announcements

March 28th, 2006

I am going to revive some of my older shareware applications and begin work on some new ones. They are as follows:

Add/Remove Programs Cleaner
This program allows you to HIDE entries that would otherwise appear in the Add/Remove Programs control panel applet. This application does not remove them entirely from your computer, nor does it uninstall them. It simply is a tool to clean-up the clutter — you know you want to get rid of all of those Hot Fixes listed there.

This program is being re-released into the wild and it has NO updates. Standard disclaimer about modifying your registry applies, though I’ve personally had no problems with it.

Did I mention it’s free? Download it now.

Event Viewer
Currently under development, this will be a replacement for the TERRIBLE Event Viewer MMC plug-in that’s been in Windows since the NT days. Sorting, searching and filtering of local and network logs will be available in the first version and future versions will allow you to monitor log files and perform diffs across multiple machines.

Windows only, sorry. Oh, and NOT free, but CHEAP.

Expense Tracker
This one is for the Mac people out there. This will be so simple to write, it’s probably gonna be free but I haven’t decided on it yet. Also in the development stages, this application will allow you to track expenses and file them into categories. That’s it. It’s simple and lightweight. Targeted at those who do not use financial management software — or use it on Windows — but want to track their individual expenses for a personal business, project, etc, Expense Tracker will provide a light-weight alternative to all that’s out there.

Client Billing
I was SO excited about this, but I think I’m gonna have to 86 it. This was to be an OS X Cocoa based application that would allow independant contractors to track time that they apply to a particular account on any given day. Recently, I discovered iBiz and while I have some issues with it my time would probably be better spent working with the author than writing my own. I have enough projects as it is. Had to throw this blurb in though incase I change my mind.

LlamaBase
Llama is a secret. I can’t tell you about it… yet.

andy Announcements, Shareware

MacBackup Review

March 28th, 2006

MacBackup was on the shelf at the Apple store. I really don’t want to pay for Retrospect and I have a shell script that I use that works pretty well for me. It’s a little slow, but I wrote it, I understand it, and as I said: It works. So, for $30 I took the plunge and bought MacBackup. The problems with the software became apparent when I got home.

Let the Beatings Begin
First, I wanted to set up a backup set that would happen every Sunday morning around 2:00 am. Opened up the manual as any RTFMer will do and low-and-behold I can’t do that yet. The manual states that I have to actually run a backup before I can set that backup on a recurring schedule. I, for the life of me, cannot understand why this is necessary but I am not the most skilled Cocoa programmer (that would be Kevin) so off to begin a backup I go. This leads to my next problem with the software: choosing what to backup.

I understand what the developer wanted to do; I just don’t think it was executed well. When I create a backup set, I would like the ability to include everything here except a certain file or files. If I say include everything on the desktop, I mean everything on the desktop. If the desktop content later changes, then capture any new files or remove the ones that no longer exist. I must add a disclaimer here that will spoil the ending, but I never did complete a backup set so the addition and removal of files may actually work — I was just unable to test it.

Backup Modes
There are different modes that you can use to backup and restore information: Easy and Advanced. Easy is drag and drop while Advanced provides a checkbox mechanism. The application tries to assist you by presenting a list on the left-hand side of locations and/or file types you may want to backup — for Easy Backup this list is Photos, Music and Movies, and Both. We will call these items on the left “categories”. On the right side of the application is, generally, what you have selected to backup from within the chosen category.

Easy Backup
The problem I have with Easy Backup is that it’s too complicated to be dubbed Easy. Let’s say I want to backup my Music… ALL my music. You would think I could select Music and Movies from the helper list and then click “Start Backup”.

Unfortunately, I can’t do that. I can either drag and drop a folder or a series of files onto the right side of the application, the side that contains the files I want to backup, or I can tell it to search for Music and Movies, a process that scours my ENTIRE computer looking for files I MIGHT want to backup.

I believe that most Mac users like simplicity or they’d be running Windows or Linux. Likewise, I believe most Mac users use the preferred locations in which to store their music, movies, etc. To me, easy would be me telling the application to backup my iTunes music and it goes and does it. I don’t want to wait for it to search every drive on my computer or for me to have to open a finder window, grab my music folder, and drop it on the application.

Likewise, when I go to click “Start Backup”, I’m unsure as to what it is I’m actually backing up? If I click on the “Music and Movies” category and then tell it to go Search for these items, it populates the list. When I then click on “Both”, the list disappears? Now, to be fair, everything that I’ve added to any of the lists is backed up, but if I have a category named “Both”, I would expect it to contain the union of the prior two categories and not be a separate list entirely.

Advanced Mode
Advanced mode is a whole other beast entirely. First, there is a huge disconnect between easy and advanced. In easy mode, everything on the right is backed up and I can remove items from the list. In Advanced Backup mode, I have to check what I want backed up and uncheck what I don’t for certain categories. In other categories, say Photos or Music and Movies, the Advanced mode behaves identical to its sibling. When I select the “Mail and Settings” category I get exactly what I’m looking for. I can tell the application to backup my entire Mail folder because it has it right there waiting for me. This, I like. But if I want to backup my Preferences with the “System Settings” category, the application behaves entirely contradictory to the action I just described. Whereas the “Mail and Settings” category displays a list of folders to backup — notably, Mail and Entourage Mail — selecting the “System Settings” category requires me to select a new category labeled “Preferences” where I can select ONE item: Preferences. Why?

At this point, I have become thoroughly frustrated because ALL I want to do is replace my shell script/cron-job solution with something that’s very OS X feeling. So, I go to the “Folders and Files” category and start drilling down through the file system selecting the items I want and then, at 11:00 pm that evening, satisfied that I atleast had a “new” solution if not an optimal one, I clicked the “Start Backup” button that began a backup of 2GB of data to a network drive across a 100Mb LAN using low compression.

The Day After
At 3:00pm, the next afternoon, 16 hours later, I cancelled the backup. That is to say, I TRIED to cancel it but the application would let me repeatedly click the cancel button and progress bars kept pixeling themselves along — tracking what progress I have no idea. I finally told the application to Quit, a command it seemed all too pleased to follow.

Funny story though. Once I relaunched the application I had, in my recent backups list, a backup that I had quit and for all intents and purposes had failed — a backup I could schedule.

Summary
Honestly, for $30, the product isn’t terrible. If you want to periodically backup your iTunes music to DVD, I’m guessing this product will work for the novice user. It will allow you to break backups across multiple discs and that is a nice feature.

However, for $30 I can do that myself by dragging and dropping items into a “Burn Folder”. I want my backups to work unattended where I don’t have to babysit the process and this software just won’t do it for me.

In the end, I go back to my shell script. I’m $30 poorer and I don’t want you to share the same fate. So, to the one reader we have out there I have made my shell script available on the Meadows Design site for download. It’s free, it’s hackish, but it works and you can read a little about it and how to use it in my blog over there.

andy Rant, Reviews, Technology

Arrrghh! One of those weeks.

March 23rd, 2006

Where to start, where to start?

Judge of Character
So I’m talking to a potential employeer/client about something entirely unrelated to all things Llama. I mentioned that I enjoy contracting because I can work 20 to 30 hours a week on client work and then 20-30 hours a week on my personal projects (Llama, Meadows Design, etc). We also talked about a local IT jugernaut — for lack of a better term — and his new foray into the MMO space. This was interpreted as “I bill my clients 40 hours a week while I only work 20 and all I want to do is write video games”. To anybody that knows me, this notion is absurd. Comments taken out of context? Unlikely as the conversation lasted 10 minutes at the most. My guess is people hear what they want to hear and judge people by their own actions or intent. I’ll vent more on my own blog, but in the end I don’t really want to work with people that are such bad judges of character so it all worked out for the better.

WinForms not ready for prime-time
For my work with Meadows Design, I’m working on a new event viewer for Windows. While I know I should be writing this to be OS native, I wanted to get a little more familiar with the WinForms functionality available in .NET 1.1. Being a big .NET advocate after spending years in the Java world, I’ve come to the conclusion that WinForms just aren’t ready for prime-time.

Don’t get me wrong, it’s a huge improvement over AWT/Swing and it’s going in the right direction but it’s just not there. For instance, I want to owner-draw my tabs. Well, if I set the tab page to owner draw I can paint pretty rectangles, etc within the tabs but the tabs themselves stay the same “blech” brown. To completely make them owner-draw, I have to use P/invoke code. Want to change the background color of your menu? Well, again, the built-in owner draw functionality falls short. I can make the “File” text a lovely shade of yellow, but it’s chased to the end of the window with that same “blech” brown. For me to change the menu bar color, I have to use P/Invoke code again and call the Win32 API function DrawMenuBar. Of course, there are the subsequent GDI brush calls, etc.

Why not 2.0 you may ask? I’ve already narrowed the market by writing this in 1.1. The 2.0 install base in nowhere near as pervasive as I would need it to be to make this application nothing more than an exercise of how to write software that nobody would use.

Cocoa Calendar Control
Ok, this has been bugging me for a while. I have an idea for an OS X piece of shareware but the Calendar control just annoys me because I can’t resize it in the designer (visual tools make you lazy, you know that, right?). Anyway, I think I have a way around it and if it works I’ll post it up here.

Random Thoughts

  • Check out the Prototype JS library. It’s pretty slick.
  • Rico’s pretty nice too, though it has some Safari problems.
  • Llama work is progressing nicely. Gonna keep that quiet though.
  • WTL will probably be the framework of choice for the next version of my event viewer. A good tutorial can be found here.

andy .Net Development, Rant, Software