Tuesday, July 22, 2008

Time Ago in Words for .NET C#

I saw the need for a C# version of the time_ago_in_words function in Ruby. I translated the code below into C# from my existing post I published for Ruby.





static string TimeAgo(DateTime time)
{
DateTime startDate = DateTime.Now;
TimeSpan deltaMinutes = startDate.Subtract(time);
string distance = string.Empty;
if (deltaMinutes.TotalMinutes <= (8724 * 60))
{
distance = DistanceOfTimeInWords(deltaMinutes.TotalMinutes);
if (deltaMinutes.Minutes < 0)
{
return distance + " from now";
}
else
{
return distance + " ago";
}
}
else
{
return "on " + time.ToString();
}
}


static string DistanceOfTimeInWords(double minutes)
{
if (minutes < 1)
{
return "less than a minute";
}
else if (minutes < 50)
{
return minutes.ToString() + " minutes";
}
else if (minutes < 90)
{
return "about one hour";
}
else if (minutes < 1080)
{
return Math.Round(new decimal((minutes / 60))).ToString() + " hours";
}
else if (minutes < 1440)
{
return "one day";
}
else if (minutes < 2880)
{
return "about one day";
}
else
{
return Math.Round(new decimal((minutes / 1440))).ToString() + " days";
}
}




You can download the complete source here: http://www.box.net/shared/3fmhllxq8g

Tuesday, July 08, 2008

Hide Submit button to prevent double click using JavaScript in .NET

Here is snippet of JavaScript to hide the submit button to prevent users from double-clicking on the button multiple times causing several server requests.

What I like to do is hide the submit button and show a message to notify the user that the action is in progress.


This is my front-end code. I have an image button that OnClick is submits an order.

<asp:ImageButton ID="btnPlaceOrder" runat="server" Visible="False" OnClick="btnPlaceOrder_Click" />
<div id="process_message" style="display:none;">
<p> Processing your order...</p>
</div>




The code-behind looks like this:




btnPlaceOrder.Attributes.Add("onclick", "this.disabled = true;this.hide(); $('process_message').show();" + ClientScript.GetPostBackEventReference(btnPlaceOrder, null) + ";");


Monday, June 30, 2008

Flash unable to request swf files from another subdomain within the same web server.

Flash unable to request swf files from another sub-domain within the same web server.

I just experienced an issue with flash loading other swf files in the same web server but requesting from another sub-domain.
For example:
http://www.mywebsite.com/flash/shell.swf is requesting http://mywebsite.com/flash/game.swf

The crossdomain.xml is not issue. This is configured to allow * all access.
The website path is provided to shell.swf via a param. If I change the param to provide “http://www.mywebsite.com” it will work when the user is using www.mywebsite.com. This is very weir because everything is stored in the same location is just an issue with host headers.
I solved this issue my simply providing the current url host header to the shell.swf via the param.

So if the user is using “www” I will use www.mywebsite.com. If the user is using “origin.mywebsite.com”, then flash will use origin.mywebsite.com.
I am not sure 100% why flash is unable to request files from other sub-domains. But this was the quickest solution to this problem.

Friday, June 27, 2008

Strip numbers from String : C# .NET Remove numbers from string

Here is a simple function I created to strip/remove numbers from a string.
I used the regular expressions to check if a char is number.
I choose to use regular expressions than using the Double.TryParse() because I feel RegEx are faster then the TryParse function. I could be wrong but at this point is doing the job.





public string StripNumbers(string input)
{
Regex regEx = new Regex("[0-9]+");
StringBuilder sb = new StringBuilder();
foreach (char a in input)
{
if (!regEx.IsMatch(a.ToString()))
{
sb.Append(a);
}
}

return sb.ToString();
}




The next steps will be to test performance and find out what method is faster to check for IsNumber().

Wednesday, June 25, 2008

The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)

In .Net this exception occurs when using the TransactionScope.


using (TransactionScope ts = new TransactionScope())
{

}


Follow this instructions on all database servers and web servers to configure properly the MSDTC service.

First verify the "Distribute Transaction Coordinator" Service is
running on both database server computer and client computers
1. Go to "Administrative Tools > Services"
2. Turn on the "Distribute Transaction Coordinator" Service if it is not running

If it is running and client application is not on the same computer as
the database server, on the computer running database server
1. Go to "Administrative Tools > Component Services"
2. On the left navigation tree, go to "Component Services > Computers
> My Computer" (you may need to double click and wait as some nodes
need time to expand)
3. Right click on "My Computer", select "Properties"
4. Select "MSDTC" tab
5. Click "Security Configuration"
6. Make sure you check "Network DTC Access", "Allow Remote Client",
"Allow Inbound/Outbound", "Enable TIP" (Not required if the client machine and remote machines are in the same domain)
7. The MSDTC service will restart.

