Wednesday, April 29, 2009

Something has happened!

Neopets alum will appreciate the title, everyone else, not so much. Anyway, let's just say you want to alert someone of some thing, some event or happening. It could happen within Page_Init, Page_Load, or some custom function you wrote, such as MyFatButton_Click(). This is all asp.net, in case there was any doubt.

In my situation, I'm working in an order entry system where people first add items, and later in the process, add payments of check, credit card, etc. There is nothing that prevents them from going back several steps and removing items after payments are applied (but not submitted yet). This results in a negative order balance which is generally undesirable, as we do not want to owe people money or have to refund money.

The fix was to simply remove payments on a negative order balance. This was regarded as acceptable by the client, and if it's good with them, it's good with me. But they also wanted to let the user know that something has happened, e.g., their payment was removed. Here's the code for that:

(inside page_init, page_load would have worked fine as well, as far as I know):

System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), "alertPaymentRemoved", string.Format("alert ('The payment(s) for this order have been removed.');"), true);

Some explanation might be helpful here. The ScriptManager allows you to inject some javascript at the time where it is useful to do so. The first argument, this, is a reference to the aspx page. Let me know if you have any questions.

Friday, April 24, 2009

Confirm alert box the e-z way

on your button or linkbutton, add the OnClientClick attribute with the following value:

OnClientClick="return confirm('Are you sure you want to delete this?');"
... />

Pretty easy, commonly requested, useful. There you go.

Thursday, April 23, 2009

Oh mother tell your children not to do what I have done

Don't do this: Have a panel that uses an ajax CollapsiblePanel from the Ajax Control Toolkit, hide it by default, and then put a textbox inside the panel, and then put a requiredfieldvalidator on the textbox, and Then: expect any of your buttons to work! The result is that when the page loads, none of your buttons will work because the validator's validatin', which is good, but you can't see the validator's error message because it's in your collapsed panel, which is bad.

Here's a little search engine fodder: Datalist linkbutton button not posting back.

Handy SQL script when creating sprocs

If you don't want to fuss with changing your stored procedure (sproc) script, specifically changing Create to Alter after the sproc has been created, use this handy snippet:


If exists(Select * from information_Schema.routines where specific_name = 'mySproc')
BEGIN
Drop proc [mySproc]
END
--(Create sproc script below)
--...


Change "mySproc" to the name of your sproc
This is especially nice when you've got a change script that just keeps growing and growing, and you don't want any interruptions when it comes time to run the script on a live environment.

Tuesday, April 21, 2009

What to do with a recently-migrated Access table that is now in your SQL database

The table in this case was a user info table called UserInfo, appropriately. I am using asp.net Membership, as well as a new table analogous to the UserInfo table, but with improvements (atomic storage of data, constraints, etc.) so I needed to create an entry in membership using the old table's email and password, and then create a corresponding entry in my user table using pretty much everything from the old table.

First, I needed to remove all of the superfluous duplicates, as email was to become a unique identifier in my new table (and act as the username in my Membership tables). These guys helped me out. They look like some good blokes. Anyway, I just wanted to delete the top 1 record in all the instances where there were 2 or more records containing the same email. My script looked like this:

DELETE TOP (1) FROM USERS
WHERE EMAIL IN
(
SELECT EMAIL FROM USERINFO
GROUP BY EMAIL
HAVING COUNT(EMAIL) > 1
)

The good thing about this script is also its flaw. It will only delete one record at a time where the email exists more than once, ensuring that you don't delete both of the records (you want to keep one!). Fortunately, there were only about 120 duplicates, and my simple and farily quick and effective solution was to just press "f5" 120 times. Done! I didn't want to mess with cursors when I can just monkey-push the button like I'm playing Track-n-Field at the local nickel arcade.

How would you have done this more elegantly?

Next, how to move data from one table to another table the E-Z way (or not).

How to migrate an MS Access table into a SQL Server 2005 database

With a little help from Google, I found a free tool that Microsoft makes and for my purposes, it worked ok. It is the SQL Server Migration Assistant 2005 for Access V4.0. Note that this requires you to get a "license". It's free also and I'm not sure why they do this, but so be it.

I had hoped this tool would move the data from an access table directly into a corresponding table in SQL Server. It did not do this. This is probably a simple case of user ignorance and I'm sure this tool is far more powerful than I understand. What this tool did instead is just copy the access table directly into the SQL database as a new table. Well, this certainly makes the table easier to work with if it's in the same database, so I was very happy to achieve this step, and so easily! I understand that Access has a migration tool, but I wasn't having a whole lot of luck with it.

Once the table was in my SQL database, that's when the fun began. What I did there is worthy of its own post.

Thursday, April 16, 2009

Bug #1234

In our web-based system, customers are not allowed to use post office boxes. We would check this with our "bulletproof" regular expression. Bulletproof means we haven't had any complaints. Until we did. Something along the lines of "Incident XXXX: Customer who lives on Post Office Road can't update her address information".

We ended up doing a special code-behind check specifically for this customer's address. Elegant? Nah. Hackish? The very essence of what a hack is. Did it work? Great! No problems reported since, and it's been months since this was implemented.