Wednesday, July 27, 2005

Thomas Hinds Tobacconist

Finally, the tobacco store is launched, here's the official Thomas Hinds Tobacconist's website. I sometimes do php work for friends, like this Tobacco Store that is based in downtown Toronto. They have the best Cuban cigars in the market, guaranteed :)
Thanks to the Zen Cart team for their wonderfull support, special thanks to QDixon, yes I owe you a box with Robustos. Thanks to Luifo for the terrific 3D tour, Idania for the nice design and the crew at Thomas Hinds for the help and support.
I hope you step in and enjoy the visit.

Thursday, July 21, 2005

Ajax, a gal can dream.

There's a lot of buzz lately on Ajax and the new web experience. Coming from a windows programming enviroment I, like almost any other programmer, found web interfaces quite orthopedic, let alone to compare them with 3D games.
Today I found one of the best blogs on Ajax, and in particular this article about the drawbacks and gotchas of making a fully async web site (see the article here)
My goal for web user interfaces, remember Minority Report? Where Detective John Anderton plays with its highly rich UI to display videos of the precog's dreams? Hopefully we won't have to wait till 2054 to have these UIs implemented
Oh well, a gal can dream...

Today, no techie stuff. Promised

I'm beginning to get quite fond of blogging, it somehow helps me to remember what I did a week ago or on what I spent/(wasted?) my time.
So...
Dear Diary:
Last Thursday evening I spent most of my time talking of books with my friend, Eric (there's no url here cause Eric has his server down at the moment), the conversation didn't start right on the books thing, but as good friends we are, we let out minds wander from one subject to another and ended up talking about books and the characters we miss the most, after closing the last page.
Eric's favorite character was a warrior of a fantasy book, I'll post the link as soon as I find the book at amazon.
Probably Obscured by Code's blogger already knows all this, as we've read more or less the same books, my favorite characters, they happen to be females most of them in order of reading:
  • Lady Jesssica, Paul's mother on Dune, the reason, all her Bene Gesserit knowledge.
  • Ellie Arroway, in Contact (the book, not the movie), the reason I liked the character, she was fond to playing with signals, white noise, math transforms and why not, if anyone ever talks about Fourier series, my sympathy is taken, for granted.
  • Arianne Emory, in Cyteen, the original Ari, not the clone, the reason, well, it's hard to tell, she highly qulaified as "evil witch" but somehow her work and dedication outlived her.
  • Lysis de Mileto on "The eye of Dyndimenio", no link at amazon.
  • Ok now, three male characters I have had a crush on, Aragorn, but what girl wouldn't fall in love with him, Paul's father in Dune and the lonely Case in Neuromancer.

Tuesday, July 19, 2005

Calling a SPROC gotcha

I dunno if I mentioned before that I changed some of the SPROCs in the company databases to accept multiple cultures (this is, retrieve values in multiple languages from the new tables). The main problem is that the company already has more than 10 applications working with those same databases, so the new changes in the SPROCs had to run smoothly without breaking any other application.
I became paranoid, heh, well, close to it.
To day I was veryfying one of the oldest web apps and noticed that one of the dropdownlists that gets the data from the SPROC Q_Regions was blank, gosh!
I promptly opened my Query Analyzer to try figure out what was going on and run this two scripts:

DECLARE @RC int
DECLARE @regionlist varchar(100)
DECLARE @minlevel int
DECLARE @maxlevel int
DECLARE @sitelist varchar(25)
DECLARE @industry char(1)
DECLARE @culture char(5)
-- Set parameter values
EXEC @RC = [IRONSearch].[dbo].[Q_Regions] @regionlist, @minlevel, @maxlevel, @sitelist, @industry, @culture



and the script setting the params:

DECLARE @RC int
DECLARE @regionlist varchar(100)
DECLARE @minlevel int
DECLARE @maxlevel int
DECLARE @sitelist varchar(25)
DECLARE @industry char(1)
DECLARE @culture char(5)
-- Set parameter values
set @minlevel=10
set @maxlevel=30
set @sitelist='1'
set @culture='en-US'


EXEC @RC = [IRONsearch].[dbo].[Q_Regions] @regionlist, @minlevel, @maxlevel, @sitelist, @industry, @culture

I was expenting the same results. The SPROC has default values that should be used if the parameter is null...

The results differ big time, so I was, hrmmm, why the default values are not taken at all?

Anyways, making the story short, if the SPROC is called
EXEC @RC = [IRONsearch].[dbo].[Q_Regions]
without any parameter at all, the default values are taken but if the SPROC is called with the parameters = null as in the first case, the default values are not taken as SQL Server takes the value null for each of them.

It's good to know this gotcha so I can write the Q_Regions with more robust code, checking for nulls and not let my data layer in the app alone with this.

The devil is in the details, isn't it? ;)

QA tests

I haven't written on this blog for quite some time. Having a tight deadline hasn't helped much. I'm currently writing the testing scripts for the QA lab team, it's not NUnit, mind you, just an excel spreadsheet with all the steps they should do to double check the application with the different browsers and OS.
We finally decided to go for www.browsercam.com to test the web app over www.crossbrowsin.com. the main reason is the first one includes Mac OS on its remote desktops tests.
I know cross browser compatibility is going to be a pain, it's always been.

Wednesday, July 13, 2005

Cross browser compatibility...ain't it fun?

We are still on the testing period for the application and we found a real cool resource for testing cross-browser compatibility. Visit the website here
The cross-browsing tests are done via a Java-applet that shows a desktop with about 10 types of browsers, you can previously select the OS and screen resolution you want. All versions of Mozilla till Firefox, IE, Opera, and NN are there, Windows and Linux are among the OS to choose and they promise Mac OS in a near future.
I had used BrowswerCam in the past but only for the snaptshops the browser screens, which is good for designers but not very usefull for web developers. I got a reply on a list now that browsercam.com also offers the actual testing with browsers and even has Mac OS that crossbrowsing.com doesn't. BrowserCam prices are a little higher though.
Okay, our app got an A+ in the tests with IE 5 and 6, all type of Mozilla to Firefox, but failed on NN and IE4, hrmmmmm, probably the JScript that Visual Studio.NET is generating is not the best ECMAScript subset...
I found these two usefull resources to understand the difference between JavaScript, JScript and what ECMAScript is:
Resource 1 at DevGuru
and the best encyclopedia on the net Wikipedia:
Resource 2 at Wikipedia, history of ECMAScript
Oh joy! Tomorrow we'll spend the day finding out what's going on, stay tuned!

Tuesday, July 12, 2005

Class access modifiers and DevPartner Studio suggestions

Finally today I started getting my hands on DevPartner Studio, I had planned to do that yesterday but life is so umpredictable, isn't it? heh, a last minute bug can change the natural course of things.
Anyway, one of the most frequent warnings I get on the project from the DevPartner Studio is "Class member field with protected access" the suggestion is to make the access identifiar Private instead of Protected.
For a nice explanation on Class access modifiers in VB.NET see this article.
So, there I go looking for Protected fields on my classes and setting them Private, but guess what? The DataBinding of the forms just blows up with this...Weird, I'm accessing those fields inside the form and assigning them to Private web form controls, hrm, well, it doesn't work, so I just rolled back my Replace All "Protected" by "Private" and the project's working again. It looks like the UI controls can't be defined Private instead of Protected if you are going to do a server side data binding or property assignment.

If anyone knows the exact, well defined cause of this, please post a comment...

Monday, July 11, 2005

DevPartner Studio and the art of optimizing code.

The company purchased CompuWare DevPartner Studio...
I spent Friday testing the recently finished ASP.NET application with the new tool. I had quite a lot of warnings and things to fix ASAP. Being this app part of legacy code, it has some long methods that need a major refactoring. So my plan for the day is to put in practice what I recently read/learned in Martin Fowler's Refactoring, Improving the Design of Existing Code
and remove all those warnings for long methods, stinky code and refactoring needs. I should get my hands on NUnit for the first time (shame on me), and make sure the changes in the code won't break the whole app. One extra thing though, the refactoring will have to be done manually, there's no refactoring tool for VB.NET 1.1, there is one for 2.0, but we won't be using 2.0 on production yet. So here is my formal complaint, the VB.NET community needs a VB.NET 1.1 refactoring tool!


PS. For those who read this post, Refactoring is not Optimizing code necesarily, Refactoring's for humans to be able to maintain code easily, while some extra encapsulation might not be the most efficient way to have your code doing a task, it's easier for us humans to maintain, and after all, we are the ones that charge per hour ;).

