Monday, July 30, 2007

Binary Encoded Strings & Zebra printers....

We built a little application which talks to UPS via XML to print out their shipping labels. Well, until a few days ago, this portion of the application worked perfectly, and we had never had any troubles with it. Basically, all of a sudden, the printer stopped printing the labels.

So I spent a few days hunting through the logic looking for a problem. Didn't find a thing wrong.

Then I checked the Application Log, hunting for any errors listed. Nothing.

Sent the XML messages that I send/receive off to UPS. Still nothing wrong.

Today, I pulled out the relevant bits of program, and toss it into a new app, just to print these labels. No XML communication. No XML Parsing. I supply the base64 encoded string to the app, and it converts it and prints it.

So, what do I get? Nothing.

Finally, I try sending printer codes without conversion. Again, nothing.

Of course all of these things are done using the Zebra's programming codes for the Thermal 2844. Basically, I have to open the port and then write out to it directly.

Alternatively, whenever I open the printer through traditional .NET printing classes and print using those, then it works perfectly, and the printer obediently spits out the text as ordered.

I am now, officially, smacking my head up against the wall. And of course, Google is less than useless for this.

Wednesday, July 25, 2007

VS Studio pasting from the browser

I'm working on this little project, and I needed a modal window system. So I did a little searching and stumbled upon Prototype Window. It's released under the same MIT license as the Prototype JS library.

That's all good. But, I'm also using a bit of JSON in this particular application, so I want to make sure that I have the latest Prototype because that's where the JSON functionality is built in at. So, I go to the site, hit the download page and then copy from there the text for the JS file.

I happily go over to VS and paste that text into my JS file and hit the site.

Where everything proceeds to throw up. Over and over again.

After searching all the code that I had written, trying to figure out what was going on, I finally open up my local copy of Prototype.js - the one I had just pasted into, and right there at the top is a nice big old: <pre>.

... <-- that's me smacking my head against the desk

And then I remembered that most hated of VS 'features' the fact that it tries to paste text copied with formatting attributes, with those formatting attributes translated into HTML.

Which means you'll get a bunch of MS Word junk when you paste from MS Word, and a bunch of HTML junk when you paste from a browser.

I can see the usefulness of such a thing, but it should not be the default setting. Or at least it should be configurable as a default setting or not.

I believe it's fixed in VS 2005, as I don't seem to remember having that headache when working on a site in it earlier this year.

Well, that's my story of my own stupidity for the day. Enjoy.

Friday, July 20, 2007

Identity Generator

Something fun wandered across my RSS Feed this evening. It's a random fake identity generator.

They can generate a whole bunch of information needed to make this fake identity look real, and they can generate medium-sized datasets for you (up to 40,000 records) for free.

In the past, I've worked on a medical PDA application, and all our testing data had to be cleaned before we could do any testing on our application.

The part of the application I worked on was where this would have been the most useful. I built a Windows service which polled the message queue where the Enterprise data source would dump its data. It then took that data, parsed it out and shoved it into our own data structures for the application. A lot of fun XML and Message Queueing and just Windows services in general, but it wasn't a lot of fun anonymizing 10,000 records of personal information. Oh, if only I had had this 3 years ago.

Thursday, July 19, 2007

Learn something new everyday...

Apparently IE has a modal option for JavaScript to launch new windows.

I can't see it being truly useful though, as it's not supported in Firefox or Opera.

Anyway, the functionality in JavaScript looks like this:

