Ajax Calls on ASP.NET UserControls

You cannot make Ajax calls on ASP.NET user controls can you? So what’s the solution? give up? absolutely not.

While believing arrogantly that I am a genius or that C# is the most beautiful piece of software ever created (and will be), ideas had been floating in my head non-stop, and most of the problems I faced just got solved, of course with nasty non advised tricks :-), keep reading.

I needed to call a web method on a usercontrol, and all I wanted was the result of the processing returned by this method, so I tried the ASP.NET AJAX PageMethods but the result was PageMethods is not defined!

Cool, if we need the result of the web method in our JavaScript, we can profit of the ASP.NET server controls and the UpdatePanel for Ajax calls, here are the steps:

1. Inserting an UpdatePanel on you usercontrol, and within it, inserting a Label and a button or a timer (or whatever way you want to callback you usercontrol)

  1. <asp:UpdatePanel ID="UpdatePanel1" runat="server">
  2.     <ContentTemplate>
  3.         <asp:Timer ID="Timer1" runat="server" Interval="4000" ontick="Timer1_Tick">
  4.         </asp:Timer>
  5.         <br />
  6.         <asp:Label ID="Label1" runat="server" Text="Label" CssClass="ResultPlaceHolder"></asp:Label>
  7.     </ContentTemplate>
  8. </asp:UpdatePanel>

The label above will be a placeholder of our Ajax call result, it has a class name ResultPlaceHolder so that it will be found easier using jQuery, as you should know, ids and names on server controls get messed up in client side with ASP.NET.

2. Setting up the result from within the Timer tick method (or the click method of your button)

  1. protected void Timer1_Tick(object sender, EventArgs e)
  2. {
  3.     Label1.Text += "a: ";
  4.     return;
  5. }

3. Exploiting these fresh results in your JavaScript, the best way would be by setting an interval for a function that checks the results in the placeholder every given moments.

  1. <script src="http://my-super-slow-uncool-laptop/jquery/jquery-1.4.2.min.js" type="text/javascript"></script>
  2.  
  3. <script>
  4.     $(document).ready(function () {
  5.         $("#button1").click(function () {
  6.                 alert($(".ResultPlaceHolder").text());
  7.         });
  8.     });
  9.  
  10.    var i = 1;
  11.    function updateResult() {
  12.         // DO WHAT EVER YOU WISH WITH THE RESULTS
  13.        i++;
  14.        if (i < 10)
  15.            $("#show").html($("#show").html() + "<br/>" + $(".ResultPlaceHolder").text());
  16.        else {
  17.            $("#show").html($(".ResultPlaceHolder").text());
  18.            i = 1;
  19.        }
  20.    }
  21.  
  22.    setInterval(updateResult, 1000);
  23. </script>
  24. <p>
  25.     <input type="button" value="Ajax it" id="button1"/>
  26.     <div id="show"/>
  27. </p>

And voila, this is a nasty nonadviced method to do Ajax calls to webcontrols’ methods, a la “vite fait”. Enjoy.


How to select distinct values based on a specific predicate using Linq Disctinct method

Selecting distinct values in a Linq query while working on non trivial data need more than a simple call to the extension method Distinct().

Say I have the following xml data, and I want to select only distinct data elements based on their date attribute.

  1. <SOMETING>
  2.     <HISTORY>
  3.         <data date="19/01/10 14:34:00" >1963</data>
  4.         <data date="19/01/10 13:34:00" >1960</data>
  5.         <data date="19/01/10 14:34:00" >1960</data>
  6.         <data date="17/01/10 21:34:00" >1911</data>
  7.         <data date="17/01/10 21:34:00" >1911</data>
  8.         <data date="17/01/10 11:34:00" >1911</data>
  9.         <data date="17/01/10 18:34:00" >1911</data>
  10.         <data date="17/01/10 17:34:00" >1911</data>
  11.     </HISTORY>
  12. </SOMETING>

As you can see there are some duplicates regarding the date attribute, the following Linq query will return all the data elements as an IEnumerable of HistoryDataElement.

  1. class HistoryDataElement
  2. {
  3.     public string Date { get; set; }
  4.     public int Value { get; set; }
  5. }
  6.  
  7. XDocument doc = XDocument.Parse(xml);
  8.  
  9. var dataElements = (from data in doc.Descendants("data")
  10.                                 select new HistoryDataElement
  11.                                 {
  12.                                     Date = data.Attribute("date").Value,
  13.                                     Value = int.Parse(data.Value)
  14.                                 });

