Thursday, April 23, 2009

Dumb Microsoft design

System.Web.UI.Pair is a class that has the simple purpose of grouping 2 objects together as a pair. Now why is it in System.Web.UI namespace? Beats me!!!

kick it on DotNetKicks.com

Sunday, January 11, 2009

PowerFailureDetector.exe

This little application can detect when you get a power failure (and thus you are now running on your UPS). For it to do that, you guessed it, there are a couple of prerequisites:
  1. You need to have a UPS (obviously)
  2. You need to have a network card to which is plugged a cable connection that gets disconnected when the power is off. In other words you might need a hub, or maybe a modem that gets turned off when you lose power. Also this means that this hub/switch/modem should not be running on backup power.
    I did not test this with wireless connections, but I am guessing wireless connections could cause the application to mistakenly think that you have a power failure when a wireless connection is lost.
  3. .NET Framework 2.0 or above
Cannot think of anything else, I guess that should do it. Now how it works. When your connection gets disconnected (one way or another, you might remove the LAN cable yourself) and that goes for any network connection (to be on the safe side if you have more than one connection), if this application is running, it will detect that and act accordingly giving you a couple of options. The easiest way to figure this application out is to test it, worst case scenario your machine gets hibernated

Application is written in C#, and I will provide source code if needed, enjoy and give me feedback.
Here is the link: Download.

kick it on DotNetKicks.com

Wednesday, November 26, 2008

ASP.NET Wizard Control Serious Bugs in Navigation

Problem: Wizard seems to get confused between its navigation controls in its different steps
Expected Behavior: The confirm Message is supposed to appear only when the Next Button of the third step is clicked.
Actual Behavior: After click Next and Previous a couple of times, Next Button of other steps now display the confirmation message.

Code (Page)


<asp:Wizard ID="wz1" runat="server" DisplaySideBar="False" >
<WizardSteps>
<asp:TemplatedWizardStep ID="step1" runat="server" Title="Step 1" StepType="start">
<ContentTemplate>Step1 Content</ContentTemplate>
<CustomNavigationTemplate>
<asp:Button ID="btnNext1" runat="server" UseSubmitBehavior="true" CommandName="MoveNext"
Text="Next1" />
</CustomNavigationTemplate>
</asp:TemplatedWizardStep>
<asp:TemplatedWizardStep ID="step2" runat="server" Title="Step 2" StepType="Step">
<ContentTemplate>Step2 Content</ContentTemplate>
<CustomNavigationTemplate>
<asp:Button ID="btnPrevious2" runat="server" CausesValidation="false"
CommandName="MovePrevious" Text="Previous2" />
<asp:Button ID="btnNext2" runat="server" UseSubmitBehavior="true" CommandName="MoveNext"
Text="Next2" />
</CustomNavigationTemplate>
</asp:TemplatedWizardStep>
<asp:TemplatedWizardStep ID="step3" runat="server" Title="Step 3" StepType="Step">
<ContentTemplate>Step3 Content</ContentTemplate>
<CustomNavigationTemplate>
<asp:Button ID="btnPrevious3" runat="server" CausesValidation="false" UseSubmitBehavior="false"
CommandName="MovePrevious" Text="Previous3" />
<asp:Button ID="btnNext3" runat="server" UseSubmitBehavior="true" CommandName="MoveNext"
Text="Next3" />
</CustomNavigationTemplate>
</asp:TemplatedWizardStep>
<asp:TemplatedWizardStep ID="step4" runat="server" Title="Step 4" StepType="Step">
<ContentTemplate>Step4 Content</ContentTemplate>
<CustomNavigationTemplate>
<asp:Button ID="btnPrevious4" runat="server" CausesValidation="false" UseSubmitBehavior="false"
CommandName="MovePrevious" Text="Previous4" />
<asp:Button ID="btnNext4" runat="server" UseSubmitBehavior="true" CommandName="MoveNext"
Text="Next4" />
</CustomNavigationTemplate>
</asp:TemplatedWizardStep>
</WizardSteps>
</asp:Wizard>

Code (Behind)

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) ViewState["called"] = false;
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

Button btnNext;
btnNext =
step3.CustomNavigationTemplateContainer.FindControl("btnNext3") as Button;
btnNext.Attributes.Add("onclick", "return confirm('" + DateTime.Now.ToString() + "');");
ViewState["called"] = true;

}

}

Note that till now I have not found a certain pattern to this problem, each case is different, for example, adding a button would change when the bug would appear. In this example clicking Next acouple of times will show the unexpected behavior.
I don't know what causes this, for now I am gonna let go the use of the Wizard control and create my own solution (showing and hiding panels).

