Archive for September 2010

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>
  3. <script>
  4.     $(document).ready(function () {
  5.         $("#button1").click(function () {
  6.                 alert($(".ResultPlaceHolder").text());
  7.         });
  8.     });
  10.    var i = 1;
  11.    function updateResult() {
  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.    }
  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.

  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. }
  7. XDocument doc = XDocument.Parse(xml);
  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. {
  4.     public bool Equals(HistoryDataElement x, HistoryDataElement y)
  5.     {
  6.         return x.Date == y.Date;
  7.     }
  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>.

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