Monday, November 9, 2009

Free .Net Profiler

I got link for free (as in beer) .Net profiler from eqatec.
It works with many languages:

LanguageVersionPlatform
C#
VB.NET
Managed C++
F#
C or C++
Java
.NET 3.5
.NET 3.0
.NET 2.0
.NET CF 3.5
.NET CF 2.0
.NET 1.1
WinXP, Vista
Windows Mobile
Windows CE
XP embedded
PocketPC, PDA
Linux

Tuesday, October 13, 2009

I got Google Wave Invite!!!

Wow, I got invitation for Google Wave.

Googlewave
preview
Thank you for signing up to give us early feedback on Google Wave. We're happy to give you access to Google Wave and are enlisting your help to improve the product.


can't wait to have a look. Will sure my experiences. Keep watching.....!

Dealing with TimeStamp columns with SubSonic 3 and MS Sql Server

Today someone asked a question at StackOverflow
regarding problem with SubSonic, not allowing to update record in table with "TimeStamp" typed column. I've been SS enthusiastic since long. I was quick to reply:

You don't need to worry about this. SubSonic is intelligent enough to handle this! Just create new object and assign values to properties and save it.
I then created a table to test it and it worked like charm.




User commented back that he is not able to make it work. It then occurred to me that he might be using SubSonic 3. I tested with SS3 and he was right there was something funny. I got following error:



What is this? SubSonic failed to take into account that a TimeStamp datatyped column should not be explicitly set in Insert or Update statements.

I fired .Net Reflector and opened SubSonic.Core.dll. It took me to the following method in SubSonic.Extensions.Database class:
public static ISqlQuery ToInsertQuery(this T item, IDataProvider provider) where T: class, new()
{
    Type type = typeof(T);

    ITable tbl = provider.FindOrCreateTable();

    Insert query = null;

    if (tbl != null)
    {
        Dictionary hashed = item.ToDictionary();

        query = new Insert(provider).Into(tbl);

        foreach (string key in hashed.Keys)
        {
            IColumn col = tbl.GetColumn(key);

            if ((col != null) && !(col.AutoIncrement || col.IsReadOnly))
            {
                query.Value(col.QualifiedName, hashed[key], col.DataType);
            }
        }
    }
    return query;

As you can see in this line:

It was checking if column was null or auto-increment, and was omitting it from column list for query. By default TimeStamp typed column should be readonly. But even if it was readonly the line above is not checking for ReadOnly property. I also tried to set it to null but it did not work.

I went to GitHub and forked subsonic source code. I was sure putting another check in if statement above will work:

if ((column != null) && !column.AutoIncrement && !column.IsReadOnly)

But when I opened the code the above method read something like this:
public static ISqlQuery ToInsertQuery(this T item, IDataProvider provider) where T : class, new()
{
    Type type = typeof(T);
    ITable tbl = provider.FindOrCreateTable();
    Insert query = null;
    if(tbl != null)
    {
        var hashed = item.ToDictionary();

        query = new Insert(provider).Into(tbl);

        foreach(string key in hashed.Keys)
        {
            IColumn col = tbl.GetColumn(key);
            if(col != null)
            {
                if(!col.AutoIncrement && !col.IsReadOnly)
                    query.Value(col.QualifiedName, hashed[key], col.DataType);
            }
        }
    }
    return query;
}
Hmm, the problem is already sorted out. The questioner is also using dll from some old build. I compiled, added reference and re-ran the test code. No luck. It confronted me with same error. I put break point at save statement to delve deeper. The column was never set as ReadOnly :(

I scourged the generated code and saw what it generated for TestTimeStamp table. It read:

public class TestTimeStampTable: DatabaseTable {
    public TestTimeStampTable(IDataProvider provider):base("TestTimeStamp",provider){
    ClassName = "TestTimeStamp";
    SchemaName = "dbo";
    ………………
    ………………

    Columns.Add(new DatabaseColumn("RowVersion", this)
    {
        IsPrimaryKey = false,
        DataType = DbType.Binary,
        IsNullable = false,
        AutoIncrement = false,
        IsForeignKey = false
    });
}

So problem was somewhere here! When creating column, SS was not putting if the column is readonly or not. I checked structs.tt T4 template.

It has following code:
<# foreach(var col in tbl.Columns){#>
    Columns.Add(new DatabaseColumn("<#=col.Name#>", this) {
         IsPrimaryKey = <#=col.IsPK.ToString().ToLower()#>,
         DataType = DbType.<#=col.DbType.ToString()#>,
         IsNullable = <#=col.IsNullable.ToString().ToLower()#>,
         AutoIncrement = <#=col.AutoIncrement.ToString().ToLower()#>,
         IsForeignKey = <#=col.IsForeignKey.ToString().ToLower()#>
    });

<# }#>

It is not even bothering to check if column is readonly or not :( I put following line after IsForeignKey line:
IsReadOnly = <#=col.DataType.ToLower().Equals("timestamp").ToString().ToLower() #>

On saving the file the code was regenerated. TestTimeStamp class now read:

Columns.Add(new DatabaseColumn("RowVersion", this) {
    IsPrimaryKey = false,
    DataType = DbType.Binary,
    IsNullable = false,
    AutoIncrement = false,
    IsForeignKey = false,
    IsReadOnly = true
});

I tried my luck again. It ran without any error. I ran it again, opened SQL Server Management Studio and executed SQL Query:

Select * From TestTimeStamp

Now it returned:

RowIDRowDescriptionRowVersion
---------------------------------------------------------
1Hello world!0x00000000000007D1
2Hello world, Again!0x00000000000007D2
(2 row(s) affected)
Happy Coding!

Friday, October 17, 2008

Showing HTML Content over Flash Movie - quick and dirty way!

I had faced a nasty problem few days ago. I was to show user a modal-popup (in html page) for Terms and Conditions for registration on a site. Popup was coming okay, but There was a flash movie at top of the page which was hidding upper portion of the dialog. The tested and widely used method is to put an Iframe at place where you want to show your content and absolute position your content and IFrame. For example, if you want to show a div above a flash movie, then place a IFrame like follows:
        <iframe style="position:absolute;top:250;left:150;"></iframe>
Then position the div exactly above this iframe like:
        <div style="position:absolute;top:250;left:150;"></div>

I was using jquery on the page to show dialog using ui.dialog plugin.
After fooling around sometime I devised following simple solution.

1)  put id attribute on movie element to uniquely identify the movie object. Like,
<object id="movie1"></object>
2)  before showing the dialog (or other content for that matter) call a javascript function to hide the movie. Like,
$("#movie1").css("display","none");

3)  now show dialog. Like,
$("#dialog").dialog("open");

4)  after closing the dialog, show the movie again. Like,
     $("#dialog").dialog("close");