Friday, July 08, 2005

VBCommenter hell no more :)

It’s alive! It’s alive!

All it needed was a reboot and voilá, ‘’’ enter and all comments are generated. Note: don’t put the ‘’’ before the Imports namespaces clause…Oops! But after the namespace name, before the class declaration and before each method
;)

VBCommenter hell

If anyone knows why VBCommenter won’t generate the proper XML files for documenting my VB project, please let me know.

I’ve always used C# as my favorite language, when I moved to work at IronSolutions the switch to VB.NET was a little burden I had to cope with. I was used to this third party Refactoring tool for C# (ReSharper from JetBrains) and the Commenter tool embedded in the VS.NET 2003. None of these features are available for VB.NET 2003 now, except this VBCommenter that won’t seem to work. The GotDotNet forum won't offer many solutions, I already compiled the VBCommenter project twice with suggestions from the forum but no luck, so far.

Is Microsoft ever taking VB seriously? It looks like they’re adding a Refactoring tool for VB in 2005, but I can’t wait to the end of the year (2005) to migrate all the code to have it documented.

I also have the Ank tool for source control, hrmmm, probably VBCommenter and Ank won’t like each other…


Thursday, July 07, 2005

finally, the app's done, let's test in the beta server...Whoa! What the heck?????

After a few months of work the app is done, it runs smoothly with your local MSSQL, all is good, all is good, let’s move it to the beta server and run a few tests before handling to QA.

