jump to navigation

When “Web Friendly Printing” Attacks February 11, 2010

Posted by markegilbert in General.
add a comment

We purchased a new printer/scanner/copier, and during setup the installer asked about enabling “Web Friendly Printing”, a feature which would strip out the chrome (navbar, footer, ads, etc.) of a web page before printing it.  Not a bad feature, although I didn’t think I had much call for it.

Eh, what the heck.  What’s the worst it could do?  Click.

Jeez!  What did you do, Ray?

(Shakes head)  Let me restart the browser, maybe that was a fluke.

Sigh.

Nope.  Couldn’t be that simple – it wouldn’t be blog-worthy if it were:

Untitled

When someone asks you “What’s the worst it could do?”, don’t hesitate.

Just smack ‘em.

Chalk it up to being detail-oriented – “Access Denied” errors in Blackboard – A Guest Post February 8, 2010

Posted by markegilbert in General, Guest Post.
add a comment

My wife teaches an online class, and the primary means of communication (for assignments, student work, discussions, etc.) is a web application called Blackboard.  My wife, despite being the power-user that she is, understands that not all of her students can glare at the application and bend it to their will (believe me, she has QUITE the glare), so she tries to do things that minimize their pain.

And yes, my suggestion of “just tranq them” was totally unappreciated.

One of the things she does is to field tech support requests herself where she can, whether it is with word processing software, web browsers, or Blackboard itself.  Today’s guest post is an email she wrote to the Blackboard administrator at her college documenting the solution to a problem she hit, or more correctly, one of her students hit, with Blackboard.  The original problem was that a few students were getting “access denied” errors when they tried to download the assignments from Blackboard.  Some other students, though, weren’t having any problems, and initially my wife couldn’t reproduce the error.

She had a couple of rounds of emails to the administrator to try to sort out what was happening, and when she finally cracked the problem she wanted to make him aware so he could pass this gem along to the other online instructors.  For the purposes of this post, we’ll use “Andy” as the name of our Blackboard administrator, and “Joe” is a dummy user that my wife was testing with (trying to reproduce the issue that the real student was having).

****

Hi Andy,

This has been the most strange issue.  I’ll fill you in on some details in case it happens to someone else, because I originally took the same tack as you — since ‘Joe’ could access the files, it must be the student’s browser/firewall/something.

As it turns out, the students who were taking the standard route of clicking on Course Documents, then the Unit 1 folder, then the handouts folder, could download the file just fine.

However, some students aren’t so great at remembering where to find files.  So at the beginning of the week I had posted an Announcement with a checklist of what they needed to accomplish over the next 7 days.  I also hyperlinked to the applicable Discussion Board forums and to the folders in Course Documents — I hoped to reduce the number of ‘I can’t find the file’ emails.

But those hyperlinks were the problem.  Students who clicked on the hyperlink to go to the folder in Course Documents got this Access Denied screen (and once I realized the hyperlinks were the issue, I checked and ‘Joe’ was getting it too, but I – as instructor – did not get it).

Where it got weird is that the hyperlinks for the Discussion Board worked fine.  For everybody.

Huh.

So as I was typing this, I went to look at the hyperlinks one more time to see if I could figure out why, and I just did.  This was the original (bad) hyperlink:

/webapps/blackboard/content/listContentEditable.jsp?content_id=_12809_1&course_id=_339_1

What jumped out at me was ‘listContentEditable’ — Is that related to having editing mode turned on?  And if so, would that mean only users with instructor-level permissions would be able to access it?

Apparently so, because if I turn editing mode off, the URL changes to:

/webapps/blackboard/content/listContent.jsp?course_id=_339_1&content_id=_12809_1&mode=reset

And, voila! Everyone can get the hyperlink to work now – even ‘Joe’.

So, I guess the lesson is if I’m cutting-and-pasting the hyperlinks inside Blackboard, I need to have the editing mode turned off.

(And I don’t see this anywhere in the manual, so I guess I shouldn’t feel too stupid!)

****

This issue raises a couple of points. First, the error report of “I’m getting an error when I try to access this document” wasn’t specific enough because there were multiple ways to get to the files. The path that the user took to get to the point of clicking the link to the document mattered.  For us trying to troubleshoot odd errors, paying attention to what the user is doing to get the issue is critical to solving it.

Second, being able to test the system as if you were a user – and not an administrator – is also critical, especially when it seems to be security-related as this one was. In the course of testing this, my wife got a dummy user account called “Joe” that had the same rights that her students did, and no more.

Troubleshooting is all about the details.

