Saturday, 22 November 2008

Windows Vista + Loosing the Ability to Hibernate

I'm one of the few people I know that use the Hibernate feature on my laptop. I find its helpful when shutting down for the evening but want to resume exactly where I left off the next day. Sleep even S3 doesn't work for me as I often find my battery depletes as on this laptop it is shockingly poor.


The other day I was performing some basic maintainence and decided to run disk cleanup to see if it was any better than XP's counterpart, it ran well and asked me would I like to remove my hibernate file. This is where my troubles began, I expected the file to be recreated upon my next hibernate, however what did happen was hibernate ceased to exist on my start menu.


After much hunting through the Control Panel I was unable to find a definitive option to renable the hibernate file, power options was all setup to hibernate however I was still unable to hibernate. I then found a simple command line setting you need to run to renable it, or even turn it off if that is your desire.


First open a command prompt window in administrative mode, its annoying when you forget to do this, then simply run the following: powercfg -H ON. The -H switch indicates hibernate and then its a simple on off. And that's it Hibernate restored and my laptop is back to it's normal self, good stuff.

Tuesday, 18 November 2008

Site Maintainance and IP Restriction

There are times during many site's life that you must perform some maintainence on the database / code, and allowing people to have access to the site whilst doing this must be restricted. Often most updates / upgrades can occur on the fly without any down time but there are occasions when you need to do this.


Usually I logon to my web server and IP Restrict the site to my IP Address and let IIS provide a default message to users that try to access the site during this period. Now although this works I often find it cumbersom, I have to have access to the web server, I need to find out my IP address, as I don't have a static one at home, and the entire process can be quite long. It's even worse if its for a site that I don't host and can't IP Restrict through IIS.

Another Way

Tonight I decided to explore a better way of doing this, and as such I've came up with a simple HTTPModule that you can stick into your ASP.Net Web Application which will handle IP Restrictions for you.


In order to maximise the use / potential of this module I've enabled it to do two things, first to allow conigurable IP Restrictions but secondly to specify whether the restriction is for a temporary basis, I.E the sites under maintainence, or whether this is a perminant block.

The Code

The code for this module is actually pretty simple. First of I created a class called IPRestrict and implemented the basic IHttpModule interface


namespace mjjames.HttpModules
{
 public class IPRestrict : IHttpModule
 {


  public void Init(HttpApplication context)
  {
                }

  public void Dispose()
  {
  }
 }
}

With the basic interface I added a event handler to the init method that on BeginRequest, when a request starts to be processed, call Application_BeginRequest. Application_BeginRequest takes the user's IP Address from the Request object and passes this to ValidIP. ValidIP by default returns that the IP is valid, the site isn't using IP Restriction, however if the site's web.config has an app setting called "IPRestrict" then the provided ip address is searched for in the app setting.


private bool ValidIP(string ipaddress)
  {
   bool bValidIP = true; 
   if(!String.IsNullOrEmpty(ConfigurationManager.AppSettings["IPRestrict"])){
    bValidIP = ConfigurationManager.AppSettings["IPRestrict"].Contains(ipaddress);
   }

   return bValidIP;
  }

The reason i decided to perform a contains function on the app setting for the ip address was so that I could ignore the IP Address delimiter within the app setting. This way whether you seperate valid IPs with a comma, a space, a comma space etc it doesn't matter, as long as the IP is within the app setting it is returned as valid


As far as the IP Check goes that's it, however in order to make the module more usable and user friendly Application_Request can use an additional two app settings from the Web.Config. "MaintainenceMode" is boolean setting which indicates the IP Restriction is in use due to maintainence, if the setting is not provided then the module assumes this is not the case by default. Maintainence Mode changes the HTTP Response Status Code for the request, by default IP Restriction means the end user recieves a 403 status code, forbidden, however whilst in Maintainence Mode a 503 status code is delivered to indicate the service / site is temporarily unavailable.


The second app setting used in Application_Request is "CustomIPRestrictMessage". This setting as the name implies is used to provide a custom IP restriction message to the user instead of te default.


The module is really simple to use, simply add the mjjames.HttpModules dll to your project as a reference and update your web.config to include the app settings. Along with the app setting the HttpModule needs adding to the HTTPModules section of the web.config, find an example of how to do this below



That's it hopefully you'll find the module easy to use. Currently it doesn't do IP Ranges as I didnt require this, I may look at adding this in the future.


Now whilst testing this I thought about how I could provide more than a custom message upon recieving the IP Restriction response, maybe a branded page dependant on the site it's used in. This is actually very easy and all you need to do is create a custom html page branded appropiately within your site and then change the CustomErrors section of your web.config.


Within here simply add a new error node, give it either the 503 or 403 status code dependant on whether you are using maintainence mode or not, and provide the html file to redirect to.



This makes the module for me at least very useful. If you want to give the module a go why not download the dll and let me know how you get on. If there's interest I'll also look at bundling a version with the full source.

Monday, 22 September 2008

Rename a Computer Using WMI Scripting

This Wednesday I'm doing an MVC Hack Night at my work with Derek Fowler. This evening will hopefully give us a chance to show other employees what ASP.NET MVC is and to give them some simple tutorials to work on.


As ASP.NET MVC is only preview 5 we didn't want to install the extensions onto the work machines, so we decided to create a time based XP Virtual Machine that everyone could copy and use for the evening. Not only did this mean we could install the extensions without fear of breaking our development machines but it also meant we could ensure that Sql Express and Visual Studio Express was setup and working with the tutorial code properly.


There was one giltch with the plan and that was that the Virtual Machines would all be using the same Computer Name, this would result in the computers not logging onto the network and all sort of errors could occur.


My solution to this was to write a dead simple WMI Script in VB that would run at logon, this script would check to see if the Computer Name was the default, in this case MVC, and if it was to rename it to MVC-{Random Number}. It would then reboot the computer and then find the name changed and hopefully find it can logon to the network fine.