On the client computer use the same above procedure to open the
"Security Configuration" setting, make sure you check "Network DTC
Access", "Allow Inbound/Outbound" option, restart service and computer
if necessary.

On the SQL server service manager, click "Service" dropdown, select
"Distribute Transaction Coordinator", it should be also running on
the SQL server computer.


Is this does not solve the issue, check the web server to ensure if DTC is enable.
1) Go To Control Panel
2) Add Remove Programs -> Add/Remove Windows Components
4) Select the Application Server and Click on the Details button
5) Ensure that Enable DTC Service is selected.



Additional Reading about MSDTC here:

http://en.wikipedia.org/wiki/Distributed_Transaction_Coordinator

http://msdn.microsoft.com/en-us/library/ms684146.aspx

Monday, June 23, 2008

C# Get Person Age In Years By Birth Date ( DOB )

Here is quick method for C# to get the age of a person given the birth date.




public int GetAge(DateTime dob)
{
// Get year diff
int years = DateTime.Now.Year - dob.Year;
// Add year diff to birth day
dob = dob.AddYears(years);

// Subtract another year if its one day before the birth day
if (DateTime.Today.CompareTo(dob) < 0) { years--; }

return years;
}



Friday, June 20, 2008

ASP.NET LinkButton does not work in FireFox as the DefaultButton

I recently discover that LinkButtons do not work in FireFox as the form's default button to trigger the form submit on the Enter keystroke.

I tried doing this:

this.Form.DefaultButton = this.lbtnLogin.UniqueID;

And no luck.
I also tried
and this also did not work.

But here is more info to solve this issue.
I worked around by making my button and ImageButton instead of a LinkButton.


http://kpumuk.info/asp-net/using-panel-defaultbutton-property-with-linkbutton-control-in-asp-net

Friday, June 13, 2008

Bookmarking with Flash and Javascript

Bookmarking using Flash

To bookmark a page from a Flash call, flash needs to call an external JavaScript function in your page to actually do the bookmarking any browser.

But here is the trick....

In order for the bookmarking prompt window for example in IE to show up the focus needs to be outside the flash object. So you need to set a focus to a DOM element outside flash.

Here is an example script that works.
function bookMarkPage(url, title) {
// set focus to a DOM element, otherwise it won't work.
$('flash_container').focus();

switch(BrowserDetect.browser){
case "Firefox":
window.location.hash = url;//set the hash value
alert("Please press 'Ctrl + D' to bookmark this page.");
break;

case "Explorer":
window.external.AddFavorite(url, title);
break;

case "Safari":
alert("Please press 'Ctrl + D' to bookmark this page.");
break;

case "Opera":
// Create document element dynamic and invoke
var bookMark = document.createElement('a');
bookMark.setAttribute('rel','sidebar');
bookMark.setAttribute('href',url);
bookMark.setAttribute('title',title);
bookMark.click();
break;

default:
alert("Please bookmark this page manually.");
break;
}
}


Thursday, June 12, 2008

The problem with video captions today?

What’s the problem with adding closed-captions to online videos up until today?

As I dig more into the online video closed-captioning market and get more convince that TubeCaption.com has the yet the best web editor for adding captions to your captions.

You see the #1 problem with the websites today such as Google Video Captioning, dotSub.com, YouTube.com, veoTag, and many others is that they force the user to use minutes and seconds. The user does not want to remember or even set the start and end time for the captions. That’s too painful. I have tried it and I hate it! Adding captions should be more simplified and super easy to use. Everyone knows that adding captions is not as easy as it looks. So, that’s why you have to provide the best out of the web for these users. Features like, copy and paste, resizing, drag and drop, delete, etc are small features that makes the user experience a much better one.

This is why I am very passionate about TubeCaption.com. On top of rewarding the users that provide the captions with money (cash $), we are trying to make a better and a more pleasant experience when it comes to adding captions (closed-captions) to their favorite videos. Try the caption editor here to start playing with the “captionizer” and add captions in seconds.

Video captions will take video viewing, searching, and of course the advertising to another level. This is the next step to online video viewing. The users will be able to find exactly what they are looking for just by simply entering short keywords that are found somewhere in a video with captions.

Oh, I am forgetting, TubeCaption.com is 100% free and will always be. Every can add captions, comments, transcripts, and etc to any online video. At this point only YouTube.com is supported but with good response from the public we will be able to add support to other video providers.

Give it a try and let us know what you think.


Tuesday, June 10, 2008

IIS Error: You have attempted to execute a CGI, ISAPI..

I setup a new asp.net 2.0 application under IIS web service and I come across this error:

The page cannot be displayed
You have attempted to execute a CGI, ISAPI, or other executable program from a directory that does not allow programs to be executed.