Join me, and together we’ll rule… – ActiveRecord and Attributes on Join Classes January 21, 2010

Posted by markegilbert in Castle ActiveRecord, Visual Studio/.NET.
add a comment

I mentioned a couple of weeks ago that other than one notable exception, I was loving Castle ActiveRecord.  That one exception is today’s topic.  I say this is an exception to the statement “I love Castle ActiveRecord” only because I fought with this issue for several weeks* before I figured it out.

Originally, I had two tables – Book and Contributor.  These were joined in a many-to-many relationship in a table called BookContributor.  The first version of BookContributor was purely a join table and therefore only contained keys to the other two.  The Book class had a property called Contributors that had the HasAndBelongsToMany() attribute on it, just as it is shown in this example.  That allowed me to add new contributors to a book using something like “MyBook.Contributors.Add(MyNewContributor)”.  And everything was peachy.

The application that uses these classes shows contributors (authors, editors, etc.) in a list box.  Up to this point they were shown in the order that they were added to the list (I was sorting on the primary key of the BookContributor table).  Now, I wanted to allow the user to rearrange the contributors in any arbitrary way.  That meant I needed to add a field to BookContributor called “SortOrder”.  I added the field, and then hit my first roadblock.  Ok, THE roadblock.

ActiveRecord had been doing a fine job managing the contents of the BookContributor table.  Saying MyBook.Contributors.Add(MyNewContributor) would create the record in BookContributor for me, and wire the up the foreign keys just right.  Now, I wanted to be able to manage the SortOrder field in the join table, so saying MyBook.Contributors.Add(MyNewContributor) wouldn’t cut it anymore.  Since SortOrder was a property of the join table and not the Contributor record itself, I also couldn’t set a property on the MyNewContributor object before invoking the Add method.

I did a search for variations on “ActiveRecord join table property” to find a way to set SortOrder.  One of the most promising posts I found was the ActiveRecord online documentation page for the HasAndBelongsToMany attribute, referenced above.  There is a section titled “Attributes on the Association Table”, which sounded like what I wanted to do.  Their approach was to define an ActiveRecord class based on the join table.  Up to this point I hadn’t needed to do that – ActiveRecord was able to manage the contents of the join table purely from the relationship I had defined between the Book and Contributor classes.

What this post wasn’t clear on, however, was how the Post and Category classes (to use their examples) needed to be adjusted to refer to the new PostCategory class.  After rereading this page several times over, and doing some additional digging on the Internet, I concluded that the Post and Category classes really didn’t refer to the PostCategory class at all.  Attaching a Category to a Post (or conversely, adding a Post to a category) doesn’t set the PostCategory.ArbitraryValue database field.  If you wanted to do anything with ArbitraryValue, you’d have to do it using the PostCategory class.

This is basically the solution I ultimately arrived at.  I would create a class for BookContributor, and instead of saying MyBook.Contributors.Add(MyNewContributor), I would so something like the following:

Dim MyBook As Book
Dim MyContributor As Contributor
Dim NewBC As BookContributor

’ Load up the MyBook and MyContributor objects here

NewBC = New BookContributor
NewBC.Book = MyBook
NewBC.Contributor = MyContributor
NewBC.SortOrder = 2
NewBC.Save()

It’s not nearly as clean as MyBook.Contributors.Add(MyContributor), but it gets the job done.  Additionally, the Contributors property on the Book class still gets populated behind the scenes which allows me to sort on the new SortOrder field, so the only real change from what I had in place before is the process of adding new ones.

* Several weeks averaging roughly 30 minutes per day.  I had a lot going on that month.

You can’t see me! PropertyGrid, Databinding, and the Browsable() attribute January 18, 2010

Posted by markegilbert in Visual Studio/.NET.
add a comment

As I described in a previous post, I’ve been working with PropertyGrids of late.  Setting the grid’s SelectedObject property to an object is enough to get that object’s properties and values to appear in the grid, but rarely is that step sufficient for a real app.  That’s where attributes come in.  Using attributes (in particular, those found in the System.ComponentModel namespace) you can do things like attach a description for a property (using the Description() attribute), place them in a category (using the Category() attribute), or even hide them so that they don’t appear in the grid (using the Browsable() attribute).

In my case, the object I was working with exposed the database ID value, something I didn’t want the user to have to worry about.  So, I attached Browsable(False) to that property to hide it:

<Browsable(False)> _
Public Property ID()
As Long
    Get
        Return Me
._ID
   
End Get
    Set
(ByVal value As Long)
        Me._ID = value
   
End Set
End Property