The source code is below, I've chosen to generate a number between 1 & 1000. This should hopefully not generate any machines with the same name, as there's only 10 of us.
The script really is quite simple, I first get the Computer WMI object and check it's name to see if it equals MVC, if it isn't I change it, echo out its been changed and then use the WMI Script object to run Shutdown.exe /r (reboot the computer). Now I could use the Operating System WMI Object to issue a shutdown but I didnt think of this until after I had wrote the script.



lowerbound = 0 ' lowest value
upperbound = 1000 ' highest value
Randomize
randomvalue = CInt(Int((upperbound - lowerbound + 1) * Rnd() + lowerbound)) 'generate random number

Name = "MVC-" & randomvalue ' our new computer name
Password = "abc123" 'my admin password
Username = "admin" 'my admin username

Set objWMIService = GetObject("Winmgmts:root\cimv2")

' Call always gets only one Win32_ComputerSystem object.
For Each objComputer in _
    objWMIService.InstancesOf("Win32_ComputerSystem")
 If objComputer.Name = "MVC" Then ' check to see if comp is using default name  
         Return = objComputer.rename(Name,Password,Username) ' rename comp
         If Return <> 0 Then 'check for error
             WScript.Echo "Rename failed. Error = " & Err.Number
        Else
             WScript.Echo "Rename succeeded." & _
                 " Rebooting for new name to go into effect"
   set objWSHShell = WScript.CreateObject("WScript.Shell")
   objWSHShell.Run "shutdown.exe /r" ' reboot comp for changes to take effect

         End If
 Else
  WScript.Echo "Rename Not Needed"
 End If

Next

If you want to use this script / adapt it for your needs feel free, it certainly made my life easier!

Tuesday, 16 September 2008

Welcome to Google Developer Day 2008

OK, I'm here, I have my shiny Google pass and a coffee I'm ready ;)


It all looks preety good so far, we strangly have a small wrapped up box which is for a session later.. I want to open it now but much like Christmas I'm thinking it may spoil it, apart from that upon arrival we are being showered in free coffee and pastries, if only I could eat the pastries I wouldn't be hungry, very good none the least.


Wembley Stadium is gorgeuos, it may have been over time and budget but it is beautiful, a nice venue to hold such an event in. I'll try to put some pictures online of the stadium later.


I have taken a few quick shots so far and will upload them to Flickr shortly, sadly I forgot my SLR and then Chris Alcock's small camera so alas it's LG "Viewty" quality only, I'll post later with more thoughts and ramblings about the day, given last night's performance though I'm thinking I need to scout out power sources soon!

Update
Google's WiFi has fallen over already and there's only 50 people here, I've switched to my 3G connection, it may be more reliable, although it will suck my battery quicker! Doh!

Pictures so Far

Sunday, 14 September 2008

Google Developer Day 2008 London

Tuesday is the UK's Google Developer Day, this year its taking place at Wembley Stadium and I'm lucky enough to be attending


I have to say I'm quite looking forward to it, a chance to get see Google Speakers and to catch up with other developers that utilise the Google API's will be awesome.


So far I have used the Google Calendar API and started to write a .Net wrapper for the YouTube API, so learning about others will be good. The sessions I have pencilled in to attend so far are: State of AJAX: Dion Almaer, YouTube API: Build YOUR YouTube: Jean Laurent Wotton, Mashing up Google Data APIs: Ryan Boyd and probably but not fully sure V8 - the Chrome engine Kevin Millikin.

As you can see it's going to be a jam packed day, but the sessions look top and I look forward to sharing and learning.


Due to travelling I'm heading down Monday night, and coming back on Tuesday Evening. If you are in London on Monday night, and fancy catching a pre dev day pint or even food, drop me a DM on twitter (mjjames)


After the day I plan on doing a summary writeup on here and hopefully sharing some cool info

Tuesday, 2 September 2008

Going Chrome

So today Google Launched Google Chrome, and like any good geek I got on it straight away.


Installation was quick and painless, and it fired up blistering quick. It was then the magic started. Now I won't focus on how nice the interface is to use, the new home page, etc I want to concentrate on the features I have used tonight whilst using it and whilst coding.


HTML & CSS Features

The first thing I did whilst playing was to view some page source, this as you would expect is on the context menu, nothing overly special here, however I did like the nice syntax highlighting, +1 to Google. However it doens't do any sort of nice reformat document, this would have been a really nice feature but we can't have it all.

Whilst looking for View Source I discovered that Chrome has a DOM Inspector built in, I got to it by "inspecting an element". This is far more than the DOM Inspector that you can get for FireFox, it gives you a nice DOM view, style information (computed, inherited, etc), Metrics, which shows the Box Model being applied to the element, and finally a properties tab giving you anything being applied to an element.


Next there's a funky search box, this allows you to search the DOM for anything, how many times have you needed to find the image with a class and you aren't sure where it renders? Now you could use inspect element, but if you are already in the inspector simply type "img" into the search box to find it lists all of the image tags within the document, now if it was really ace you could type image + class="photo" but this is not the case yet...


Resources and Debugging

All of that was only under the Elements section, there's another section... Resources This is similar to the net view tab in FireBug, it shows all of the "resources" requested by the page and shows them on a nice graph, showing how long they took to load and where in the process or you can compare the file sizes.
By clicking on the file the graph turns into a preview of the file, be it the image, JavaScript file etc.


I was slightly disapointed when I opened a JavaScript file to preview, I was expecting to be able to set breakpoints and watch's but alas no :( However there is a JavaScript Console, this is located at the bottom of the screen, the 2nd button from the left, this pops up the console.


