Friday, October 26, 2007

Using Asynchronous Javascript with validators

Before Asp.Net Ajax was released I used to work with a library called AjaxPro (formerly Ajax.Net). It also wrapped specially decorated methods and sent them to the Page as javascript functions with a callback javascript function as the last parameter. In this library, by not using a callback you were saying that you want to execute the function synchronously, that you want to wait for a result. After all, that's a functionality included in the XmlHttpRequest object.

I was amazed to see that Asp.Net Ajax does not offer such an option. You NEED a callback function. So... how do you use a WebMethod as a javascript validation function, since the validators only accept a synchronous function?

The first idea I had was the easy way, to cycle inside the function until I had a result. Bad idea: Javascript itself is not really multitask, so it just took the CPU to 100% and that was the end of it: kill task. The second idea was the hard way: redo all code in the XmlHttpRequest wrapper and use the included synchronous functionality. Too complicated, although I found an article about how to do that. So here is the way I did it:
1. Get the validator object
2. Set a property on it to tell if the validator is inside an async call or not
3. Set a property to hold the last value that was validated
4. Set a property to hold the last result returned
5. Set a method of the validator as the call back function
6. If is in async return false
7. If the last value is the same with the current validating value, return last result
8. Execute the async validation function with the validator callback method as a parameter and return false (or "in async")

Now, the callback method just sets the result and clears the async flag and also updates the visual of the validator. By doing this I essentially don't allow postbacks during validation calls, which makes sense. I also had an idea of creating a special "in async" validator that would not allow postback and would display something nice, but the solution I am explaining keeps it local, with ValidationGroups and everything working just fine.

I will show the code in a few seconds, but first be warned that I am using a validator made by myself which expects null or true as valid and a string or false as invalid. If the result is a string, it displays it as the ErrorMessage. So, on with the code:
The function to get a reference to the validator (which in some cases, especially Ajax, is not the same as the span with the same id)
function getValidator(id)
{
if (typeof(Page_Validators)=='object')
for (c=0; c<Page_Validators.length; c++)
if (Page_Validators[c].id==id) return Page_Validators[c];
return false;
}


The preparing function, which can be reused for more validators. I couldn't find a better way to encapsulate this behaviour yet, please feel free to enlighten me with ideas
// parameters are the value to be validated 
// and the validator object
function prepareAsync(value,validator) {
if (!validator) {
validator.doReturn=true;
return 'Error in prepareAsync: validator not found!';
}
// it's validating
if (validator.inAsync) {
validator.doReturn=true;
return 'In async validation';
}
// it has validated this value before
if (validator.prevValue==value) {
validator.doReturn=true;
return validator.result;
}
// create the callBack function as a method
// of the validator object
if (!validator.callBack)
validator.callBack=function(res) {
validator.inAsync=false;
validator.result=res;
if (res==null) {
validator.isvalid=true;
} else
if (typeof(res)=='boolean') {
validator.isvalid=res;
} else {
// setting the validation message is
// as simple as changing the innerHTML
// of the validator span
validator.innerHTML=res;
validator.isvalid=false;
}
// that's an ASP.Net validator function
// since .NET 1.0 upwards
ValidatorUpdateDisplay(validator);
}
validator.inAsync=true;
validator.prevValue=value;
validator.doReturn=false;
}


and now a sample validation function:
// parameters are the value to be validated
// and the id of the validator
function ValidateProdotto(value,id) {
// get the validator object
var validator=getValidator(id);
// reuse this function to all validators in the page
var res=prepareAsync(value,validator);
// doReturn says if it has a result for us
if (validator.doReturn) return res;
// perform the actual validation
PageMethods.ValidateProdotto(value,validator.callBack);
// and return false, since we are in async now
return false;
}


Hope this helps somebody. This applies to short validations, but feel free to enhance my design with cancellations of running async operations in case the value is changed or with an array caching all the values tried and validated.

Wednesday, October 24, 2007

StackOverflowException: Aspnet_wp.exe (PID: [number]) stopped unexpectedly.

