Monday, December 22, 2008

Displaying Images from Database into an ASP:IMAGE control

Just recently, while working on a project, I stumbled upon a need to fetch images from the SQL Database and display them in the image control on the page.

I did a bit of research and landed upon a concept of using GENERIC HANDLERS for that purpose.

I found that really useful as compared to any other approach of saving the files to disk and setting the URLs etc.

Here is what can be done:

1. Add a new GENERIC HANDLER (ImageDisplay.ashx) to the project.
2. Set the ImageControl's ImageUrl to this ashx page..
imgDisplay.ImageUrl = "ImageDisplay.ashx?imageId=1";
where imageId is the Database ID of the image that needs to be fetched.
3. Now write code to fetch data from Database for that imageId in the ProcessRequest event of the ashx page.

public void ProcessRequest(HttpContext context)
{
Int32 imageId = Convert.ToInt32(context.Request.QueryString["imageId"]);

// This is the function that returns the Byte Array from the Database
Byte[] pict = GetImageById(imageId);
context.Response.ContentType = "image/bmp";
context.Response.OutputStream.Write(pict, 0, pict.Length);
}

4. The method GetImageById would depend upon the Database and data-type that you have for the column for image. Since I had a MySQL database with BLOB column, which can hold a Byte[], the method was quite simple for me and I just had to pull it out from Database and insert it into a Byte[] object.

-- Ashutosh

Monday, December 8, 2008

TabContainer cannot have children of type.....

Recently, I encountered the problem quite similiar to the one above.....
TabContainer cannot have children of type
'System.Web.UI.WebControls.Repeater'

to be precise...

I googled quite a bit for this error, but could not find much about it.. No wonders.. It was a careless mistake that I had made. Here is the control that caused this issue....

<cc1:tabcontainer id="tabToolbox" runat="server">
<cc1:tabpanel id="pnl" headertext="Most Popular">
<contenttemplate>
<asp:repeater id="rptMostPopular" runat="server">
<itemtemplate>
<asp:linkbutton id="lnkPopular" runat="server" text=""></asp:linkbutton>
</itemtemplate>
</asp:repeater>
</contenttemplate>
</cc1:tabpanel>
<cc1:tabpanel id="pnl2" headertext="Most Viewed">
<contenttemplate>
<asp:repeater id="rptMostViewed" runat="server">
<itemtemplate>
<asp:linkbutton id="lnkPopular" runat="server" text="">&jt;/asp:linkbutton>
</itemtemplate>
</asp:repeater>
</contenttemplate>
</cc1:tabpanel>
<cc1:tabpanel id="pnl3" headertext="Most Emailed">
<contenttemplate>
<asp:repeater id="rptMostEmailed" runat="server">
<itemtemplate>
<asp:linkbutton id="lnkPopular" runat="server" text=""></asp:linkbutton>
</itemtemplate>
</asp:repeater>
</contenttemplate>
</cc1:tabpanel>
</cc1:tabcontainer>

Well...... A very simple reason for getting this error, even on the designer and also at runtime..
I FORGOT THE TAG "RUNAT=SERVER" WHILE DESCRIBING THE TAB PANELS AND therefore could not get the tab-panels to be server side...

This is what raised the issue.

A simple addition of RUNAT=SERVER solves the issue...


Hope this would help someone in need... :)

--Ashutosh

Friday, December 5, 2008

Showing ModalPopUpExtender from Client Side

Just recently, I came across a situation where I needed to display a modal popup dialog box from my left navigation bar links.

Now the problem it had was all those links were actually Anchor (HREFs) and therefore they had a few problems in getting it to show the modal pop-up.

So here is how I finally got it done through Javascript...

This is the HREF that I created
<a href='' onclick='javascript:fncShowPopUp();return false;'>Edit Profile</a>
And here is what is required in the fncShowPopUp function:
function fncShowPopUp()
{
var popUpExtender = $find("ModalPopupExtender");
if(popUpExtender)
{
popUpExtender.show();
}
return false;
}

return false; is something that would actually stop the HREF from inducing a postback on the page, since if there is a post back, the Modal Popup would be hidden once again..

Njoy
-- Ashutosh

Thursday, November 20, 2008

Error handling with Global.asax and Update Panel

This morning while working with the Global.asax to handle my application level errors, I faced a very strange problem.

Despite of having a Error Handling routine in my Global.asax file, I was unable to trap an exception from the application and instead it was just throwing up a Message Box with the exception message.

So all my routine of logging the error and recording it into the DB was going without being executed.

After a fair bit of research, the UPDATEPANEL came out to be the culprit.