Now this is really good, it has intelisense ;) So if you start typing document.getElementByID for example all you need to do is: do [tab].get[tab] and choose by ID. If you cant remember the name, for example getElementsByName you can just keep pressing [tab]

Now at the moment it only seems to do DOM but I'm hoping it may eventually pick up references and then you can do funky jQuery or something within the console...


Now there is soo much more I could talk about, however the final feature I used tonight was the JavaScript debugger, this is under Developer > Debug Javascript or you can use the keyboard shortcut.

Now I expected more than this, but maybe It does do more than I currently know, if you type help within the console you can see what you can do. You can attach breakpoints using the console, print variables, see what scripts are loaded, etc.


When attached to a tab the debugger will catch any errors and you can print out any variables that you need to inspect before typing continue to continue.

For me I still prefer firebug for JS debugging but I'm sure this will evolve further over time.


So that's it for tonight, I am loving Chrome, it's fast, it's slick but... there are still some bugs and glitches to iron out. For example I have seen quite a few pages where font-size is being inherited wrong within li's, so if I had 90% font size by the 5th li the text was unreadable :( There have been some other weird text issues but nothing that major.
I'm not going to make Chrome my default browser yet... but I'm not far off ;)

Friday, 25 July 2008

LinqDataSource and Could not find a row that matches the given keys in the original values stored in ViewState.

Today I was working on something quickly where I used a LinqDataSource, to keep things simple I attached a simple list view to it and had insert, update and delete operations.


Insert operations seemed to work OK however when I came to do an update to an existing item it crashed out

   Could not find a row that matches the given keys in the original values stored in ViewState.

Initially I thought that maybe some databinding had gone astray but this wasn't the issue. As I hadn't used design view but source view to create the ListView had missed off the DataKeyNames attribute, this meant that upon update the LinqDataSource was trying to match all my values against the database, of course it couldnt do this. By specifying the DataKeyName to match against, usually your Primary Key if using LinqtoSql, not only do you limit how much matching and work your LinqDataSource has to do, but also you'll find you can update :D


So quick tip, if you get "Could not find a row that matches the given keys in the original values stored in ViewState." double check your ListView, FormView, GridView etc has the DataKeyNames set.

Monday, 21 July 2008

System.Web.Query.Dynamic.ParseException: Digit expected

Today I wrote a quick piece of code using Linq to Sql that would pull out some records from a table given a provided where clause
To make my life easy, I used a LinqDataSource within a web form and then databound a form view to it, this was only a quick prototype of an idea so I felt these were appropriate.


The where clause for my LinqDataSource was being assigned programatically and consisted of a GUID value from a user object I had knocked together. Upon compiling and running the code though I got an odd error: System.Web.Query.Dynamic.ParseException: Digit expected


First thing to check was that the value I was giving the where clause was actually an GUID value, debugging showed this fine, I next looked at putting a hard coded GUID where clause in to see if it was some weirdness caused by my user object, but this wasn't the case. I finally googled the error message, and found 1 meesly result which pointed to the MSDN forums.


Here someone posted that you can convert to various types and to try explicitly converting to a GUID value


   lds.Where = string.Format("user_id == Guid({0})", user_id);

This worked fine, and it made sense too, as when you declare where parameters on the linqdatasource control you normally define its type, as I wasn't doing this nor programtically it was type casting by itself.

Monday, 14 July 2008

Build failed due to validation errors in. dbml

OK so I got in today to find that I was unable to build my current project, I got the following

Error 1 Build failed due to validation errors in C:\xxx\DB.dbml. Open the file and resolve the issues in the Error List, then try rebuilding the project. C:\xxx\DB.dbml 2

I opened the projects dbml files to find that these files were fine, no errors or typos, the project was just dead. a little bit of Googling lead me to find that its a problem with Visual Studio 2008 not loading an assembly correctly, in particular the one with a GUID of 8D8529D3-625D-4496-8354-3DAD630ECC1B

In order to load the assembly correctly you need to get Visual Studio to reset it's packages, to do this:

  1. Open a new command prompt
  2. Navigate to C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE
  3. Run Visual Sudio with the /resetskippkgs argument: devenv /resetskippkgs

You should now find that your project opens and builds correctly! I'm hoping that maybe SP1 of Visual Studio will correct this, if not SP2 maybe...

Update: SP1 Didn't fix this :( Also worth noting if you are running a 64 bit OS then the visual studio folder path is C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE

Thursday, 26 June 2008

Loosing the Address Bar

Microsoft Windows has had the "address bar" for a long time. Although not used by many adding it to your taskbar for some has provided an amazing way of quickly getting to files, folders and web addresses.


I have used it for a while and have it in the bottom row of my task bar, I have this setup at home on my machine, work and until recently Hayleys Laptop.


SP3 came out recently and I immediately updated Hayleys laptop to it, all seemed fine, however today I logged into as me, and noticed the address bar had "vanished". First of all I thought I has just knocked it off but no it had physically disapeared from the toolbar list.


A quick Google later left me speachless....


"After installing Windows XP Service Pack 3, the Address Bar feature will be removed from the Taskbar. The Address Bar feature will not be present in Windows XP Service Pack 3. This change is in response to a regulatory request and is present beginning with Windows XP Service Pack 3 Beta."

It has been removed! The reason behind this is that the Addres Bar is actually part of IE, and Microsoft are trying to make IE less dominant within Windows due to antitrust. I personally think this is a joke, if the address bar opens links up in your preffered browser, in my case Firefox, does it matter that it's an IE component that fires up FireFox??


After further browsing I have found an Addon some one has wrote MuvEnum Address Bar to help with the issue but as of yet I havn't tried it due to now wanting to put something else on Hayleys Laptop.


To remove such an established feature is a real low blow, and I'm sure there must be a better solution, even if it involved more work.... So I was left without my address bar on Hayleys Laptop and hoping that work doesn't upgrade to SP3 anytime soon. Interestingly SP1 Vista still has the address bar so I wonder if SP2 will remove it.