When you get this error it usually means that you have not set execute permissions to "Scripts only" under the "home directory" tab in your website properties. When creating a new website the value for execute permission is set to "none". Changing to "Scripts only" will solve this problem.

Friday, June 06, 2008

Amazon website down??

Just when to amazon.com and to find out that there website is down.

Why?


Thursday, June 05, 2008

TubeCaption.com Videos with Closed Captions

It’s been a very good journey working on my latest website TubeCaption.com.
I started this experiment site with my friend Alex Le. I took on this challenge primary to learn something else other than .NET. Yes, I started to learn ruby on rails. We started this project 2 months ago to be exact. Our dedication was just part-time since we both have real jobs. However, the project got more and more interesting (actually a lot more fun than work) that we spend more and more time on in and in 3 occasions we coded through the night. No we are so happy that we can at least provide a beta version out in the web so that users can start experimenting with TubeCaption.com.

I learned a lot working with Alex as a team. We both worked remotely and we did pear to pear programming in our laptops over IM.
Early in the game I had the opportunity to chat with Rohit Kumar, new CIO for the Chicago Sun-times newspaper (http://www.topix.com/com/hlr/2008/02/rohit-kumar-named-stmgs-new-cio) at an i.cstars event. Rohit and I had a great chat about online video broadcasting and advertising. Up to today videos are only searchable by the title and the description. Some companies are trying tagging the videos with keywords so that searches and ads are more targeted and related to the video content. But with TubeCaption.com you can take this to the next level. Our videos are not just searchable by the title, description, and tags but also by the entire video content. One of my first videos I added captions was a music video by 3 Doors Down (Without you). Two (2) minutes after my captions were published the ads next to the video were about 3 Doors down music rings. Then I experiment with the movie trailer from Iron Man and same thing. A minute later the ads next to the video displayed a video ad for the new Hulk movie. How cool is that?
I believe TubeCaption.com has lots of potential.

I am personally going to use it to record my own videos, upload them to YouTube, and add captions to provide teaching and how to for the i.cstars community of interns and alumni.
What’s great about TubeCaption?
One nice feature about our site is that we share the revenue with you!
Once you have created an account us, you can link your Google Adsense account and we will display Google ads using your account when your video captions are displayed, about 50% of the time. In the near future will ad support for additional advertising providers.
Well, that’s if for my starter. I have plenty to say but I got to keep in short for today.
Thanks for reading and make sure to visit TubeCaption.com

Monday, June 02, 2008

ruby on rails: will_paginate anchor param

Recently I discover that I can add an anchor to the will_paginate helper for the will_paginate plugin in rails.

This will create the url as "path/?page=2#myanchor".




<%= will_paginate @videos, :params => {:anchor => "myanchor" }%>


Wednesday, May 28, 2008

IIS 5.1 Server Application Unavailable Error

I get this error sometimes when I change the default application in IIS.
When trying to browse my default.aspx page I get the big red font error "Server Application Unavailable".

I fix this issue by executing the following commands:
1) Give modify access to the "IIS_WPG"and "Internet Guest Account" users to your web directory. Try see if that works, if not continue with step2.


Photobucket

2) aspnet_regiis -i
3) iisreset

Microsoft Instructions:
To fix IIS mappings for ASP.NET, run the aspnet_regiis.exe utility:
1. Click Start, and then click Run.
2. In the Open text box, type cmd, and then press ENTER.
3. At the command prompt, type the following, and then press ENTER:
"%windir%\Microsoft.NET\Framework\version\aspnet_regiis.exe" -i
In this path, version represents the version number of the .NET Framework that you installed on your server. You must replace this placeholder with the actual version number when you type the command.

Then,

1. Click Start, and then click Run.
2. In the Open text box, type iisreset.

Done! Go check out your site it should be up and running.

Ruby: Display datetime - time in words - timeago helper function.

I found this function on the web and putted right into my helper class to display DateTime or Time into words. Displaying time in words is now more used on the web. Popular pages such as YouTube and Yahoo videos use this approach.

Copy the code and plugged into your helper class.




def timeago(time, options = {})
start_date = options.delete(:start_date) || Time.new
date_format = options.delete(:date_format) || :default
delta_minutes = (start_date.to_i - time.to_i).floor / 60
if delta_minutes.abs <= (8724*60)
distance = distance_of_time_in_words(delta_minutes)
if delta_minutes < 0
return "#{distance} from now"
else
return "#{distance} ago"
end
else
return "on #{DateTime.now.to_formatted_s(date_format)}"
end
end
def distance_of_time_in_words(minutes)
case
when minutes < 1
"less than a minute"
when minutes < 50
pluralize(minutes, "minute")
when minutes < 90
"about one hour"
when minutes < 1080
"#{(minutes / 60).round} hours"
when minutes < 1440
"one day"
when minutes < 2880
"about one day"
else
"#{(minutes / 1440).round} days"
end
end