By its very design, UpdatePanels are designed not to bubble up the exception by default and thus it just pops up a Message Box and thus the Error handling routine in Global.asax was never called.

So to call this and feature a full post-back, we need to handle the AsyncPostBackError event of the Script Manager. Here is the code for that.
1. Add the following attribute to the Script Manager
OnAsyncPostBackError="scriptMan_AsyncPostBackError"
2. Create the event handler on the code behind
protected void scriptMan_AsyncPostBackError(object
sender, AsyncPostBackErrorEventArgs e)
{
MethodInfo preserveStackTrace =
typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance BindingFlags.NonPublic);
preserveStackTrace.Invoke(e.Exception, null);
throw e.Exception;
}

This would bubble up the event and Global.asax would be able to catch the exception thrown and here we could have our all cleanup routine for error trapping and recording.

-- Ashutosh

Wednesday, November 19, 2008

The row value(s) updated or deleted either do not make the row unique or they alter multiple rows.

This is not a common error to see in the context of today's world, but it is really annoying when it does come up.

This morning while working on a SQL Table, I got this error to come up when I inserted a new row to a table. It did not complain to me when I did an insert on that table, but when I tried to update a few values in that newly added row, it threw up this error.

After a further look down into the issue, I noticed that the table did not had a Primary Key and therefore it allowed me to enter the duplicate records.

Now using SQL Server Management Studio, when I tried to update that row, this error showed up.

Now the worst part, it would not even let you delete that row from the table, since it gets confused which row to delete as there are two rows with exactly same values in the DB.

So below are the two methods to get rid of such an issue.

1. Use "SET ROWCOUNT = 1" when deleting the row.
When you do a
DELETE FROM Table1 where Name = 'ABCD'

it will not work since there are two rows with the value of Name = 'ABCD'
So by simple doing
SET ROWCOUNT = 1
DELETE FROM Table1 where Name = 'ABCD'

it works as it now looks for the first row that matches the criteria and deletes that.

2. Adding an Identity Column
Another way of tackling this problem is adding a new temporary Identity column that would serve as Primary key and we could safely delete the row based on that PK.
ALTER TABLE Table1
ADD TempPKID INT IDENTITY(1, 1)

This will give seperate identity values to both the rows and thus one of them could be deleted by using this column in the where clause.

Friday, August 29, 2008

Component Container

Just recently, one of my collegues came up to me asking if I knew what a .NET developer MUST KNOW as per MSDN.... and fired me a simple straight question.....


WHAT IS A COMPONENT CONTAINER ??


Well the question was straight and simple, but certainly the answer was not. Not atleast for me.


So I quick fired MSDN and searched for the same.


Here is what it says:
The IContainer that contains the Component, if any, or nullNothingnullptra null
reference (Nothing in Visual Basic) if the Component is not encapsulated in an
IContainer.


Does not really a help for someone new to the concept. So I expanded my search to google. And off came quite a few results. Now uptill now, this is what I could understand and would CERTAINLY WELCOME OTHERS THOUGHTS ON IT

Monday, May 5, 2008

Javascript Rounding

Just discovered:

Math.Round() function in Javascript return only the nearest whole number for any values.

So Math.Round(4.366) = 4
and Math.Round(8.33345) = 8.

We had a problem where we also needed to have the number rounded upto 2 or 3 decimal places.

Here is a way of doing the same:

function RoundNumber(Number, decimal)
{
var orgNumber = Math.round(Number*(Math.pow(10,decimal)));
var result = orgNumber /(Math.pow(10,decimal));
return result;
}


-- Ashutosh

Monday, February 11, 2008

Google AJAX Search API

Hi,

While browsing through, I just stumblled upon what is known as Google AJAX Search API.

I was in seach of something where I could encorporate a google search right into my blog and which looks a touch different than the normal search page from google.

And I did well to land upon the Google AJAX Search API

It was quite simple and had enough tutorials and sample codes written for someone looking to encorporate a decent search into their site.

Take a look at the search box at the right bar on the blog. And try searching for something through it. It displays the results for each category as a seperate tab on the very same page.

Here is the way to encorporate the same in your blog.

1. Obtain a Google API Key. This is a kinda composite key for all the services of google that we would be using.

2. Integrate the API key code into your blog. OPen your blog and go to Edit HTML and in the head section of your blog, add the following script tag:
<script src='http://www.google.com/jsapi?key=developer_key'
type='text/javascript'/>

3. This will allow us to use all the services that google offers. Now we need to put up the code for displaying the search box. Here is the code for that.

<script type="'text/javascript'">
google.load("search", "1");

// Call this function when the page has been loaded