Tuesday, 24 June 2008

Using Yahoo! Media Player on a dynamic page

Recently I added paging to my churches podcast page, the steps on how I did this are part of another post that I aim to finish at some point, however I thought I'd quickly blog tonight some tips on using the Yahoo! Media Player on a dynamic page.


Originally the podcast paging was causing a full postback which reloaded everything on the page, this felt dirty so tonight I reconfigured my podcast control to make use of the ASP.Net Ajax UpdatePanel. The paging worked great however the WMP wasn't updating which left the playlist out of date and the new podcasts without play buttons.


The issue was that by default the YMP JS fires on load and the ajax update wouldn't trigger this. Moving the script to load as part of the ajax updated content also wouldn't help this, all I would be doing would be reloading the source, not actually solving the problem.


I turned to the YMP wiki however I didn't really turn anything up that was of great use.


I knew that the YMP scraped the page on load for MP3 files and then built up its playlist, so it was a case of finding this scrape function, clearing the current playlist and then triggering the scrape.


Firebug came to my rescue, I add a watch to the YMP object YAHOO.music.WebPlayer and found that it had quite a few functions available if you know they are there, I have listed a few useful ones below:

  • asyncLoadPlayer() - if the player is loaded after the window has loaded this will manually load the whole player
  • clear() - clears the playlist
  • pause() - pauses the item playing in the media player
  • play() - plays the current item in the playlist
  • scrape() - scrapes the page for mp3's and adds them to the playlist
  • shutdown() - shutsdown the media player and releases all resources
  • startup() - starts the player up, not sure if this is useful as asyncLoadPlayer()is probably better
  • stop() - stops the item playing in the media player


So for my case with a dynamically loading page I added some simple JavaScript to the content that is loaded in, this JavaScript first ensures YMP has already been loaded and then clears the playlist and scrapes the page for new media items for adding to the playlist.


function PageLoadedEventHandler() {
  if(YAHOO.music.WebPlayer.loaded){      
    YAHOO.music.WebPlayer.clear();      
    YAHOO.music.WebPlayer.scrape();
  }
}

I did ponder about leaving out the clear, that way as you page through the podcasts the playlist simply grows so you can listen to any of them, I decided against this but I hope you can see what you can do.


So there wasn't much to it, I am hoping Yahoo! will properly document the functions available within the YMP as I would have saved alot of time faffing with FireBug and the watch window. I hope this helps someone, I'm now thinking on how I could use my own player interface and utilise YMP to power it... any way thats something for a rainy day

Friday, 30 May 2008

Linq + Failed to set one or more properties on type

So I have had quite an interesting hour or so tracking down the following Linq error:


Failed to set one or more properties on type [namespace].EntityContexts.project. Ensure that the input values are valid and can be converted to the corresponding property types.


This was occurring whilst performing an update in a formview. Previously the form had been behaving properly, but this morning I added a new field to the database and updated the LinqtoSQL file. I also added a new databound field to my formview, however since this every time i tried to update the form it crashed out.


A few people have suggested to delete your LinqtoSQL file and readd, this didn't work for me, I even created a new page with just the datasource and formview for testing purposes.


The datasource was configured to select all from a table and had auto insert, update delete set. The formview was just generated.


It was at this point that I noticed the foreign key relationships I had setup were child entities in my entitycontext. This meant that my formview was generating databound controls for my lookup table etc. In my original page these didn't exist as I had manually removed them in sourceview.
So I again removed these controls within my new page and tried again, still no joy, I then wondered if removing them in Design view instead of Source had any impact, and it did. What was happening was my designer code file was not being updated upon rebuilding from the pages source view.


I then thought further on how to avoid this, my initial thoughts were upon inserting a LinqDataSource only select the columns you need, thus skipping the child entities, this would work for read only select data sources however to use auto generate insert and update you can't use select. If you try to do this then you get the following error:


LinqDataSource 'LinqDataSource1' does not support the Select property when the Delete, Insert or Update operations are enabled


There is a way around this though, although its not pretty and i think its a massive bodge but, insert your datasource and manually select the columns you need, create your formview. Then update the datasource, you are now able to turn on auto gen insert, update and delete. However the manual select still exists on your datasource so switch to source view and remove that.


You should then finds it all works...... Total bodge, I'd sooner just ensure i switch to Design mode to remove my extra fields, but hey everyone has there own way...

Tuesday, 27 May 2008

JavaScript Library and File Loader

OK so tonight I was going to blog about adding paging to a repeater using Linq, however Google today announced that they are now hosting JS Libraries and I couldnt resist whipping together a webcontrol for use in my projects. So I have postponed that post until tomorrow or later on in the week.

JSLoader 2.0

A few months ago I released a fairly basic webcontrol that you could use to import JavaScript files into your .Net pages, it had fairly configurable options and ensured that the file was only loaded once. This worked great, but at the time I thought wouldn't it be great to load JS Libraries from a shared location. At the time the libraries were all over the place and I couldn't decide on the best way to load the files so shelved the project. Today Google announced they are now hosting AJAX libraries, I immediately thought back to upgrading the JSLoader and tonight after a few bits and pieces I fired up Visual Studio 2008 and hacked together JSLoader 2.0

Using JSLoader 2.0