If we want distinct results based on the date attribute for example, we have to create a comparison class that implements the interface IEqualityComparer<T>.

Here is a very simple implementation:

  1. class DataExtractorElementComparer : IEqualityComparer<HistoryDataElement>
  2. {
  3.  
  4.     public bool Equals(HistoryDataElement x, HistoryDataElement y)
  5.     {
  6.         return x.Date == y.Date;
  7.     }
  8.  
  9.     public int GetHashCode(HistoryDataElement obj)
  10.     {
  11.         return obj.Date.GetHashCode();
  12.     }
  13. }

With this class in place, we can just pass a new instance of this class to the Distinct method to get the desired results :

  1. var dataElements = (from data in doc.Descendants("data")
  2.                                 select new HistoryDataElement
  3.                                 {
  4.                                     Date = data.Attribute("date").Value,
  5.                                     Value = int.Parse(data.Value)
  6.                                 }).Distinct(new DataExtractorElementComparer());

Notice that this way, you are eliminating all the duplicates that have the same property date, so only the first element of the matching elements is retrieved even If the other properties differ, this is cited by code in the Equals method of the IEqualityComparer<T>.


Multilingual Website Interface on the Fly With jQuery

Applying a multilingual interface on your webpages and allowing the change at the client side without the need for a server postback has never been easier using the technique I’ll describe in this post.
While developing Bloginto, I came across the situation of implementing an English-Arabic-French interface with the possibility to change the language on the fly (on the client side), so I used a trick so close to culture resource files in the .NET.
My first priority was to write the minimum of code using jQuery, and as you will see, it is *really* minimal.

1. Preparing the resources for the language

We will encapsulate the language resources with Javascript arrays, here is an example:
  1. function getLanguageResources() {
  2.     var fr = new Array(); var en = new Array();
  3.  
  4.     fr['settings'] = "paramètres"; en['settings'] = "settings";
  5.     fr['default_feed'] = "Flux par défaut"; en['default_feed'] = "Default feed";
  6.     fr['hidden'] = "Masquer"; en['hidden'] = " Hidden";
  7.     fr['save_settings'] = "Enregistrer les paramètres"; en['save_settings'] = "Save settings";
  8.  
  9.     var resources = new Array();
  10.     resources['fr'] = fr;
  11.     resources['en'] = en;
  12.  
  13.     return resources;
  14. }
The getLanguageResources function returns an array that contains an associative key/value arrays of the desirable languages, notice how the same key is used for the different translations.

2. Preparing the HTML markup

We need to put placeholders for the multilingual text to show in the markup, I choose a <span> tag here, but obviously you can use whatever elements fits best. The trick is to have all these multilingual spans use the same name attribute (this is not a necessity neither, you can use whatever attribute you wish), and have them use another attribute, for example caption which value is the key of the text to show in the resource arrays.
We will also add two buttons to test the language change, here is the final markup :
  1. <input type="radio" id="radioEnglish" name="radio-language" value="en"/><label for="radioEnglish">English</label>
  2. <input type="radio" id="radioFrench" name="radio-language" value="fr"/><label for="radioFrench">Français</label><br/>
  3.  
  4. Text for : settings : <b><span name="lbl" caption="settings"></span></b><br/>
  5. Text for : default_feed : <b><span name="lbl" caption="default_feed"></span></b><br/>
  6. Text for : hidden : <b><span name="lbl" caption="hidden"></span></b><br/>
  7. Text for : save_settings : <b><span name="lbl" caption="save_settings"></span></b><br/>
Notice how the radio buttons for changing the language have values which are the keys of the resource language (the arrays).

3. jQuery magic

Now we will apply some jQuery code to associate the spans with their corresponding text from the language selected by the radio buttons
  1. function changeLanguage(lang) {
  2.     var langResources = getLanguageResources()[lang];
  3.  
  4.     $("span[name='lbl']").each(function (i, elt) {
  5.         $(elt).text(langResources[$(elt).attr("caption")]);
  6.     });
  7. }
  8.  
  9. $(document).ready(function () {
  10.     $("input[name='radio-language']").click(function () {
  11.         changeLanguage($(this).val());
  12.     });
  13. });