That worked beautifully.  The ID property dropped out of the grid and I went on my merry way.  That is, until I opened up a form that had a databound drop down box based on a collection of these objects.  When I opened the form I was greeted with “Cannot bind to the new value member. Parameter name: value”.  This worked before.  What have I changed since then?

On a hunch, I tried backing out the changes I made to the class for the PropertyGrid.  Now, the drop down worked again.  After a little back and forth I determined that the Browsable() attribute was the problem.  Apparently, having that on the field not only hid it from the PropertyGrid, it rendered it unbindable.

The next best thing to having the field hidden from the grid completely was to make it read-only.  Would making it read-only still allow the drop down to bind to it?  I reworked the attributes on the class to test it:

<[ReadOnly](True), _
  Description("The format’s internal system ID"), _
  Category("Properties")> _
Public Property ID()
As Long
    Get
        Return Me
._ID
   
End Get
    Set
(ByVal value As Long)
        Me._ID = value
   
End Set
End Property

Sure enough, the drop down was happy again.  The field appears in the grid again, but this time it appears greyed out and isn’t editable. 

That’’ll do, ID.  That’ll do.

Focus, grasshopper! January 14, 2010

Posted by markegilbert in Visual Studio/.NET.
1 comment so far

I was working with a WinForms form that contained a PropertyGrid control, and hit an interesting problem when I was trying to save updates made to the values in it.  I was using the PropertyGrid as a quick and dirty way to provide an admin screen where the user could select an item from a list, see the properties for that item in the grid, edit them as needed, and then hit Save.  The problem was that Save wasn’t always picking up my changes.

The Save function was defined on the app’s menu, and it invoked the form’s Save method.  I assigned a shortcut of Ctrl-S to this menu item.  In the course of my testing I was finding that if I typed a new value into the grid and then hit Ctrl-S, my new value wasn’t being saved.  In stepping through the code, the grid’s SelectedObject property – which would normally contain all of the values being displayed in the grid – wasn’t getting the one I was just working on.  If I modified the value and used my mouse to select the Save option from the menu, then it worked.

Clearly, strange things are afoot at the Circle-K.

What if I modified a value in the grid, then clicked somewhere else in the grid, then hit Ctrl-S?  That worked.  Ok, now things are making more sense – the problem is focus.  The focus was still on the item I just edited, so SelectedObject wasn’t being updated with what I just typed in.  When I hit Ctrl-S, the focus wasn’t changed at all, but it did change when I clicked the menu item for Save.

The solution proved to be quite simple.  At the beginning of my form’s Save method, I added this line:

Me.MainGrid.Focus

That forced the focus to be moved away from whichever field in the grid I was just working on, thereby forcing the SelectedObject to be updated with the latest values from the grid.  That, in turn, allowed both pathways – keyboard shortcut and menu click – to work.

Constant Learning January 11, 2010

Posted by markegilbert in Visual Studio/.NET.
add a comment

The other day I needed to verify that a particular value had been set for one of the constants in an executable I had deployed to a client’s server.  I decided the quickest way to check it would be to use Reflector to poke into the EXE that I sent them.  I dropped the executable into Reflector, drilled down into my Main() module, and found it in the tree.  I right-clicked and selected “Disassemble”.  What I got was something like this:

Private Shared EXTRACT_PREFIX As String

Sigh.  So close.  This was SUPPOSED to be easy. 

After a little more poking around, I found that the context menu for this constant had another option – Analyze.  I hit that and got another pane with another tree to drill into.  When I expanded the top level (which contained my constant), I saw two items: “Used By” and “Assigned By”.  Expanding the latter showed one place that assigned a value to the EXTRACT_PREFIX constant – the module’s .cctor method.  Right clicking on that gave me an option for “Go to member” which refreshed the Disassembler pane to show me this:

Shared Sub New()
   Main.EXTRACT_PREFIX = "PRIMARY_DATA_"
End Sub

At least I got the answer to the question that I started with, but several new ones now appeared on the scene.  Are all constants initialized like that?  What is the “.cctor” method used for?  How is “.cctor” different than the “.ctor” method?  I decided to open another binary file containing constants, this one a class library.  As it turns out, the class library had the constants initialized with the declaration statement (and therefore the value was visible in the Disassembler pane), just like how I would write it in source code, and what I was expecting to see originally.

Ok, now I became really curious.  Why the two different methods for initialization?  What was the difference?  The first was an executable that was built from a module, the other was a class library containing classes.  As an experiment, I looked at another executable, this one a WinForms app whose startup entity was a class (one of the forms in the app, to be precise).  That executable initialized the constants with the declaration, just like the library class did.  The difference appears to be whether the constant was part of a class or a module.