@#@%#@ what the heck???? My local sql server had gotten the data from the beta server, it should all work the same…it doesn’t. Lemme see the SPROCs’ code, lemme check it again, it should work! Let’s roll back, let’s commit again, it should work??? Wait, is the data what it’s supposed to be?

The relief of the nightmare, here’s the medicine, gal: Tools for comparing and sync databases, the SQL Bundle

And the always sweet file/folder comparing tool, here’s the super Araxis Merge

There you have! Yo data!

Wednesday, July 06, 2005

testing postings on my blog from email

Cool! I’ve been working on getting emails from a mailbox to import into a database with php, and I’m really having a hard time with MS Outlook’s stationeries so I guess that blogger (my blogging engine) will successfully clean up this email and present it on my blog, I need that code, heh J

Cheers,

Lizet

Localization example, yes, here you have free code to play with...

I think I'm better off if you have a nice small example of how to use the SiteTextControl to wrap the ResourceManager features, so here it is...enjoy!

Localization example, zip file with ASP.NET project.

Tuesday, July 05, 2005

A Resource Manager Wrapper User Control, used on ASP.NET 1.1 for Globalization and Localization of apps

Here it is as promised, a user control that wraps the functionality of the ResourceManager class and save you lots of coding:

Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Resources
Imports System.Reflection
Imports System.Threading

Public Class SiteTextControl
Inherits System.Web.UI.UserControl

#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
Private Sub InitializeComponent()

End Sub

'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Private _Name As String
Private lit As LiteralControl
Private res As ResourceManager
Private Shared _myCulture As String

Public Shared ReadOnly Property myCulture() As String
Get
Return Thread.CurrentThread.CurrentCulture.ToString
End Get

End Property
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal Value As String)
_Name = Value
End Set
End Property
Public WriteOnly Property Text() As String