Here we attach a click event to the radio buttons, and we simply call the function changeLanguage whenever a button is clicked, we pass the value of the “value” attribute of that button to the function which represents the specified language (‘fr’ or ‘en’)
The changeLanguage function loads the corresponding array of the languages from the getLanguageResources function, then iterate through every element that has the attribute namelbl”, and change its text to the value in the resource language array which key is the caption of that specified element (span), pretty simple!
As you can see, all the magic is done with 2 lines of jQuery, if you guessed that the “.attr()” method will do the same instead of “.each()” then you’ve guessed wrong, attr() applies only to the first element in the selection set. See .attr() specification here.

4. Demo

Her is a working demo http://jsfiddle.net/uUgWD/.

Posted in , |

Bloginto 2.0 is here, with a lot of improvements

Bloginto is a Google Chrome extension that brings feeds from the Digg like websites called Bloginy for both the Algerian http://bloginy.com and the Moroccan http://bloginy.ma

Today I’m pleased to announce that the version 2.0 of the extension is here, you can install it from https://chrome.google.com/extensions/detail/jppmcmbnmodlmgbfdddmeopgagancoak or update it from the settings section in Google Chrome if you have already installed the previous version.

This new version $(‘was’).completely(‘jQuery’, ‘fied’), cleaner and reliable code has been introduced to make sure handling all the error cases by showing pretty informative messages to the user. Enough talking, here are the new features :

settings page

As you can see from the settings page :

  • You can choose the default view, the Algerian or the Moroccan Bloginy, this has been present in the previous versions, but it has an impact on the notifications of the unread and new arriving feeds, you will notified only when feeds from the default feed arrive.
  • The notification themselves notifications: the number shows the unread feeds count, it will refresh automatically and change when you read feeds or new ones become available.
  • Because you can vote on articles directly from the extension now, there is a section where you can save your user name and password for both, Bloginy.com and Bloginy.ma.
  • Timeouts for the request, you should make this bigger if you have slow internet, and the feeds timeout, this is the frequency of checking new articles on the website.
  • While reading feeds, you can mark them as read, and the extension offer you to hide read feeds, or just mark them with a different color.
  • And most of all, it is now multilingual, you can change the language from Arabic to French to English, and it works on the fly (God bless jQuery), if you need to know how this is done, here is the code that does it all :p

    $("span[name='lbl']").each(function(i, elt){
        $(elt).text(l[$(elt).attr("caption")]);
    });
       

    where l is the resources language;

ar settings[12]

The extension itself allows the marking/hiding of the read posts, live voting and twittering the posts directly from the extension. You can toggle hidden posts by clicking on the button at the top. To vote, you simply click on the “like” icon, to twitter… well you click on the twitter icon and to mark a post as read, you click on the description of the post.

Finally, I hope Bloginy will get a little active after making the voting available directly and eventually allowing multiple languages that may match the users tastes.

The code source is available on Google Code at this address : https://code.google.com/p/bloginto-chrome/

$(‘feed > back’).is({always: ‘welcome ;)’}) ;
Ramadan Mubarak for all, and that’s my present for you guys to spend more time “engaged” with the community.

main screenerror notifications

Posted in |

How Does Google Pack Know What Application is Installed On Your Computer

Google pack is a set of software made available free by Google including programs by Google like Chrome and Picasa or other vendors like Mozilla Firefox and Adobe Reader. What is strange about the Google pack is its webpage, where it shows the applications you have installed on your computer and the applications that are not installed already.

The question that pops first is, how does a webpage knows what software is installed on my computer? I decided to see how does it work, inspecting Google’s coming-from-hell javascript files and trying to figure out how things are put together. To be honest, my motivation was first to know if I can use Google’s technique to leverage any information about other installed software on someone’s computer or not, and the answer I simply: no you cant, don’t bother.

Google’s pack webpage http://pack.google.com/ links to a javascript file and have some application parameters initialized at the page loading, with a notable array of guid ‘s and application names:

  1. {'93613D9F-C440-475B-8379-E7B7E37DAAB7':'ci_ar',
  2. '71339EA2-A88C-11DE-8E3D-65F655D89593':'ci_avast',
  3. '8A69D345-D564-463C-AFF1-A69D9E530F96':'ci_chrome',
  4. '74AF07D8-FB8F-4D51-8AC7-927721D56EBB':'ci_earth',
  5. …}