Yesterday I was trying to guess what the hell is going on with my application. You see, I was moving controls from one panel to the other in case the browser was FireFox and I forgot all about it. In Internet Explorer it would work, in FireFox ASP.Net would crash, with a Server not available error and not any relevant message as to why. In the Application Event Log I would get stuff like:
aspnet_wp.exe (PID: 872) stopped unexpectedly.
and
EventType clr20r3, P1 aspnet_wp.exe, P2 2.0.50727.832, P3 461ef1db, P4 system, P5 2.0.0.0, P6 461ef191, P7 143a, P8 1f, P9 system.stackoverflowexception, P10 NIL.

and no explanations. Google would give me a lot of links that pertained to WebServices and Asynchronous operations and multi threading, but my application is a simple app. What was going on?

It turns out I was doing this:
pnlNoAjax.Controls.Add(UpdatePanel1.ContentTemplateContainer.Controls[0]);
Nothing wrong with it, except the control that I was adding was also pnlNoAjax and so it went round and round chasing its own tail until a stack overflow exception was generated.

So, bottom line: try to see if you don't have a control adding itself to its control collection when you meet this weird error. Or, of course, the problem might be in a WebService or threading operation :)

Disabling ASP.Net Ajax on a page with UpdatePanels

You have one beautiful page with Ajax.Net, UpdatePanels and the sorts. Then you go test it with FireFox and it doesn't work. Or you have some other reason for not wanting Ajax in certain situations, like for example people with no Javascript. So what do you do? How can you tell the page NOT to do Ajax postbacks?

The solution is to set ScriptManager's EnablePartialRendering to false. I used to do it with a Panel that was outside the UpdatePanel and in the page Init cycle I would move all controls from the update panel to this normal panel. And it worked, too.

Tuesday, October 23, 2007

INSERT or UPDATE or DELETE failed because the following SET options have incorrect settings: 'ARITHABORT' or something else

Quick fix: look for indexed views or indexes on tables with computed columns and delete the index or change it to not reference the view or the computed column.

I got this error while trying to optimize an SQL server. I did the trace, I used the Database Engine Tuning Advisor, it gave me an sql file of magical Create Statistics and Create Index lines. But after I applied it, happy that I will get a 38% increase in my SQL speed, I got this weird error:
UPDATE failed because the following SET options have incorrect settings: 'ARITHABORT'

I wasn't aware that a cluster could break your database! So I found this little Microsoft article: PRB: Error "INSERT Failed" When You Update Table Referenced in an Indexed View.

Yet it only speaks about Indexed Views and it somehow shifts the blame to some missing ArithAbort setting. Not so. In my case it was about one of the indexes referencing a computed column in the INCLUDE statement.

In my particular case, changing the offending index to not reference the computed column was the solution. Of course, indexing computed columns and views is totally possibly, but it depends on how you create those indexes. In my case, SET ARITHABORT ON was set before creating the index. The solution in the Microsoft Support article might be better, even if less attractive to lazy people as myself.

Monday, October 22, 2007

Thread was being aborted exception - possible solutions and unsolved problems

Update February 2016: This post discusses a problem in .Net 2.0 that is more than 8 years old. Perhaps you should look elsewhere. That being said, there are several situations here:
  1. The default execution timeout is 90 in ASP.Net, increase it to whatever you like (in seconds) with <system.web>
       <httpRuntime executionTimeout="VALUE" />
    </system.web>
    Also read this: What exactly is Appdomain recycling, since it is likely this applies in a lot more situations where the server decides the app needs to be recycled.
  2. You use a Response.Redirect, Server.Transfer or Response.End directly, which is the method that ultimately throws this exception. Response.Redirect has an optional bool parameter that, when set to false, does not execute Response.End. Response.End itself is obsolete, recommended is the HttpApplication.CompleteRequest method. Read the remarks for Response.End, it is a method exclusively left there as for compatibility with ASP and it is pretty damn awful. See here how to replace Response.End.
  3. The original problem that made me write this post, which was a long running method inside a web service in .Net 2.0, to which I have not found the solution back then. The solution is probably related to AppDomain/Application Pool recycling from the first point and at that time I did not look hard enough at all application pool settings.
  4. Some issues encountered by other readers that were caused by the ASP.Net application writing in its bin folder, causing the automatic recompiling of the app.