Set(ByVal Value As String)
If Controls.Count > 0 Then
lit.Text = Value
End If

End Set
End Property



Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
End Sub
Protected NotOverridable Overrides Sub CreateChildControls()
res = New ResourceManager("machinelocator.Resource1", [Assembly].GetExecutingAssembly())

Dim _Text As String = res.GetString(_Name, Thread.CurrentThread.CurrentCulture)
lit = New LiteralControl(_Text)
Controls.Add(lit)
lit.Dispose()
End Sub

Public Shared Function GetResourceContent(ByVal name As String) As String
Dim rm As ResourceManager = New ResourceManager("machinelocator.Resource1", [Assembly].GetExecutingAssembly())
Return rm.GetString(name)
End Function

End Class



On the Application events at the Global.asax your code should look like:
mports System.Web
Imports System.Web.SessionState
Imports System.Globalization
Imports System.Threading
Imports System.Resources
Imports System.Reflection
Imports System.Collections
Imports System.IO




Public Class Global

Inherits System.Web.HttpApplication
Private rm As ResourceManager


#Region " Component Designer Generated Code "

Public Sub New()
MyBase.New()

'This call is required by the Component Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Component Designer
'It can be modified using the Component Designer.
'Do not modify it using the code editor.
Private Sub InitializeComponent()
components = New System.ComponentModel.Container
End Sub

#End Region

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the application is started


End Sub

Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the session is started
End Sub

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' Fires at the beginning of each request
Dim culturePref As String = Nothing
Dim cultureSet As Boolean = False

Try
If Request.Cookies.Count <> 0 Then
If Request.Cookies("CulturePref").Value <> Nothing Then
culturePref = Request.Cookies("CulturePref").Value
cultureSet = True

End If
End If
Catch ex As Exception
'nothing
End Try


If cultureSet Then
Try
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culturePref)
Catch
'Set the default culture
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
End Try
End If

Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture

End Sub

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
' Fires upon attempting to authenticate the use
End Sub

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Fires when an error occurs
End Sub

Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the session ends
End Sub

Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the application ends
End Sub

End Class


And finally for using this control you can either put it on your HTML or use it on your CodeBehind like:

strDetail =SiteTextControl.GetResourceContent("AproxResource")


Special thanks to Mark Kucera the original creator of the control, the above code have very few modifications.

What I've been working on: Localization and Globalization with ASP.NET 1.1

Good resources for this topic can be found at dasBlonde's blog
You might like to read this thread in particular: A hot discussion thread on Localization Architectures
If you're racking your head off with a database design that suits your Globalization needs a good article for that is: database design examples
Last and no least the whole fallback process for locating resources files in satellite assemblies...
The most tricky thing about Localization in ASP.NET 1.1 is the assemblies naming convention, without it, the whole process of locating the proper resource file will fail and your application won't speak all the languages that it's supposed to. Notice that the naming convention for ASP.NET 1.1 differs a litle from the naming convention in Windows apps.
A good article for that is MSDN Locating Resources on Satellite Assemblies
Note: You don't have to create the assemblies by hand using the AL.exe utility, VS 2003 will do it for you, you don't even need to create a separate project with the .resX file so it will be compiled into a dll, no need, VS 2003 automatically converts your .resX files into dlls, each one will be a satellite assembly.
My directory structure looks like this:
c:\Inetpub\wwwroot\MyApp\bin
|_ \en\Resources.resx
|_ \fr\Resources.fr.resx
MyApp so far speaks only two languages, English, from the en-US culture and French from the fr-FR culture.

Stay tuned, I'll publish a good user control wrapper to save you lots of code while using the ResourceManager class...

Cheers,
Lizet

Welcome to this blog. Is blogging worth it? We'll find out soon

Hi, not much to say on a first post, just feel free to snoop around, this is what blogs are for anyways.
Yes, I'm a programmer, I like coding, designing and deploying applications, I'm not on top of the mountain yet, but I like to think I'll be there soon ;)