It turns out that Google stores information of the applications in the Windows registry (not exactly the same technique on other systems) at the path HKEY_LOCAL_MACHINE\SOFTWARE\Google\Google Updater\AppData\. My research was mainly about how does the Javascript code figure out how to fetch these information from the registry and if it is possible to make it read information from other locations in the registry.

Using burp proxy to intercept and change the applications guid on the fly in the html page, I didn’t come to any result, and it turns out that the only information that is read from the registry was only from  inside HKEY_LOCAL_MACHINE\SOFTWARE\Google\Google Updater\AppData\.

So the only trick left was to analyze the javascript file http://pack.google.com/cominst.js?2 (go ahead, take a look), if you want to try the code yourself, you can use the console in firebug under firefox or the Developer Tools (Ctrl + Shit + I) under Google chrome.

firebug

The javascript code defines some objects used to manipulate all the operations from reading the list of applications available, to fetching the applications already installed etc…

First a script on the page creates a _CI_Pack object named pack, this pack object have a property named plugin that contains a Plugin object which is the main piece of code we are looking for. This plugin is an embed object installed on the page with the function Plugin.createCIObject that inserts the following code on the page :

  1. <embed id="CIPlugin_14" type="application/x-vnd.google.cominstctrl.14" width="0" height="0">

This plugin then exposes an attribute called ciobj which is the one reading information from the registry.

In fact this plugin preloads all the information from the registry found in HKEY_LOCAL_MACHINE\SOFTWARE\Google\Google Updater\AppData\ in advance, and the guids that are presented in the pack object have no effect on these information, that’s why we can’t inject or make the plugin read other keys outside this path.

You can read the guid of the applications loaded by the pluing using this code :

  1. var b = pack.plugin;
  2. var e = b.ciobj;
  3. alert(e.Applications.Length);
  4. for (i = 0;i<e.Applications.Length; i++)
  5.     alert(e.Applications.ElementAt(i).Id);

How the plugin discover the installed applications :

The plugin object uses a simple method to know if the application is installed or not, installed applications have a version number associated with their corresponding object, if the application is not installed, the version number have the value of null, Google checks if the version number is not null, and hence figures out if the application id already installed or not.

  1. function d(m) {
  2.     if (!m) return false;
  3.     var o = c[m.Id.toUpperCase()];
  4.     if (!o) return false;
  5.     if (b.ci_mimeNum >= 14) { //Here the script check for the installed application
  6.         m = m.Version;
  7.         if (!m) return false
  8.     }
  9.     return i[o] = true
  10. }

Note that every object in pack.plugin.ciobj.Applications have the two properties exposed for javascript which are Id and Version. The script is really complicated due to the shortening in the variable names, and this function is the one responsible for returning the installed apps function getInstalledList(b, c).

And that’s it, maybe when someone else wonders someday how Google Pack fetch the information of installed applications on the visitor’s computer, he won’t hopefully waste 3 or such days trying to figure out how that javascript file works.

Posted in , |

Circular Links in You Twitter/Facebook updates

Say you want to insert a link for your tweet inside that same tweet, or want to link a facebook update inside the update itself. The issue with this is that: first you can’t know what will be the link to your new tweet/update, and second, once you post something on these sites you can’t change it (unlike Google Buzz for example).

I am used to celebrate my tweets which rank is of the form xxxx where 0<x<10 (I expect some technical knowledge for my reader :p), for example my 1111th and 6666th tweet, and usually the form of the tweet was :

wohoo, my xxxxth tweet [and a link to this same tweet here]

The idea was to use a link shortening service and do the following, we can use bit.ly

  • Check if the url http://bit.ly/WHAT_EVER_YOU_WANT_HERE is not already taken, by typing it into the browser and checking that a Page Not Found error occurred which means the suffix WHAT_EVER_YOU_WANT_HERE is available.
  • post your tweet/update with the above link.
  • then take the link of the new tweet/update, shorten it with bit.ly and custom the shortened url using the same suffix of the link above.

And by doing this, you finally have a circular link, targeting the same tweet/update which contains the same link targeting the same… you get the point.

Here is an example of a tweet:

A test tweet with a circular linkhttp://bit.ly/WHAT_EVER_YOU_WANT_HERE

Posted in , |

Swedish Greys - a WordPress theme from Nordic Themepark. Converted by LiteThemes.com.