The basic principles remain the same as JSLoader. You reference the control and then create a new webcontrol when you want to load some JavaScript. The difference now is you can use the old way of specifying a directory, file, version type etc, see my JSLoader post on using the old technique, but you can now load up Libraries from Google. Google currently hosts dojo, prototype, jQuery, script.aculo.us and MooTools and as such these are the only libraries that JSLoader 2.0 supports. In time I'll add YUI but for now these will do. JSloader now includes an extra attribute on the control, JSLibrary, here you can specify the AJAX library to load.
<mjjames:jsLoader ID="jsLoader2" runat="server" JSLibrary="dojo"  />
This would then add the following code to your page:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("dojo" , "1");
</script>
You can also tell the loader to get Google to render the uncompressed version of the library, this is done by setting the type attribute to uncompressed
<mjjames:jsLoader ID="jsLoader1" runat="server" JSLibrary="mootools" Type="uncompressed" />
Thus:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("mootools" , "1" , {uncompressed:true});
</script>
Note: only jQuery, MooTools and Dojo have uncompressed versions, if you specify uncompressed for the other libraries the compressed versions are still served up. Finally you specify a version number, by default JSLoader 2.0 tries to load the latest 1.x release of each library however if you want the 1.2.3 release of jQuery simply set the Version Attribute to 1.2.3
<mjjames:jsLoader ID="jsLoader3" runat="server" JSLibrary="jquery" Version="1.2.3" />
Giving you:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("jquery" , "1.2.3");
</script>
It really is simple, it ensures only one version of each library is loaded and its quick and simple to use. Get the latest JSLoader 2.0, add a reference to it in your code, add the control to your site's web.config or register it on the page, and you are away.
<add tagPrefix="mjjames" namespace="mjjames.WebControls" assembly="jsLoader"/>
Hope you like it, any questions or issues let me know.

Side Note

Script.aculo.us depends on Prototype, however JSLoader 2.0 doesn't currently enforce this dependancy, would you like to see JSLoader 2.0 enforce this dependancy and load Prototype before Script.aculo.us or should it load it anyway and let the developer ensure Prototype is loaded? Would be good to see arguements for and against, then I can make a final decision some point this week.

Wednesday, 30 April 2008

Invalid postback or callback argument.

Ok so I have been playing with .Net Membership and Roles recently and have added a new login to a website's backend. Now I added a simple sign out button that invokes the forms authentication signout method and added it to the backend. This worked as expected for all the pages except one.


On one of my pages I am currently using an iFrame to pull in some content, until I integrate it properly. If you tried to signout from this page the following error occurs:

Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

This I thought was odd, and as it only occured on this page I guessed it was something specific to this page. My first thought was to temporarily disable EventValidation, this however didn't fix the problem.


I next turned to the source code, initially everything looked OK. However what I failed to notice was I had entered my iFrame as below:


<iframe src="/somewhere" id="something" width="800px" height="1000px"  frameborder="0" />

I had wrongly made the iframe self closing. Changing this to the valid way:


<iframe src="/somewhere" id="something" width="800px" height="1000px"  frameborder="0">
</iframe>

fixed my event validation error and all was great.


I would love to know the reason behind this, I'm thinking its down to what the server expects the iframe to be and what the source says but I'm not sure. More interestingly hoever is that Visual Studio doesn't flag the invalid iframe as an error or a warning, unlike most other invalid HTML.

Saturday, 19 April 2008

For When You Move Your Site

How many of us often end up rebuilding our site's either from one techonology to another, php to ASP.Net or ASP to ASP.Net, my guess is quite a few as I have done this a few times within the last year.


When rebuilding sites you often find that unless you map the old file extension or urls to the new ones your Google rating / ranking is hit as Google, and other search bots will encounter 404 errors instead of the pages they were expecting.

Now the best way when changing your site or even moving pages is to give the user and searchbots a pointer to where the new files are. A signpost if you will, this means they can find the new content and they will now know the new route to the content.


The HTTP specification defines two methods for these type of redirects. A 302 resposne is a temporary redirect, the content has moved for now but will be back in its original home at some point so don't update your references. The 301 status code however is a Moved Permanently redirect. If you serve this up as part of your response header and the new location then a user will be redirected to the new content. If Searchbots receieve this then they update all your stored links in their database to the new address.


What this results in is that your search listings all now point to the new address and you won't experience a drop in you page rank or have people going to 404 pages from a search listing.


Now this is great, however the issue often is how can I make these 301 redirects, do i have to manually add in pages to my new site that redirect to the new pages? In the past I have done this, where all i needed to do was redirect 1 or 2 pages, however last night I needed to cater for a site that had over 12 pages. Manually doing this was not an option.

urlRedirects

So last night I hacked together a simple HTTPHandler. urlRedirects. This HTTPHandler recieves requests and looks at XML file to see if it has a redirect for it. If it does it returns a 301 Header, if it doesn't it returns a 404 header. If the site has a custom 404 file it also returns this, otherwise a generic 404 message is returned.


The HTTP Handler is quite simple, to handle interacting with the XML file and filtering easily I used LINQ. I love LINQ at the moment and will hopefully post on how I've been using it, and learning to use it at another date. The rest of the code then just deals with serving the correct response header and content.

Using urlRedirects

Configuring Your .Net Web Application

If you want to use this project first get the DLL and reference it into your project. Next create yourself an XML file for your redirects, I called mine xmlredirects.xml


Next you need to define your redirects in the following XML Structure:


<?xml version="1.0" encoding="utf-8" ?>
<redirects> 
<redirect originalurl="/loadpage.php?id=7" redirecturl="/page.aspx?key=7" />
</redirects>

So your root node is <redirects> and this contains children node's redirect. Each redirect node has two attributes, originalurl and redirecturl. It is worth noting that the redirects uses the path and querystring so you can have page.php?key=something.


Once you have created your new file in your applications web.config you need to add a new application setting. XmlRedirectsLocation


<add key="XmlRedirectsLocation" value="~/xmlredirects.xml" />

Now you have the DLL references and the XML file created and available we now need to tell the .Net engine to pass any files of our choosing to our new handler. In my example I want to redirect PHP files so to do this I create a new HTTPHandler in my web.config


<add verb="*" path="*.php" type="mjjames.httphandlers.UrlRedirects, UrlRedirects" />

