Ajax
ASP.Net Ajax, Error Handling and WTF
I am facing some really unpleasant choices at the moment. And I thought it would be so easy.
I wanted to add global error handling to all the web services that we expose as [ScriptService].
For some reason, they didn't show up in the Application_Error event, and that caused the exception details to be sent to the client.
It looks like for some strange reasons, web services exceptions don't go through the Application_Error, so I implemented a SoapExtension to handle that, but ScriptService doesn't go through the Soap layers, so it obviously doesn't work.
Then I went and looked at the code.
The whole thing...
Javascript, lexical scopes and what your momma thought you about variables
Let us assume that we have this amazing javascript function: function test()
{
var nums = [1,2,3,4,5,6,7];
for(var i = 0; i<nums.length; i++)
{
var alertLink = document.createElement("A");
alertLink.href = "#";
alertLink.innerHTML = nums[i];
if( nums[i] % 2 == 0)
{
alertLink.onclick = function() { alert('EVEN: '+ nums[i]); };
}
else
{
alertLink.onclick = function() { alert('ODD: ' + nums[i]); };
}
document.firstChild.appendChild(alertLink);
document.firstChild.appendChild(document.createElement("BR"));
}
}
Can you guess what it would generate? Quite a few undefines alerts, as a matter of fact. Why is that? Because the anonymous function is a closure, which capture not the value of i, but the i variable itself.
This means when we click on a link that this method has generated, we use the...
You leave a team alone for one week...
And they go ahead and write Outlook Web Access behind your back... I am going over the code, and I am simply amazed. JavaScript & HTML component, using DomainJSon Generation and some additional smarts around that idea.
Cross Site Scripting
So I had to do it today, I had two pages, in two unrelated domains (foo.com and bar.com) and I had to open a page from one and interact with it. Security constraints disallow this, unfortantely. There are all sorts of ways around it, mostly focusing on proxies, but I didn't want to get into that for a simple page, so I decided to write my own stupid method to do it. From foo.com, the calling page: var url = "http://www.bar.com/someImportantPage.castle?id=15"&onCloseRedirectTo=" +
encodeURIComponent(window.location.href + ...
Handling javascript localization in Mono Rail
I run into the issue of having to alert the user of some error, and it brought home the fact that English & Hebrew are not easy to mix. In fact, code such as this is consider a very bad sign, usually code that you don't really want to touch, see or believe in: So, we need some sort of a way to externalize those strings, even if the only language that this application is going to use is Hebrew, simply because of the pain of mixing the two together. After thinking about it for a while, I...
YSlow: Another Web Developer adding for FireFox
After getting hooked into FireBug, it looks like YSlow it going to be another essential tool. Just the screen shots makes me want to drool...
Using partials in Web Forms
Partial is a MonoRail term to a piece of UI that you extract outside, so you can call it again, often with Ajax. This is something that is harder to do in WebForms. Yesterday I found an elegant solution to the problem. ASPX code:<div id="UserDetailsDiv">
<ayende:UserDetails runt="server" ID="TheUserDetails"/>
</div>
User Control:<div>
Name: <asp:label ID="Name" runat="server"/> <br/>
Email: <asp:label ID="Email" runat="server"/>
</div>
Client Side Code:function changeUser(newUserId, div)
{
var srv = new MyApp.Services.UserDetails();
srv.GetUserDetailsView(newUserId, onSucccessGetUserDetailsView, null, div);
}
function onSucccessGetUserDetailsView(response, userContext)
{
var div = $(userContext);
div.innerHTML = response;
new Effect.Highlight(div);
}
Web Service Code:[WebMethod(EnableSession = true)]
public string GetUserDetailsView(int userId)
{
User user = Controller.GetUser(userId);
//there may be a better way to do this, I haven't bothered looking
UserDetails...
Bug hunting, looking around the box
I just spent way too long trying to figure out what is wrong with this code: <script type="text4/javascript"> function customerUpdated() { ...
ASP.Net Ajax vs. Unit Tests
By definition, unit tests should be fast. Integration tests should be as fast as possible as well. Almost by definition, Javascript is not fast. In the battle between ASP.Net Ajax and my Unit/Integration tests, so far the only loser it me. This is the point when I am going to stop dedicating any more time to making this work.
ASP.Net Ajax, Performance and Race Conditions, Oh MY!
I have just tracked down the Nthbug in my application that I can blame ASP.Net Ajax for. To be rather exact, I can blame ASP.Net Ajax performance, and to be absolutely clear, I am talking about initialization performance. The main issue is that I keep running into is that it takes human noticable time for the extended behaviors to be set on the page. By human noticable time I means over a second. The immediate result is that users are able to interact with the page in unexpected ways. Leading to all...
JavaScript Race Conditions
About a week ago I posted how to handle Multiple Cascadiong Drop Downs using MS Ajax. That worked, except sometimes it didn't work. Took me a while to figure out that there was a race condition there. Let me tell you, Javascript in the browser is not the language for tracking down threading issues. At any rate, here is the fix. function changeOnParentChangeOnProductsToAvoidRaceConditions() ...
Multiple Cascading Drop Down Lists
I recently found myself needing to handle a case where I had three drop down lists, and I needed to setup cascading relationship between those: Using the CascadingDropDown extender really make this a breeze, except that I had additional requirement, the benefits drop down should be filtered by both policy and insurance. So, when a policy is selected, all the matching insurance types are filled as well as all the matching benefits for the policy. When an insurance is selected, the benefits list should contains only the benefits...
Development stats
A single page. 34 integration tests. 432 lines of test code (excluding data setup and stuff move to test infrastructure). 66 lines of code behind 210 lines of Javascript 641 lines of in the ASPX file (include the javascript above) ...
Code smell
Why does it have to be like this? if($F('<%= PolicyDescription.ClientID %>')== '<asp:Literal runat="server" Text="<%$ Resources:PolicyResources, DescriptionNotFound %>"/>') { ...
How to add Atlas ListSearch to a drop down via code
I wanted to add this functionality to all my drop down lists, but it turned out that this is surprisingly difficult to do.
I am using the normal "inherit from all the controls that you are using" model, and I put the following inside my Drop Down class:
protected override void OnInit(EventArgs ignored)
{
Page.RegisterRequiresControlState(this);
Page.Load += delegate
{
extender.ID = "ListSearch_" + ID;
extender.PromptCssClass = "invisible";
extender.TargetControlID = "dummy";
extender.ResolveControlID += delegate(object sender, ResolveControlEventArgs e) { e.Control = this; };
AddExtenderToParentFormOrUpdatePanel();
};
}
private void AddExtenderToParentFormOrUpdatePanel()
{
Control ctrl = Parent;
while( !(ctrl is HtmlForm) && !(ctrl is UpdatePanel))
ctrl = ctrl.Parent;
UpdatePanel panel...
Removing the leaky abstractions from WebForms
My preferred approach to develop on the web is using MonoRail, but since I am doing a lot of work for clients, they sometimes get to choose the technology. My current project is using Web Forms and Atlas. I already mentioned that I am using Igloo to provide a truer MVC support for WebForms, it is not as good as what MonoRail can provide, but it is nice. (The only problem is that I keep feeling that my controllers are getting too big and complex, I have finally finished doing a stint on the UI that...
Atlas Weight Issues: Take 2
I got some really great comments on my last post. Apperantly FireFox doesn't report on the wire numbers, so here are the numbers from Fiddler. After clearing the cache, a page with a text box, ScriptManager and CalendarExtender: Request Count: 17 Bytes Sent: 10,492 Bytes Received: 149,145 Refreshing the page (meaning we get stuff from the cache): Request Count: 14 Bytes Sent: 9,382 Bytes Received:...
Atlas weight issues: what am I missing?
I have the strong feeling that I am missing something. We have just run into a major slow down in one of our pages, as a result of adding the CalendarExtender. This led me to do some searching, and I am not sure that I can believe the results. Let us take this simple page: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="ExplodingMonkeys.Web.test" %> ...
Why isn't there a simple way to trigger an UpdatePanel from client script?
All I want is something in the order of:$get('<%= MyUpdatePanel.ClientId %>').update(); You would think that this is elementry, but apperantly we get things like this, which involve tricking the UpdatePanel into triggering.
Evaluating Atlas
Sorry, I meant that I am evaluating Microsoft(R) ASP.Net(TM) Ajax(Patent Pending) Extentions :-). I mentioned before that I am not really feeling overly excited about that whole Ajax thing. Because of a client constraints, I am unable to use MonoRail (but I use just about everything else from the Castle stack :-) ), so I thought that I would give Atlas a try. This is still very early in the project, but I like to understand how things works so I know why they broke. And for some reason, just about anything breaks...
With or without you: Ajax
David Hayden has a post (ASP.NET AJAX Web Controls - AJAX Experience Without Learning AJAX) that really bothers me. He talks about the different components that he tested for Ajax support, and conclude with:I was thinking that the AJAX experience was going to be a lot of work, but my guess is that the control vendors are taking care of this for me. And, quite frankly, I didn't want to have to learn this technology in depth if I could get away with it. Frankly, I would like to know as much about...