Function modalWin() {
if (window.showModalDialog) {

window.showModalDialog("xpopupex.htm","name", "dialogWidth:255px; dialogHeight:250px");

} else {'xpopupex.htm','name', 'height=255,width=250, toolbar=no,directories=no,status=no, menubar=no,scrollbars=no, resizable=no ,modal=yes');


As I said, I'm not 100% certain what the usefulness of this is, as if I want something modal, then that means I need it modal in Firefox and Opera as well as in IE.

Wednesday, July 18, 2007


An interesting topic flashed across my RSS Reder courtesy of TheServerSide.Net.

Basically, it was Ruby.NET (a .NET implementation of the Ruby programming language) is going open source.

I like Ruby, though I've not played on it nearly enough, and I'm fairly excited about this happening, especially if WATIR and other Ruby tools (i.e. RAILS!) can be folded into the Ruby.NET implementation.

This definitely bears further attention.

Tuesday, July 17, 2007

Scripting SQL Server Roles

For our prime contract, we have multiple applications all using the same database. We choose this schema because there is some information that is shared among all these applications, and rather than having it duplicated, we decided to just shove it all into the same place. Additionally, we have users tacked onto the databases, for each application which owns the objects of that application.

This allows us to have two tables named the same, but schema'd out to the application. For example, the EPB.Documents table and the ELETA.Documents table. While they are named the same, they serve distinctly different purposes. The EPB.Documents table is the meta data for the documents which EPB generates. The ELETA.Documents table is attribute data for documents displayed by ELETA.

Little things like that.

Anyways, in addition to all of that, we use Roles to control access to the application. For example there is an EPBUser role and a ELETAUser role. This means that we can quickly assign access to the db user to those elements which each application needs to function.

The problem comes in with generating SQL script files for backup/configuration/deployment purposes. 2000's Enterprise Manager has no support for scripting the role to a file or a query window. 2005's SQL Server Studio does, but it only scripts the creation of that role, not all the underlying permissions.

So, I hunted the internet and found this. What this does is displays just what attributes a user or a role has (there are 2 scripts on that link, the top one is for users the bottom for roles).

I grabbed it, plugged the name of my role in, and within seconds I had a nice batch of GRANT statements which the role needs to run the application.

Monday, July 16, 2007

Windows Integrated Security for Websites...

A lot of our websites that we build for our prime contract have anonymous access turned off, and integrated Windows security turned on. What this means is that when you try to hit the site, you get the Network username/password prompt box, where you have to enter your username/password for the domain. Not that big of a deal, it's easy security to implement, and we don't have to deal with generating passwords, and it's one less password for the user to remember. Additionally, if you're on their network and using IE, then the authentication process is transparent for the user.

Up until now, we had been using a server variable and then session variables to store the username. In fact this is the exact code we used from the Session_Start function of Global.ASAX:

Session("User") = Trim(Request.ServerVariables("LOGON_USER")).Replace("/", "\").Replace("'", "''")
Session("User") = CStr(Session("User")).Substring(CStr(Session("User")).LastIndexOf("\") + 1)
Not the most beautiful code in existence, but it did what we needed. It got the network username from the server and stuck it in a place where we could use it.

Of course I hated that code. It annoyed me because it was a hack. Enforced psuedo-authentication. What is worse, is that it didn't use the Page.User functionality.

So, we got a new project from that prime contract, and I was pondering how I could get that LOGON_USER ServerVariable into Page.User. So a bit of research, and I came up with some new code. First, the retreival of the LOGON_USER moved from Session_Start to Application_AuthenticateRequest. Then I added this code to that method:
Dim username As String
username = Trim(Request.ServerVariables("LOGON_USER")).Replace("/", "\").Replace("'", "''")
username = username.Substring(username.LastIndexOf("\") + 1)

System.Web.Security.FormsAuthentication.SetAuthCookie(username, False)

Dim id As New System.Security.Principal.GenericIdentity(username)
Dim p As New System.Security.Principal.GenericPrincipal(id, getUserApplicationRoles(username))
HttpContext.Current.User = p
What this does is retrieves the username from the server variable, uses that username to generate the authentication cookie so that the PAGE object knows about the authentication, and then generates the GenericIdentity and Generic Princpal objects necessary for Page.User functionality.

The final bit of usefulness would be the getUserApplicationRoles function which returns an array of strings, and basically gets the roles associated to the passed in user for our application.

So, we still use the server's security, but we now have access to Page.User.Identity.Name and Page.User.IsInRole. And I'm happy.

Friday, July 13, 2007

JSON Editor

I love JSON for use in JavaScript functionality. It's easier, faster and just better to use than XML in the same scenarios.

The only problem with it, is it's a hassle to format properly sometimes. Especially if you're dealing with dynamic data on the server side.

Well Thomas Frank has now put together a JSON Editor. It runs online or you can download a copy to run locally.

Thursday, July 12, 2007

A New Project and a RadioButtonList

Got two new things at work this week. The first is a new employee and the second is a new project. That ramps up the total current projects that I'm assigned to to 4. One is "turned off," while the other three are happily chugging alone. And of course, none of these projects are simple business websites. No, these are full fledged web applications, all running on an interconnected database.


And, I get the joy of training the new guy. Truthfully, I enjoy training. I enjoy imparting my knowledge to others. It's fun. Especially in the workplace where people actually WANT to learn. The downside is that there's a lot of knowledge that needs to be imparted. Everything from process to arcane code structures which we use to improve application efficiency (i.e. using "OBJECT Is Nothing" rather than "IsNothing(object)", etc).

This of course cuts into the time I have to spend on developing. Since we were tossed another application, that means I had to toss some development towards the new guy before I was certain how much he understood what the code is doing. Well, I was trained via trial by fire, so I guess it will work for him as well.

Anyhow, I spent a good hour cursing at .NET 1.1 this morning. I have a RadioButtonList on my form, and the datastore that was coming from the database was the Text, Value and Selected attributes of the ListItems. So, I spent a bit of time, hunting the web to see if there was a way to utilize the selected attribute while doing a classical databind.

Unfortunately, there's not. That meant that I had to walk the DataReader myself, creating the ListItems and setting their Selected attribute all the while. How annoying.

I wonder if they fixed that in .NET 2.0, but somehow I doubt it.

Friday, July 6, 2007

Developer Testing

This must probably be the most onerous portion of my job. The task where I have to play with the currently stable pre-release version of our product prior to turning it over to the testers for system testing. Fixing little things like someone having changed every ":" in the application's text to a ".".

I know it needs to be done. I know WHY it needs to be done, and I can do it. I just rather be rebuilding the processing engine (again), because, well, that is FUN!..

Speaking of rebuilding the engine, the product I'm talking about is our document builder (and if we ever get our commercialization stuff finished, I'd be ecstatic to provide links to this thing, as I'm proud of it). Anyways, our document builder has certain controls which are always on the page. These controls are basically for the information that is shared across pursuit-scopes for the documents (such as the name of a project). That's not a problem, the problem is that there are multiple pursuit scopes, and each scope has a slightly divergent need for controls. So the design involved adding pursuit-pages to handle that, in addition to the INDEX page. A change from previously where we had only a single page. An unfortunate side-effect of that was suddenly our code base tripled in size, with a lot of that being replicated functionality for those pages.

I didn't like that then (too much chance for functions not getting update) and I don't like it now. So my solution is to change how the system works. Currently, the application asks for a pursuit and an department. Once it has that information, then it allows you to create the document in the database. Which seems backwards to me, especially since the application is a document builder. If we made those shared controls dynamic, then we could pretty much force the application to create a path for data entry based on document type. Which not only means we can go to a single page again, but that we can also use the tool to generate documents that are not specifically tied to a project (what those mythical documents are, I'm not sure, but it sounds good as an argument).

Anyways, now I must convince the project leaders of the glory of my vision. And then tell them I want to change the system even more, so that the controls are all built dynamically via JavaScript, loading and saving data through a web service accessed via AJAX.

That should be a fun discussion.

Blog Widget by LinkWithin