Now, let’s tackle the question of “.cctor” versus “.ctor”.  After doing a little searching on the web, I found a couple of posts that shed some light on the difference between these two.  The first one, published several years ago by “cbrumme”, calls the “.cctor” method the “static constructor”: http://blogs.msdn.com/cbrumme/archive/2003/04/15/51348.aspx.  The second one, published far more recently (just a few weeks ago, in fact) calls it a “module initializer”.  Both of these seem to point to “.cctor” being necessary when initializing code for a module – in other words, a structure that isn’t a class.  The “.ctor” method, therefore, is used to initialize a class.  I don’t think I can use “classes use .ctor while modules use .cctor” as a hard and fast rule, however – cbrumme’s post refers to the “.cctor” method for a class, too.

I definitely feel like I’ve wandered deeper into the .NET framework than where I’m comfortable, but I think it was a worthwhile trip.  Even if my speculation about the uses of “.cctor” versus “.ctor” are wrong, I’ve at least learned there is more than one place to look for constant initialization.

The end is… not so near. January 7, 2010

Posted by markegilbert in General.
add a comment

I hit a fun one today.  I received a meeting invitation for January 21, 2010.  I casually clicked on the “Calendar” button in Outlook to bring up my schedule for that day.  I was greeted with the following:

Calendar

Um.

Wow.

I closed that view and checked the meeting invite again.  No, it was definitely this millennium.

I clicked “Calendar” again, thinking it was a fluke.  August 31, 4500 came up again.  I tried clicking one of the September dates – no dice.  I could back up to July 4500, though.  So apparently, August 31, 4500 is the max date in Outlook.  Now for the really fun part.  I accepted the meeting.  If clicking “Calendar” jumped me 2500 years into the future, what would accepting it do?

Well, obviously it put it on my calendar for January 21.

Sigh.

Such a let down.  I really wanted to give my project manager crap for going a little around the bend when it came to proactive planning.  Way, WAY around the bend.

But hey, good thing we found this Y4-1/2k issue when we did.  As soon as we’re done dealing with the monolith this year, and the end of the UNIX world in 2038, we can get cracking on this one.

Sorry, you’re just not my Type January 7, 2010

Posted by markegilbert in Castle ActiveRecord, Visual Studio/.NET.
add a comment

I was trying to write a method for one of my Castle ActiveRecord classes that would return a list of Contributors by type.  The types were defined as an Int32 enumeration in the Contributor class, and my original method was as follows:

Public Shared Function GetAllByType(ByVal SearchContributorType As ContributorType) As IList(Of Contributor)
    Dim MySearchCriteria As DetachedCriteria
    Dim MySearchOrder As NHibernate.Expression.Order
    Dim ContributorArray() As Contributor
    Dim ContributorCollection As ICollection(Of Contributor)

    MySearchCriteria = DetachedCriteria.For(GetType(Contributor)).Add(Expression.Eq("Type", SearchContributorType))
    MySearchOrder = New NHibernate.Expression.Order("Name", True)
    ContributorArray = Contributor.FindAll(MySearchCriteria, MySearchOrder)

    ContributorCollection = CType(ContributorArray, ICollection(Of Contributor))
    Return CType(ContributorCollection, IEnumerable(Of Contributor))
End Function

When I ran the unit test that exercised the FindAll method, I got this error:

Could not perform FindAll for Contributor

Not terribly helpful, but when I looked at the inner exception, I found the real cause:

Type mismatch in NHibernate.Expression.EqExpression: Type expected type System.Int32, actual type BMSBusinessServices.Contributor+ContributorType

I tried explicitly casting the SearchContributorType parameter to an Integer (Int32) value, and it worked – no more exception, and my test passed.  

In the past, .NET has done a fabulous job of implicitly casting things for me.  Perhaps what is happening here (and I have not looked at the NHibernate source to confirm this, so this is pure conjecture) is that NHibernate needed to compare the Contributor.Type property to the SearchContributorType variable.  The former is declared as Int32 while the latter was of the Contributor.ContributorType enumeration.  Even though the latter was also ultimately defined as Int32, NHibernate needed to do something like a .Equals, and the slight difference in types was just enough to throw it off.

At any rate, the CType() was easily inserted into the Expression, and I was on my merry way.

Nearly Sentient Error Messages January 4, 2010

Posted by markegilbert in Castle ActiveRecord, Visual Studio/.NET.
1 comment so far

I’ve been working with Castle ActiveRecord for a “home” project for much of the last year.  With one notable exception (which I intend to blog about in the near future), I love the framework and the functionality it provides.