Read more about the ThreadAbortException, which is raised when aborting a thread, which in itself is a pretty bad idea. Ultimately, I would say that getting this exception nowadays is a sure sign of bad design.

Now for the original post:

Update: the problem I was facing is still there and with no solution. I must be doing something wrong, but I can't figure out what. It involves a web service in NET 2.0, added with Web Reference in another app. The service has a method that takes a lot of time. If I do it synchronously it works, depending on the Timeout property of the web service proxy and the executionTimeout setting in the web.config. If I do it asynchronously, though, it doesn't work! If it takes too long it just kills the thread. The Timeout property of the web service doesn't even count in async calls. My solution was to call the method synchronously and be done with it. If anyone has an answer for this, please let me know!

(Oh, but if you mean to tell me that an asynchronous operation in a web service should not take long and that it is bad design and so on and so on, don't let me know!)

The single most related article to my problem that I found on the net is this: timeout problem with webservice and suggests a client problem, but no solution other than asynchronously calling the synchronous call to the web service, and no explanation to the underlying problem.

As for the regular solution for Thread being aborted, it actually it's not my solution, it was given in a forum by a guy with the nickname dstefanov, but I stole it with impunity :)

Here it is:
ThreadAbortException happens when the thread serving the request doesn't finish for a long time. The ASP.NET hosting process aborts this thread after certain time. You can adjust that time with:

<system.web>
<httpRuntime executionTimeout="600" />
</system.web>

By default the executionTimeout="90" seconds.


This applies to ASP.Net web apps, including web services, so also to console or windows forms applications that use web services. My own personal favourite is 86400, the number of seconds in a day.

Thanks dstefanov!

Jem - They

I saw this chick sing "They" on Mtv. She was stripping in space in that video, a thing that I found a bit distasteful, even if it did link to a Jane Fonda scene in a film called Barbarella, Queen of the Galaxy. But that's the MTV world: strip if you want to get noticed. True enough, I haven't seen any other of her videos on any music television since, but then I stopped watching them.

Jem (real name Jemma Griffiths) is a Welsh singer and this is (I guess) the original video of "They". She is young, beautiful, but also has a nice voice and sound. Check her out at her official web site or the MySpace site.

ASP.Net Ajax, UpdatePanel, PageRequestManager, Dan Wahlin

I had to rewrite the entire post. It started from a nice article by a guy called Dan Wahlin and it ended with three (at least? :) ) separate links to his articles and his blog entered in my Technorati favourites.

Here are links to what appears to be a series about Asp.Net Ajax, really informative and concise:

Update Panel properties explained: Implement UpdatePanel Properties

Implement visual cues during updates:Inform Users With Customized Visual Feedback

Minimize the load on the server on many subsequent clicks or refresh requests:Coping With Click-Happy Users

Here is a complete list of the links in the same series:
ASP.NET AJAX Articles

Steroids for the brain: ampakine

I've found this while randomly browsing the net, a substance that is supposed to be increasing memory and brain plasticity called ampakine. An article called it steroids for the brain and I borrowed that in the title, since I found it is appropriate enough.

Like all mind enhancing drugs it was discovered by accident, while working on a cure for Alzheimer. Why would anyone try to enhance one's brain on purpose, anyway? :-|

I am not much of a biochemist (even if I recently made some acquaintances that are :) and I could ask them to enlighten me) so I will just post a list of links that I found on the subject. It seems that there are no publicly available pills yet, as the drug is still in trials, but who knows... maybe we can become smarter rather than dumber for a change.

Here are the links:

ampakines
A profile of the behavioral changes produced by
facilitation of AMPA-type glutamate receptors

ampakine
Ampakines
'Memory pill' for the forgetful

Friday, October 12, 2007

flashVars empty after Internet Explorer fix

In a previous post I was writing about a fix to remove the Press Spacebar or Enter to activate or use this control message. But it also made a mess out of a flash file I was trying to use. After a lot of looking into the source code (Flex) and trying to understand what happened, I found a solution.

First of all, you will find a lot of web pages advocating using a parameter called flashVars for sending parameters to Flash applications. Then you would use Application.application.parameters to get the variables URLEncoded in flashVars. That works in most cases, but not when:
a. you used an IE fix for the annoying message
b. you have in the movie and/or src parameters an url that has parameters. (like when you would get the SWF file out from an HttpHandler, for example)

