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