function initialize()
{

var searchControl = new google.search.SearchControl();

searchControl.addSearcher(new GwebSearch());

searchControl.addSearcher(new GvideoSearch());

searchControl.addSearcher(new GblogSearch());

searchControl.addSearcher(new GnewsSearch());

searchControl.addSearcher(new GimageSearch());

searchControl.addSearcher(new GbookSearch());

// create a drawOptions object

var drawOptions = new GdrawOptions();
// tell the searcher to draw itself in tabbed mode

drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED);
drawOptions.setSearchFormRoot(document.getElementById("searchPlaceHolder"));
searchControl.draw(document.getElementById("searchcontrol"), drawOptions);

}

google.setOnLoadCallback(initialize);
</script>




4. An explaination of this code is as below:
a. google.load("search", "1"); - This line of code prepares the search API from google and loads all the functions necessary to perfrom the search.

b. google.search.SearchControl();- This is the main control that displays the search results.

c. searchControl.addSearcher(new GwebSearch());- This is used to add various searchers to the control. Add as many searches as you like.

d. GdrawOptions();- A draawoptions object gives you the flexibility of customizing your search results display. The below two lines show the examples of its usage.

e. drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED); - This tells the search control how to display the search results. Here we have set it to display in the form of different tabs.

f. drawOptions.setSearchFormRoot(document.getElementById("searchPlaceHolder"));- This tells the search option the control to which the search box would be bind. I created a div with the ID searchPlaceHolder to hold my search box.

g. searchControl.draw(document.getElementById("searchcontrol"), drawOptions); - This is used to actually draw the search control with the appropriate draw options.

h.
Loading
- This provides us with an instance of a searchcontrol. Place it where you want the results to be displayed.


This way it would display a search box where you place the searchPlaceHolder control and would display the search results where you place the searchcontrol.


Hope this helps a lot of people like me ....

-- Ashutosh

Tuesday, January 8, 2008

Harbhajan Banned for 3 test matches.......

Yes this indeed is a technical blog but being a sentimental Indian, I could not stop myself from writing my own views of the story.

First of all, comments from a few commendable people:

  • "I am South African, and I understand the word racism. - Mike Proctor"
  • "They're entitled to do whatever they think is appropriate at the time but for me that would be a little bit extreme, I must admit. - Ricky Ponting"
  • "What to do? Calls for sackings are knee-jerk, the threat to abandon the tour nonsensical. Apart from anything else, the all-powerful television moguls here and in India would not countenance it. The tour will go on, and so will the captains. So law and order it must be. - Greg Baum (The AGE)"
  • "I saw the footage of what had happened involving Andrew Symonds when the
    Australians were in India. Most of the spectators were just having some light-hearted banter, and there was no malice in most cases. - Steve Waugh"
  • "Michael Clarke also had a dreadful match but he is a young man and has time to rethink his outlook. That his mind was in disarray could be told from his batting. In the first innings he offered no shot to a straight ball and in the second he remained at the crease after giving an easy catch to slip. On this evidence Clarke cannot be promoted to the vice-captaincy of his country. - Peter Roebuck"
  • There are times when you don't know. So, you ask the question. Every player has right to ask the umpire. I will say I don't appeal if I don't think they are out. If I am not sure, I will ask the umpire and I'll accept his decision. - Adam Gilchrist"

SO these are the view of certain people who are known to be experts of their own fields.
Well Mr. Mike Proctor just to let you know, We are the citizens of India and We really do not know what RACISM is. We never hear such words in our country because we never had views and culture as in SA our even Australia where people are discriminated on the basis of color.


And the statement from a reputed person from Australia "WHY SYMONDS ONLY !!" confirms the stand that they still have racism running through their blood. I mean had the same statement been made against Ponting or any white cricketer that would have not been a Racial comment but since it has been againsta Black, it is definitely the ONE..........

Regarding cancellation of the tour - As an Indian, yes I would most definitely like it to happen, but as an ardent cricket fan, I would most definitely like the tour to go on. Because the fight from here on would definitely be an interesting one becuase now it would most certainly not be a mere game of cricket but it would be a question of the national pride at stake.

As Greg Baum quoted - The television media that is presenting the live coverage all over the world is strong enough to make the tour continue. There would be a huge loss to the industry if it does not. After all we are talking of around 3 months of cricket going out of question.

And lastly, to comment on what Adam Gilchrist had to say on Rahul Dravid's dismissal, well Gilli your statement suggests that you were not confirm if that was out or not so you had put up a question to bucknor asking for his openion.

Well I would leave that to the readers to decide upon after having a look at the footage of the dismissal.


--Ashutosh