Tuesday, May 27, 2008

Ruby: Format seconds into minutes to_minutes function

I created this function to turn seconds into minutes.
Example: 500 seconds should be displayed as 8:00 minutes.




def to_minutes(seconds)

m = (seconds/60).floor
s = (seconds - (m * 60)).round

# add leading zero to one-digit minute
if m < 10
m = "0#{m}"
end
# add leading zero to one-digit second
if s < 10
s = "0#{s}"
end
# return formatted time
return "#{m}:#{s}"
end


Tuesday, March 25, 2008

IE caches IFrame pages. Page load does not fire in IFrame page.

I had this issue on a project that I was working on. I created an IFrame to load a page in a modal window. On the close of the modal window I will close the frame, and then when the user clicks on a button to open the window I will recreate the frame with the same url to load the page. This worked fine with FireFox. On every load of the modal window I the Page_Load event will fire, however, with IE this was not the case. I solve the problem by creating a unique request every time setting a parameter with a random number in the source of the IFrame.


Iframe.src="MyPage.aspx?unique="+ Math.random();

Thursday, March 20, 2008

Aivea eShop Shopping Cart is NOT Enterprise Ready (Review)

After looking for e-commerce solution for my store shopping cart I made the decision to go with Aivea eShop product. Their website ‘professional’ looking was what convinced me to buy it. However, when I downloaded the product with the source code I was shock. I have work in “Enterprise wide” applications and the eShop source code is not enterprise ready as they claim in their website.

These are my disappointment factors:

  • Source code uses Hungarian notation.

  • In store front website source code they persists almost every value in the session in the session.

  • They don’t use strong typed entities. I only noticed 3 or 4 object to used to get data

  • Heavy used of data sets instead of objects

  • Not a flexible architecture. Business rules and data access is all in the App_Code folder. If you have more than one interface that needs to access the shopping cart to process order or retrieve order orders you can’t accomplish it without serious re-factoring and extracting the source code to reusable components.


I am sure I can find other reasons but I will stop here. This was the reason I decided not to use it in my application. Towards the end of the project I was so happy that I did not use this out of the shelf solution that encouraged me to write this article.



I am not writing this post to drive off their business, but to express my believe and make them be aware of what a user is thinking about their product. By the way the version that I used was 2.5+.



You can find more reviews here at
http://www.411asp.net/func/review?id=6449910&rid=&proc=anony

Tuesday, March 18, 2008

DetailsView Edit Mode never changes after Update command. DetailsView Edit button requires to clicks to change to edit mode.

I was stocked for sometime using the asp.net 2.0 DetailsView control to Edit/Update data. I wanted to do my custom implementation for the Update command instead of using the DataBinding Object sources but I found my self in trouble with several road blocks.

Problem 1:
When clicking on the Edit button the DetailsView will not change the mode until the second click. The edit button required two clicks to change the mode to Edit instead of ReadOnly.
I solved this problem by changing the mode in the ModeChanging event handler and then rebinding the DetailsView control.


ModeChanging Event Handler:

protected void dvOrder_ModeChanging(object sender, DetailsViewModeEventArgs e)
{
dvOrders.ChangeMode(e.NewMode);

if (e.NewMode != DetailsViewMode.Insert)
{
RefreshOrderDetails();
}
}




Problem 2:
When clicking the update button I handle the updating of the order in the ItemUpdating event but the ItemUpdated never fires and the DetailsView never change the mode to ReadOnly after the data was updated. DetailsView control always stayed on the Edit Mode.


I solve this problem by canceling the ItemUpdating event, changing the mode, and rebinding the details view data source.


ItemUpdating Event Handler:

protected void dvOrder_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{

UpdateOrder();

e.Cancel = true;

dvOrders.ChangeMode(DetailsViewMode.ReadOnly);

RefreshOrderDetails();
}



This was the only way I got things to worked for me. The ItemUpdated event never fired but I got the DetailsView to works how I wanted. I wish there was an easier way to do this or at least more documentation on Microsoft’s website.

Tuesday, March 11, 2008

IE Autocomplete Dropdown wrong location in Modal/Dialog window ASP.NET 2.0

I recently discover that if the AutoCompleteType attribute is not specify explicitly in the input control IE will display the autocomplete options dropdown in offset location in modal/dialog windows.

This is not the case if you are using Yahoo's tool bar or Google's auto fill feature in its tool bar, but IE is more stupid.

I fixed this issue my explicitly settings the AutoCompleteType attribute in the Textbox control.

Example textbox for first name field.


<asp:TextBox ID="txtFirstName" CssClass="input" runat="server" AutoCompleteType="firstname"></asp:TextBox>




By setting the AutoCompleteType attribute the problem was corrected.