kick it on DotNetKicks.com

Thursday, October 30, 2008

AnkhSvn vs. Intellisense (Bug fixed)

According to the AnkhSvn guys, the problem was fixed. You can track it here and here.
Keep it up.

kick it on DotNetKicks.com

Saturday, October 25, 2008

AnkhSvn vs. Intellisense

This appears to be a bug in AnkhSvn. The Pending Changes window (View -> Show Pending Changes) causes intellisense (list of suggestions you get while typing code) in Visual Studio 2008 to disappear. It only appears for a fraction of a second and then vanishes. To confirm this all I had to do is close the Pending Changes window and intellisense works again.
Hope someone fixes that.


kick it on DotNetKicks.com

Tuesday, October 21, 2008

Oracle Outer Joins, non-commutative join conditions

In this post I am going to show how Outer Join Conditions do not behave as expected and in other words are not commutative. Check the following 2 sample tables:

Script:


CREATE TABLE TABLE1
(
ID NUMBER(10),
NAME VARCHAR2(50 BYTE)
)

CREATE UNIQUE INDEX PK_TABLE1 ON TABLE1(ID);
ALTER TABLE TABLE1 ADD (CONSTRAINT PK_TABLE1 PRIMARY KEY (ID));

-----------------
CREATE TABLE TABLE2
(
ID NUMBER(10),
TABLE1_ID NUMBER(10),
NAME VARCHAR2(50 BYTE),
CREATE_DATE DATE
)

CREATE UNIQUE INDEX PK_TABLE2 ON TABLE2(ID);
ALTER TABLE TABLE2 ADD (CONSTRAINT PK_TABLE2 PRIMARY KEY (ID));

Here is some data to insert:


INSERT INTO TABLE1 ( ID, NAME ) VALUES ( 1, 'first');
INSERT INTO TABLE1 ( ID, NAME ) VALUES ( 2, 'second');
INSERT INTO TABLE1 ( ID, NAME ) VALUES ( 3, 'third');
--------------------------------
INSERT INTO TABLE2 ( ID, TABLE1_ID, NAME, CREATE_DATE ) VALUES (
1, 1, 'kaakaa', TO_Date( '10/21/2008', 'MM/DD/YYYY'));
INSERT INTO TABLE2 ( ID, TABLE1_ID, NAME, CREATE_DATE ) VALUES (
2, 1, 'kookoo', TO_Date( '10/16/2008', 'MM/DD/YYYY'));
INSERT INTO TABLE2 ( ID, TABLE1_ID, NAME, CREATE_DATE ) VALUES (
3, 2, 'keekee', TO_Date( '10/30/2008', 'MM/DD/YYYY'));

Now for the interesting part. Here are two select statements:

Select *
From table1 Left Join
table2 On
(table2.Table1_ID = table1.ID and SysDate <= Create_Date)


Select *
From table1 Left Join
table2 On
(table2.Table1_ID = table1.ID and Create_Date >= SysDate)

The following can be noticed from the above 2 select statements:
  1. They are basically the same with the only difference of replacing
    SysDate <= Create_Date

    with
    Create_Date >= SysDate

  2. Left Join is used instead of a usual Inner Join. This would be used when we need to get all the records on the left table regardless of whether the Join Condition succeeds or fails, in case it fails then the values from the right table are null.
  3. The Join Condition (On) is a composite condition
Now the expected behavior is for both statements to return the same result set, yet that does not happen.
Results:

ID NAME    ID_1 TABLE_1_ID NAME_1 CREATE_DATE
-- ------- ---- ---------- ------ -----------
 1 first      1          1 kaakaa 10/21/2008
 1 first      2          1 kookoo 10/16/2008
 2 second     3          2 keekee 10/30/2008
 3 third
 4 rows selected

ID NAME    ID_1 TABLE_1_ID NAME_1 CREATE_DATE
-- ------- ---- ---------- ------ -----------
 2 second     3          2 keekee 10/30/2008
 1 first
 3 third
 3 rows selected
Now we can see how Outer Join Conditions (Left Join is implicitly an Outer Join) are not commutative in the sense that "a op b" is not the same as "b op' a" (where op' is the inverse operator of op). The expected behavior happens when "a" (Left Hand Side) is the column name. Also notice that using between for dates for example poses a similar problem where a condition like "sysdate between date1 and date2" is not the same as "date1 <= SysDate and date2 >= SysDate". To get the expected behavior we have to use the second condition.

kick it on DotNetKicks.com

Friday, October 10, 2008

NHibernation

And here is the new blog: nhibernation.blogspot.com.


kick it on DotNetKicks.com