The solution is to put all the variables you would put in the flashVars in the url of the movie or src parameters.

So, instead of :
<param name='movie' value='test.swf' />
<param name='flashVars' value='a=%27test%27&b=12' />

use
<param name='movie' value='test.swf?a=%27test%27&b=12' />

Don't forget to UrlEncode the values.

But why does this happen? Apparently, the problem is that after setting the innerHTML property the FlashVars param element has an empty value. I tried to fix the javascript to 1. get the value of FlashVars 2. do the fix 3. replace the empty FlashVars value with the saved value. It did not work! Even by javascript, after finding the param element with the name of FlashVars and an empty value, I could not set the value of the element. It probably has to do with the IE "fix". Something must clear the FlashVars when being set from anything else but from source.

Getting rid of the annoying Press Spacebar or Enter to activate and use this control message

Ok, the why is something I could never truly understand. It's some lawyer thing. But the fact remains that Microsoft was legally bound to show that message on each ActiveX control in Internet Explorer, thus screwing everybody and all their Flash pages.

When you Google this you find a miriad solutions. Some of them rewrite the entire HTML, others just take all the objects and embeds and rewrite their innerHTML or their outerHtml. But sometimes, it just seems that none of them work. And here is the catch for all of them: in order to work, the function that does the replacing of the HTML must be in an external Javascript file. Yes, you read right, if the function is inside the page, it doesn't work. Weird, huh?

Anyway, here is the script I use. It works, apparently.

function fixFlash() {
//ediy v2
n=navigator.userAgent;
w=n.indexOf("MSIE");
if((w>0)&&(parseInt(n.charAt(w+5))>5)){
T=["object","embed","applet"];
for(j=0;j<2;j++){
E=document.getElementsByTagName(T[j]);
for(i=0;i<E.length;i++){
P=E[i].parentNode;
H=P.innerHTML;
P.removeChild(E[i]);
P.innerHTML=H;
}}}
}


For more information about other solutions and the legal issue between Microsoft and Eolas read this specialised blog: IE ActiveX Change "Click to activate and use this control"

Update:
Well, I noticed that the Flash file I wanted to use stopped working after using this fix. Luckily I had the source and so I found a fix. The next post details it.

WebResource.axd or how I learned to love the embedded resource

It all started with my own library, a dll in which I wanted to include Javascript, CSS and ultimately images or flash files. I did it the only way I could in 1.1, mainly adding the resources to the project, setting them as Embedded Resource, then reading them and either put them in the page or write them in the application directory and link them in the page. As you can imagine, there were a lot of issues related to writing writes and so on.

But then .NET 2.0 and the AjaxControlToolkit arrived. This toolkit had this funny looking Tab thing, and it used images. So where did it get the images? I was surprised to see that the namespace of the TabContainer control was decorated with stuff like this:

[assembly: WebResource("AjaxControlToolkit.Tabs.tab.gif", "image/gif")]

then in the CSS files, stuff like

background-image:url(<%=WebResource("AjaxControlToolkit.Tabs.tab.gif")%>)

Could it be so easy? yes! And for the js files, they had this class called a ScriptControlBase and the only thing you needed to do to insert a javascript file was decorate the implementing class like this:

[ClientScriptResource("AjaxControlToolkit.TabPanel", "AjaxControlToolkit.Tabs.Tabs.js")]

But what was the underlying mechanism? Googling for WebResource.axd you get these informative links:
Using WebResource.axd for embedded resources
Accessing Embedded Resources through a URL using WebResource.axd

Working with Web Resources in ASP.NET 2.0

These three articles pretty much explain the basics, so I won't do anything but emphasize the more important points:
  • When you use the name of the resource, either when decorating the namespace or when getting the reference to it, use the project namespace and the folder in which the file is in, otherwise it will not work. So if you have the namespace MyControls.Web and you have the folder Images in which you embedded an Image.gif file, the name should be MyControls.Web.Images.Image.gif.
  • To programatically get the url for an embedded resource use Page.ClientScript.GetWebResourceUrl(Type type,string resourceName)
  • In order to get the contents of an embedded resource use code like this:
    Assembly assembly = GetType().Assembly;
    arr = assembly.GetManifestResourceNames();
    foreach (string name in arr)
    if (name==resourceName) {
    Stream s = assembly.GetManifestResourceStream(name);
    // do something with the stream
    break;
    }