Now this tells the .Net engine what to do with PHP files but your webserver by default will not be passing PHP files to the .Net engine. The next step is to configure IIS to pass your file type to the .Net engine. Again I'll use PHP for my examples.

Configuring IIS

I assume most people will be using IIS6 however configuring it IIS7 is also as easy which I'll comment on in a moment.

IIS6

First of all bring up the properties menu for your site and navigate to the home directory tab. Once here click the configuration button which is in the application settigns area. This will bring up a new window.


The first tab mappings is the one we want to deal with. We want to map PHP files to the ASP.Net engine, so click add. In the new dialogue box we need to enter the ASP.Net isapi dll as our executable, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll in my case. Then the file extension to send to it, in my example .PHP You can finally configure which VERBS it responds too, I went with the usual .Net ones GET,HEAD,POST,DEBUG. Click OK and then it's time to test your site.


Hopefully you'll find you new directs will kick in and you should see your new content.

IIS7

I found configuring the redirects for IIS7 easier, choose your site and then click on handler mappings.


This then brings up a list of the configured mappings, choose "add managed handler".

On the new window that pops up enter the request path, .php in my example. Then you can choose the handler from the drop down box: mjjames.httphandlers.UrlRedirects. Notice that for IIS7 you don't pass the request to the .Net isapi filter, you pass it straight to the handler. IIS7 is very cool ;) You can then name the new handler mapping for ease and if you want you can configure your request restricitons but this is optional.

That's it, I hope you find the URLRedirects useful, let me know any feedback / feature requests and I'll see if I can accommodate them.

Download urlRedirects

Wednesday, 19 March 2008

Post HH{H} Launch Thoughts

OK so todays been a busy day.


Got up at 5am for a 6.30am Train to Birmingham for the Microsoft UK Heroes Happen {Here} Launch. The train journey was pretty uneventful and I even had mobile internet for a fair chunk of it.


Upon arriving at the venue it was apparent that this was an MS event. Big banners with the Hh{h} marketing everywhere.


Registration went very smoothly and considering we didn't arrive till 8.50 we were able to make it to the keynote / marketing bonanza ;) Whilst sat in the keynote I had a rummage in my initial swag bundle and to my dismay there was no notepad! Eek! Here was I with a new Microsoft Pen but no paper and to add insult to injury my laptop was low on juice to my initial train journey. Not Good.


One thing I also noted early on was that there were alot of attendees, and I mean alot. So much that at the start of the first session my fears were realised, there were more people than seats in the sessions, I only got to attend the first session by one seat.


This then lead to quite a few tweets on twitter about the situation, and the lack of power for laptop users, whats the point of wifi, which although slow did work, if you have no power... Of course unless you're Chris Alcock with a super battery addon ;)


I have to say the quality of the presentations were very good and were very much aimed at being launch demo's. This isn't a bad thing, very quickly I was able to find out what VS2008 would mean to me and things I could do with it.


In particular I thought the Linq talk by Mike Taulty was very good. He knew his stuff and delivered the content very well. I think I said the phrase "no way" and "really", and perhaps at one point "shut up, no" as you do. I think I am now in love with Linq and can't wait to play with it... say tomorrow night :D


Anyhow the day progressed and I even found a plug socket upstairs to get a quick 30min charge. I then got even more MS Swag, MSDN mags and such and then finally what I had been waiting for.... The Software.


The Hh{h} software pack is in my opinion very professional, it fits well and comprises of an evaluation version of Windows Server 2008 Enterprise, SQL Server 2008 ctp 5.0 and Visual Studio 2008 Standard.


I was happy enough to get a full version of VS for at home finally which is great, the other software I know I will VM for testing and developing at home, in particular I really do like IIS7 and have been using it in Vista for over 7 months, to be able to host development sites locally on a server edition of windows I know will vastly increase my deployment knowledge.


What the software suite also included which I actually missed originally is an "Application Voucher" which allows you to get an evaluation copy of SQL Server 2008 when it's released. This is good and for me anyway lets me think I haven't missed out too much with SQL 2008 being delayed.


My day rounded up with attendance at a session on IIS7, which covered alot of what I had read / seen previously but also covered some of its other new features and how / to use them. In particular I hadn't realised that as of IIS7 IIS will not be constrained to only being updated with a new Server OS release, IIS8 for example will probably come out on Windows Server 2008. Also new modules for IIS7 will be released on their website in particular the new media throttling one was demo'd and looked very good.


The day drew to a close and the closing session touched on the future of programming in parallel. This is a very important and was very aimed at developers, I enjoyed it none the less.


It was then meant to be the community reception and I did attend for a while. However alot of people seemed to just leave and there was no real air / buzz about the place. There didn't seem to be a lot of mingling or good conversations going on. This was disappointing and I did expect more, there was an abundance of drink but no food, maybe this didn't help.


Anyway overall I did enjoy the day, alot of travelling and very little sleep is beginning to take its toll on me but it was worth it none the less. The question now is do I play with Linq tonight.....

Tuesday, 18 March 2008

Heroes Happen {here}