One particular area where ActiveRecord excels is its error messages.  Not only are the messages detailed, but the ones that I’ve come across also tend to give you hints as to what you may have forgotten to do.  Take this one, for example:

Castle.ActiveRecord.Framework.ActiveRecordException : You have accessed an ActiveRecord class that wasn’t properly initialized. The only explanation is that the call to ActiveRecordStarter.Initialize() didn’t include BMSBusinessServices.SKUDate class.

Before you can use an ActiveRecord class, you have to initialize it.  For desktop apps like mine, the call to ActiveRecordStarter.Initialize() is made in the MDI Parent form’s constructor, one of the first things to execute when the app loads (for web apps you’d place this call in the Application_Init event, defined in Global.asax).  The Initialize() method takes a list of the classes that you want to designate as being visible to ActiveRecord.  The error message above points you in that direction.

Now, as it turns out, I did have the SKUDate class listed in the Initialize method, so I had to dig a little deeper for the solution, which I found in this post: http://www.feed-squirrel.com/index.cfm?evt=viewItem&ID=69310.  The post is a little hard to read (any and all whitespace between sentences and paragraphs appeared to be stripped out), but near the very end the post mentions that this error can also be caused when you forget to decorate the class in question with the <ActiveRecord()> attribute.

Which I had.

And once I added it everything was happy again.

Despite the fact that the error didn’t point to the real solution to my problem, what it did give showed me what an exception could really be.  After seeing this particular message, I felt compelled to take a long hard look at the custom exceptions that I write and the messages that they include. Basically, my exceptions needed to grow up a little and become slightly more intelligent.

System.String has me in knots December 1, 2009

Posted by markegilbert in Visual Studio/.NET.
add a comment

You know it’s time to call it a day when System.String starts giving me difficulties.

Or at least, I SHOULD have known.

A few weeks ago I was happily working on a utility for one of my projects, and started seeing some odd behavior out of a logging routine I was using.  I was trying to pass it a string that had carriage return/line feeds in it, and wanted to dump that string out to the console window as well as to a log file:

Sub Main()
    MyMethod("blah" & vbCrLf & "blah2" & vbCrLf & "blah3" & vbCrLf & "blah4" & vbCrLf)
End Sub

Private Sub MyMethod(ByVal CrazyString As String)
  
‘ Do some stuff
End Sub

What I was seeing was in some cases the carriage returns were being stripped out of the final string.  I decided to trace through it with the debugger to try to figure out what was killing them.  I set a breakpoint just inside of MyMethod and ran it.  I examined the CrazyString parameter value using the Command Window, and saw that the carriage returns were gone – all of my strings were, ahem, strung together.

After a little more tinkering, I tried doing this in the Command Window:

? CrazyString & vbCrLf & “Test”

That actually allowed ALL of the original carriage returns to appear, not just the one I appended in the window.  I then tried this:

? CrazyString & “Test”

That also worked – all of the carriage returns appeared.  Ok, now let’s move on to the truly silly – let’s append an empty string to CrazyString:

? CrazyString & “”

Sure enough, carriage returns manifest.  Ok, so now that we’ve completely walked off the deep end, it’s time to bring in the sanity reinforcements.  I dragged a colleague over to my desk and showed him the silliness above.  After discussing it for a few minutes the thought occurred to me that perhaps something funny was going on with my machine or my installation of Visual Studio, so we walked over to his desk so he could try to reproduce the problem.  Sure enough, after a couple of minutes he had a console app running on his machine that exhibited the exact same behavior.  Yay!  It’s still broken!  Oh, wait…

He then took my Command Window tests one step further with the following:

? CrazyString.ToString

Surely that won’t make a difference – CrazyString is already defined as a string.  For some reason, however, it does make a difference.  “CrazyString” has no carriage returns, but “CrazyString.ToString” does.

We then tried adding a line of code to the app to write out the value to the console window:

Console.WriteLine(CrazyString)

The above line succeeded in writing out the carriage returns, and it didn’t require ‘”.ToString” at the end.  After yet some more tinkering, I found that the phantom carriage returns would be preserved through even through successive function calls, but would only manifest themselves if I appended something to the string, or I invoked .ToString on the parameter.

Now, for the final mind-bender.  We tried this expression in the Immediate Window (while in Debug mode):

? CrazyString = CrazyString.ToString

It returns True.

Sigh.

The apparent moral to the story is just to slap .ToString onto every String variable, just so all outputs (Console.WriteLine(), Immediate Window, Command Window, watches, QuickWatch Window, etc.) show the same thing.