But what is this WebResource.axd? It's an IHttpHandler, one that you can also implement quite easily. They are used to handle Ajax, file uploads, get access to all kinds of resources. Look it up. Somewhere in the near future I might write an article about these, too.

Wednesday, October 10, 2007

Saving Internet Explorer and FireFox tabs

It happened to everyone: you opened a bunch of sites and you have to go or restart your computer or something like that. You would like to save those tabs for later reference. Well, Internet Explorer does have something built in to take care of this, but it's kind of stupid. A third party software would be far better.

But anyway, you are in a hurry, you want a quick solution and I have two for you:
1. Make sure you have set Warn me when closing multiple tags in Internet Options, then close your browser. It will ask you if you want to close all tabs, click on Show Options, check Open these next time I use Internet Explorer.

2. Go to Internet Options and then just click Use current in the Home page section. It will set all your open sites as home pages.

In Firefox things are far better. Just right click on the tabs bar and bookmark all. It will ask you to save them with a name. Then just go to the Bookmarks menu and reload them.

Tuesday, October 09, 2007

Sarah Bettens from K's Choice

I remembered today of a song that I liked to listen to called Everything for Free, by K's Choice. Back then (oh, my tired bones) the Internet was not yet as... evolved as these days and you couldn't really get all the discography of an artist in a few minutes, so I only listened to this one song that was also on MTV.

I am putting the video clip here, but really do look into the singer, Sarah Bettens, who also has a solo project beyond K's Choice and has a lot of videos on YouTube. Here are some sites you can visit:

K's ChoiceSarah Bettens
Official SiteXX
Myspace SiteXX
Wikipedia SiteXX


Absolute position of html elements in Javascript

Update: in IE7 I noticed that the style property doesn't keep the inherited values or the CSS values, but only the inline values of style. 'currentStyle' keeps all values, therefore I used that too, in case style would not work.

Update: the same can be done in FireFox by using the document.defaultView.getComputedStyle(myObject, null) syntax equivalent to myObject.currentStyle in Internet Explorer. I have not updated my function to work with that, though.

Update: By adding a break in case of relative or absolute positioning I seemed to have fixed most of the issues regarding those types of positioned elements.

Whenever one wants to popup something with Javascript, the bigger problem arising is to find the absolute position of the element that you want the popup to cling to. Searching the web you will probably find a site like this: How to get an element’s position and area, you will try that solution and say "Wee! It works!" until you scroll something inside the page and everything turns to mush.

Analysing the code and the html you will see that it ignores completely the scrolling of various elements. Even worse, the offsetParent is one for Internet Explorer and another for FireFox. So here is my solution, which seems to work in most cases. I will work on it some more, but not in the near future and usually one doesn't need a popup in a popup. So here is the code:

function findPos(obj)
{
var curleft = 0;
var curtop = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curleft += obj.offsetLeft-obj.scrollLeft;
curtop += obj.offsetTop-obj.scrollTop;
var position='';
if (obj.style&&obj.style.position)
position=obj.style.position.toLowerCase();
if (!position)
if (obj.currentStyle && obj.currentStyle.position)
position = obj.currentStyle.position.toLowerCase();
if ((position=='absolute')||(position=='relative')) break;
while (obj.parentNode!=obj.offsetParent) {
obj=obj.parentNode;
curleft -= obj.scrollLeft;
curtop -= obj.scrollTop;
}
obj = obj.offsetParent;
}
}
else {
if (obj.x)
curleft += obj.x;
if (obj.y)
curtop += obj.y;
}
return {left:curleft,top:curtop};
}

Wednesday, October 03, 2007

Poe - Not a Virgin Anymore

This song is one of my latest favourites, even if the sound itself is a bit too much like country music, the lyrics are really funny. I wasn't able to find the video for the song, so here is a random video one.



Poe, by her real name Ann Danielewski is the daughter of the Polish director Tad Danielewski and is singing since 1990. Look for her other songs as well, some are really smart and they sound pretty cool.