$("#movie1").css("display","inline"); 

that's all folks, Happy Coding

Monday, January 28, 2008

Working with Anthem.NET and AJAXControlToolkit CalendarExtender

I've wasted almost complete day to debug what now seems very trivial. I'm using Anthem.NET in my project. I almost exclusively use Anthem.NET in my ASP.Net applications for AJAX. Almost because I've to rely on AjaxControlToolkit for some capabilities, like Calendar and ListSearchExtender.
I'm using Anthem ListBox box, and some textboxes on a page. Listbox generates a callback and textboxes are populated async'ly. One of the textboxes is for date input. I've used CalendarExtender control to show dropdown (I just love it for this thing) calendar. When page first loads calendar shows nicely, but as soon as callback is generated, it stops working.
After looking at generated page, I found code responsible for creating client side calendar. It is this one:
Sys.Application.add_init(function() {
$create(AjaxControlToolkit.CalendarBehavior, {"format":"dd/MMM/yyyy","id":"MyCal"}, null, null, $get("ctl00_ContentPlaceHolder1_txtPurchaseDate"));


So, it seemed very simple register a PostCallback function for ListBox, with $create method in it, to recreate calendar everytime a callback occured.

So far so good, but it cropped up control with duplicate id problem. I tried $dispose method from ajax.net library, but it told me that element I'm looking for is unavailable. Then I tried prototype to remove the said element from the DOM tree, but it was also not able to find element.

Then after googling many times for many things (in the meantime reading scripts in AjaxControlToolkit source code, using reflector to go through System.Web.Extensions.dll and using firebug extensively) I got to Ajax.NET reference on asp.net (now, don't laugh at me that it is not in my delicious, as I've been relying mostly on Anthem.NET).

There I found the whole story at page for Sys class [here]. I used $find method to get my element and used removeComponent to remove previous instance before creating new one.
Sys.Application.removeComponent($find("MyCal"));

Thursday, October 11, 2007

Setting focus to control in Asp.NET 2

I'm building a website (as i told in my previous post). In one form i used wizard control. The problem was that the form is in master page, which itself contains navigation bar as header of the site. When page loaded, the control will go to links and controls on the master form first and then to controls in this form.

I googled and found nice snippets of Javascript and even a control class on codeproject. But I tried to go the easier way first. So in page_load event I tried like dropdownlist1.Focus() and voila it worked.

Next was to see on which step the wizard is, which I was already doing to validate the inputs from user, and set the focus to first control on next page of wizard.

There was a postback also, where a dropdown list changes and loads another one. In postback handler (dropdownlist2_selectedindexchanged) at the end, I wrote dropdownlist3.Focus() and it was working here too.

Hope it helps you.

Saturday, October 6, 2007

Another reason for "Failed to Update Database ..\App_Data\aspnet.mdf because database is readonly

I am currently working on ASP.NET 2 project. After working for 2 days and creating an outline for the site and flow for user interaction, I decided it was right time to put it into source control.

After I added it to source control it started giving me giving strange "database is read-only problem". I googled a bit about it. The solutions offered ranged from giving IIS process, ASPNET user and don't remember who else to give access to app_data folder. But it did not work.

Then there was an elaborate solution using command line sseutil . It recommended to detach the database and reattach it. After some futile attempts, I had to close VS, and restart Sql Express.

Again today some how I checked in all the files in solution and it again gave gave me same problem when I tried to create a Stored Procedure. Then occurred to me that maybe it is because the database file is checked in source control and is read-only (it was checked in). I detached it (with sseutil of course), checked out the file (aspnet.mdf) and it is working again alright.