Ok so tomorrow is the Official UK Launch of the new MS Development Suite, Visual Studio 2008, SQL Server 2008 and Windows Server 2008. I will be in attendance and hope to get a good look at the new suite and what can be done with it. I'm travelling down to Birmingham and sadly will be on a 6.35 am train :( At least I'll be with Chris and Derek On the train we aim to do a mini "hackathon" and I'm hoping to get my latest project up to a 0.2 "alpha" release. That of course rely on getting my mobile sharing the internet with my laptop, I just worked out how to do it on my viewty but sadly need it's USB cable :( Anyhow time for an early night, I'll no doubt be on twitter and may even blog at lunch :D

Saturday, 1 March 2008

"Making the Right 2.0 Choice" - My Talk @ BarCamp ManchesterUK

Find below my slides from my BarCamp Talk, more details on BarCamp later.

Tuesday, 26 February 2008

What I aim to talk about at BarCamp Manchester UK

So on Saturday it's the first BarCamp in Manchester, UK. I have to say I'm quite excited about attending and from the beggining have been pondering on what to talk about. Within the last week I have formalised this and got the majority of my two code demo's done and started the slides tonight. I'm aiming, if chosen, to talk about the process and stages I went through to make a simple ASP.Net application "web 2.0", in other words swishy and more "AJAX". I will highlight two methods, of endless methods I may add, the pros and con's of both, the decisions I made and why. I'm hoping this will help people who are trying to enhance existing code, be it personal or at a business level, to see what methods are available and at least somethings to consider before making a decision. Regardless of whether I do the talk at BarCamp I will aim to post slides and my examples on here by the end of the weekend.

Tuesday, 19 February 2008

So What is it Code Behind or Code File??

Recently I have been working on a web project in VS2005. All has been going well, several class files, several pages, and a few web controls all make for a project of fun.


I came back to work on the project, and I happily added a few more web controls, compiled the site etc and got some work done.


Now here's where things began to go wrong, after some lunch I reopened my project, but this time I opened the projects solution properly. Did some work, then went to build the solution and..... It broke. :( Now a project not compiling occurs frequently, ie rubbish code, but this time it started winging on how all my controls in the custom web controls that I built before lunch were now out of scope.


Frustrating. I started poking around and tried to find the issue, and I couldn't find anything. It was at this point that I looked at my .ascx file and not the .ascx.cs


With ASP.Net you can have code seperation. Content in one file, .ascx if a control and logic in another.ascx.cs. This is called code behind, and in the content .ascx file you normally have a reference that links the logic file, .ascx.cs to the content control.


This is where my issue was. ASP.Net 1.1 used the syntax CodeBehind, and the code in the file was classed as a seperate class. .Net 2.0 however introduced partial classes and as a result Microsoft added the CodeFile syntax. This syntax CodeFile doesn't include the full code-behind class declaration, instead this is generated on page compilation. The page compilation step automatically generates members for each control and these are then fused with the CodeFile's partial class.


My issue was that my file was using the CodeBehind syntax. Although this is still supported in .Net 2.0, during the page compilation step of the build the generation of the members partial class is missed out. .Net 2 assumes that the codebehind file is a full class, not a partial class.


Now this is ok, as long as your code behind file contains a full class and not a partial class .Net 2 will compile the code using the old method. But somehow, and I'm still not sure how my Content file, had changed to using CodeBehind instead of CodeFile. Initially I missed this as CodeBehind isn't necessarily wrong, in the correct context.


Changing codebehind back to codefile corrected the issue and the partial classes were generated and fused properly.


After searching the net I also found that this can occur after upgrading a vs 2003 .net 1.1 project to vs 2005 .net 2.0 Web Application project and seems to cause a few people headaches.


So there you have it, if you find your code won't compile suddenly or after converting a 1.1 project to a 2.0 Web Application project, with your controls being out of scope, check whether you're using codebehind with partial classes and if so change to CodeFile.

Monday, 4 February 2008

More Web Controls - jQuery

Ok so I have an obsession with web controls and since my last one, Yahoo! Media Player, I have been toying with the idea of doing one for John Resig's jQuery. Tonight I got around to doing this and am now releasing version 1 of it. I made the web control as often when I write Web User Controls that contain / use jQuery to enhance the controls I'm not sure if jQuery exists in my web.master or web page itself. This often leads to me having to go back and change pages or include it in the web control only to find one page already uses it. And yes I'm rubbish at remember what JS is used where :S. So this web control not only checks to see if the jQuery control has been rendered before, if not render it but also allows you to simply specify the jQuery version, path to the file and which type to use, normal, minified or packed. Download jQueryWebControl.zip

How To Use It

So add a register assembly into the top of your aspx file
<%@ Register Assembly="jQueryWebControl" Namespace="jQueryWebControl" TagPrefix="jQuery" %>
Then which ever page, master page or even web control will need jQuery add the jQuery Web Control.
<jQuery:jQuery runat="server" ID="jQuery"/>
As the control checks to see if a jQuery control has rendered before you don't have to worry about only including the control once. This should ensure you don't have to waste time checking but also means your controls can be used independantly in different sites.

Using the three optional parameters, Version, Type and Path.

Version - this is just a string parameter that allows you to specify the version of jQuery to use. E.G "1.2.2" - if this is left out then the control defaults to 1.2.0 Type - again a string parameter, this time with three options, empty string "" = default / development version, "min" = minified version, "pack" - the packed version for people who cant serve up gzipped files. - if left the control defaults to the normal development version Path - a string parameter indicating the path to the javascript files. E.G "/javascript/jquery". - if left the control defaults to the /javascript/ It is worth noting that the control expects you to host the jQuery files, so in order to render the script tag for version 1.2.2 pack'd jQuery file you will need jquery.1.2.2.pack.js in the location you specify with the path parameter.

Example of use using parameters

<jQuery:jQuery runat="server" ID="jQuery" Version="1.2.2" Type="min" Path="/javascript/jQuery/"/>
I personally have made use of the version parameter the most as it has means different sites that have been developed against different jQuery releases can be updated / forced to use one version of the library. It also works best if all your jQuery files are in one centralised location, using a virtual directory or a shared location. So hope you like the control, let me know any thoughts, comments or improvements and enjoy. Download jQueryWebControl.zip

An Update to the YMP Web Control

Tonight I was going over my YMP Web Control that I released in December. However I noticed that I could end up having multiple controls render onto a page. This could happen by having a control in my master page and then including it in a web user control, or countless other situations. This then results in your page not validating and the JavaScript going astray. So tonight I altered the code, it now checks to see a YMP control has already rendered and if so it doesn't render. This version should replace the previous version and works in exactly the same way. Download the new version.

Tuesday, 15 January 2008

Yahoo! Media Player Web Control

Last week Yahoo! released there new Yahoo! Media Player and I had a little play with it, and I must admit found it to be quite cool. Basic but still very functional. Well I wanted to use this in a small project I'm working on and initially just added the JS to my page. However I thought wouldn't this be useful if I could just add an ASP.Net Web Control into any page I want this on, would save me x lines of code. So I created myself a quick Web Control, YMPWebControl. Its quite simple to use and by default all you have to do is put it into a page, and it renders the appropriate JavaScript. So here it is. YMP-1.1.zip

How To Use It

So add a register assembly into the top of your aspx file
<%@ Register Assembly="YMP" Namespace="YMP" TagPrefix="YMP" %>
Then where ever you want the YMP to render, I advise it be the last control in your page as it "adds to your page" and you want the page to load as quick as possible.
<YMP:YMPControl runat="server" ID="ympcontrol"/>
I have also added two optional parameters, DevelopmentVersion and EmbedInHead. These two boolean parameters allow you to turn on the Development version of the player, which supposedly is buggy has all the latest stuff, and allows you to embed the control into the header of your page from where ever it was added. Now this second parameter I would advise against using as you can just manually stick the control code into your header. The option was added in the case where you don't have the ability to change your master page or get access to the head section of code, i.e your using templates or something. This solves that. So an example of wanting the development version of the YMP but also loading it into the head
<YMP:YMPControl runat="server" ID="ympcontrol" EmbedInHead="true" DevelopmentVersion="true"/>
Download the YMP-1.1.zip And that's it, try it out if you like it and use it please let me know, below.

Update

The control has now been updated to version 1.1, this new version only allows one instance of the control to be rendered on a page. All previous links have been updated to this new version. Download the YMP-1.1.zip

Monday, 14 January 2008

Open ID for your Mobile

I very rarely just do a post highlighting other blog posts, I usually use my del.icio.us script but as I broke this by killing my unix PHP box I thought I'd post it the old fashioned way. This evening I glanced over at Ian McKellar's blog and he has been messing with OpenID for the mobile. I have just started playing with OpenID and been working on integrating into one of my projects and this looks a really good idea for mobile OpenID http://ianloic.com/2008/01/13/a-simpler-mobile-openid-workflow/ Take a look at that link and try out, comment and share the love for this project. I'll post more about OpenID and using it at a later date.

Sunday, 13 January 2008

Knowing what's on your page

So in work the other day I was asked to help a colleague with an interesting error he was experiencing. In IE he would find on usually the second page load of the site IE would bomb out with an exception: "Internet Explorer cannot open the Internet site", "Operation aborted".


Now I had seen this error before and usually it was down to people forgetting or even not knowing that they had to wait for the DOM to finish loading before trying to fire off JavaScript that manipulates or uses the DOM.


Of course most of us know we can solve this by using event listeners to attach functions to load on the window.load event or my personal favourite by using some sort of .onDOMReady method. Just like the one in jQuery or YUI.


Now in this case it looked like my colleague had set up his JavaScript properly, it was using the YUI onDomReady so this wasn't the issue, so where was the problem. We ended up turning to his JavaScript JSLint'n it to see if there was something I had missed but still the code eventually validated and we still had the IE error.


So we scratched our heads and then by chance I noticed that the page with the error had a flash movie embedded into it. Now I'm very much in the camp of not liking how many developers embed flash into a page and I always use UFO (Unobtrusive Flash Object. It was at this point my colleague mentioned that he was also using UFO after seeing me use it in a few projects, as it allowed him to put alt content in place for non Flash peeps. It was at this point I realised what had happened.


In case your not fully knowledgeable on UFO, "UFO is a DOM script that detects the Flash plug-in and embeds Flash objects (files with the .swf extension)." What you can then do is replace the contents of one Div Container, say one which contains alternative content for non flash users, with a Flash object. It does this using JavaScript and I find it to be the only way of allowing flash on any sites that I work on.


Now as this JavaScript manipulates the DOM, i.e remove the contents of our Flash Div and then put our Flash object into it, it must run once the DOM is ready otherwise we run the risk of trying to manipulate the DOM before it's even ready. This is what our page was trying to do.


Now I mentioned earlier that my colleague had wrapped his JavaScript functionality into a onDomReady, now what he didn't check and I initially missed was what else was in the page and what other JavaScript was loading. In this case his new functionality was causing the page to load a little slower which meant that the UFO code, which wasn't wrapped in a nice onDomReady, was firing before the DOM had finished loading. Such that the Flash DIV wasn't actually available at the point that the UFO code was trying to run.


So we simple moved the UFO method call into our onDomReady function and we were sorted. This example clearly shows that especially when writing JavaScript you need to be aware of what else is on your page and in particular what else is interacting with it. Before writing some JavaScript that does X Y and Z take alook at the page or even site and see what else is running / loading. Not only will this allow you to ensure your code doesn't break or break anything else but you will also find if there is some code you may want to reuse.


For example I often find myself writing JavaScript that uses the YUI library as this is what i have used most however recently I was writing some new functionality for a site and started to use YUI as its what I use most, got the functionality working on my example page, then went to put it into the site and found that it was already using JQuery. I then had to go back and quickly change my code so that it used JQuery instead of YUI as using more than one JavaScript library in my opinion is stupid and means that the end user has to download far more and it will end up with page load times being sacrificed.


So when writing JavaScript ensure you know whats going on in your page before writing your code, otherwise you may end up with a situation like my colleague did or you may end up re writing you code like I did. And you may find that your work load is actually reduced as you may be able to reuse code that's already in the page.