Tuesday, December 8, 2009

Good stuff!

Some previews of what is to come with Silverlight 4 that are of keen interest to me are found here.

Better databinding with formatting, nullvalue and invalid binding handling. And more...I even heard rumors that binding to collections with an indexer will be natively supported, but I heard that elsewhere.

Additionally, if you haven't worked with Common Table Expressions in your SQL database, you really need to know about them. They make all sorts of things easier including paging and complex combinations of queries. Here's a nice introductory article.

Wednesday, November 25, 2009

Popups and Borders, Oh my!

In Silverlight there is a "Popup" control which is designed to be a popup. You open and close it using the "IsOpen" property. It is a container like border, grid, etc. In Blend it sometimes decides to be open and sometimes not (I noticed this odd behavior both in Blend 2 and 3).

One big downside I found to using the Popup control aside from the Blend oddness is its drag behavior is very choppy.

When you add the MouseDragElementBehavior to a Popup, and then try to drag it at runtime, it jumps around before stopping where you dragged it. YUCK.

Thus I really don't see any advantage to using the Popup over using a Border instead. When the MouseDragElementBehavior is applied to a Border, its movement is as smooth as a baby's tushie. From a code perspective you just have to control the Border's Visibility property instead of using IsOpen. Not a huge change.

If anyone knows some advantage of the Popup that I'm missing, please do tell.

Monday, October 26, 2009

DataGrid & Dynamic Font Loading

Unicode font packages are HUGE. Like 33MB huge. This interferes with compiling your .xap file if you are using the "supported" method of using the FontManager to include the font in your Silverlight assembly. By interferes, I mean anywhere from 25-75% of the time you get an "Out of memory" exception when you try to compile. Reboot and the problem goes away for awhile, but not long.

For months I've had on my "to-do" list to pull the font file out and start loading it dynamically using the WebClient, but I had so many features in my "to-do" list that the users can actually see that I kept delaying it. Well, today I got so fed up with the out-of-memory shuffle that I decided to put my foot down, stop working on everything else, and git-r-dun.

I decided to use the unicode font only where the potential for dynamic data exists and to use a static font for static data. Find-replace for the win. However, there is a bit of drudgery associated with updating the FontSource for each framework element that must use the dynamically loaded font. And, when it came to updating the Silverlight ToolKit DataGrid objects I was using... a small stumbling block. The DataGrid and its DataGridColumns do not expose the FontSource. They expose the FontFamily, but that's only half the work.

So here's how I handled it - I replaced all my DataGridTextColumns with DataGridTemplateColumns and for each one, defined a custom CellTemplate containing a TextBlock. I set the Text using the normal Binding Path methodology and defined a handler for the Loaded event of the TextBlock. In this Loaded event, I set the FontSource.

You might recognize this trick from my dynamic ToolTip post... that's where I got the idea. (I also tried binding the FontSource property of the TextBlock in the XAML but that caused a Big Fiery Ball Visible From Space.)

Maybe prujohn or some of my other Silverlight 3 savvy readers may know if there is a better way to do this in Silverlight 3 (which I should be able to upgrade to any time now when our Blend 3 licenses arrive...waiting...waiting...) or whether I should continue to make this change all over my application (spending a heck of a lot of drudgerous time in so doing)?

Happy Monday,
Anye

Monday, October 5, 2009

Abstract base classes

A short fyi - Expression Blend (ETA: Blend 2) can't handle abstract base classes.

Scenario: I have two pages A & B that I need to be possible "source" pages for another page - I could either have both implement an interface or use inheritance. I choose inheritance for various reasons (mainly involving shared functionality between A & B), and want each class to have an UpdateAfterDone() type method to be called by the 2nd page to update the 1st with its results. I tried having both A&B inherit from an abstract class that defines an abstract method UpdateAfterDone(), and everything was hunky dory until I tried to open A in Blend. When I switched the base class to be concrete and made UpdateAfterDone virtual, it rendered fine.

Not a show-stopper, but since I don't really have "default" functionality for UpdateAfterDone() like I do for some of the other methods I would think it would be cleaner to be abstract. If not for the shared functionality I'd use an interface instead.

Harumph.

Friday, August 28, 2009

Indexed views in SQL 2K5 Standard

I know, I've been away for awhile. Main reason for that is every topic I think of to blog about ends up being too darn proprietary. The powers that be would be unhappy if I blogged about certain topics.

So, today I will talk about something I was investigating recently that ended up being a pain in the rear: indexed views.

Here's the situation - you have a view that is crossing several tables, all the tables are indexed properly, but the performance of the view is slow because the view itself is not indexed. When you write the same query using all the underlying tables, messy as it is, it runs faster. Wouldn't it be nice if you could index the view?

Well, you can...sometimes. The biggest kicker here is in order to use indexed views there are certain settings that your database table has to have - QUOTED_IDENTIFIERS = ON, ANSI_NULLS = ON among others - and these have to be set when you create the table. So, if you've already got lots of happy data living peacefully in your tables - it's not necessarily a simple matter to drop the table and rebuild.

Additionally, it's not just the table that needs these settings - all of your queries that perform CRUD against these tables need to be adjusted as well to run in a session with these settings in place. And of course, whenever you read from the view in question they must also be set this way.

The good news is, if you are starting from scratch it is a relatively simple matter to do all these things. The bad news is, if you are maintaining a system like mine where deleting the data to upgrade is not an option, then you are in a pickle. At first I tried going the route of, "ok, we just won't update existing installations." But - this presents a problem when all installations have to use the same codebase. The code needs to be able to figure out how to set the settings. There are functions to look at the settings of a table, so you technically could query each table in question, determine if ANSI_NULLS and the other usual suspects are ON or OFF and set the session accordingly. Multiply that across all your code and you have a maintenance nightmare.

So, I decided to wait until the next major schema rewrite where we don't upgrade existing installations and to make the changes then, full stop. So I can support one schema, one codebase without a bunch of kludgy code to figure out which database schema I'm working with. In the meantime, the slower of my views won't be getting as much heavy lifting as they should be.

But, the lesson has been learned for the future - when you write your schema, plan for these indexed views. Or just plain don't use views unless you have to.

Tuesday, June 2, 2009

Dance of the Transport Security Penguins

I've spent the last couple days getting a WCF service working with Transport security + basic authentication using wsHttpBinding and it has been an experience.

If I weren't constrained to a server that already has live sites that can't go down randomly for tinkering, it would have been much easier. I will warn you up front that although it is possible to fool WCF using a fake SSL certificate your life will be easier if you can work where there is a real, trusted one.

But, I finally prevailed.

Some tidbits of "wisdom"...
I had trouble with the mex endpoint requiring anonymous authentication being available once I turned basic authentication on. So I had to remove the mex endpoint and remove the httpsGetEnabled line in the service behavior. This of course means you cannot discover the service from this location, so luckily I had discovered it locally already (locally does not have an SSL certificate however).

(Interestingly enough, when I tried this with a simple basicHttpBinding service, discovered locally w/o security and then changed the config to transport security, I got an error trying to set the client credentials, telling me the username and password were read only. Huh? I abandoned my simple test and went back to the main service which I already had running under transport security with no authentication.)

This part is probably obvious but just in case I will state it here in case it helps anyone - when you are configuring IIS, if you are going to use a local machine account for the basic authentication, the domain & realm should be empty. If you are using a domain account, you need to pick the domain and put it in these fields.

I eventually got this running with anonymous auth turned off, no mex endpoint, using either a domain account or a local machine account. I settled on a local machine account with remote access disabled and no permissions, which I then encrypted before adding to the config as settings. Luckily for me, I don't WANT my app to function if anyone messes with my settings.

One other thing I will mention is that the error messages I got were not always descriptive. I saw a lot of "the service could not be activated" when I had the mex endpoint still existing after turning on Basic Authentication in IIS, and even after getting to the working configuration of IIS and my config files, when I passed an incorrect username & password on the proxy, the resulting error message didn't indicate that the problem was invalid credentials but instead said "the http request is unauthorized with client authentication scheme 'anonymous'". Note that you will see this same error message if you forget to change the client side config transport clientCredentialType to Basic from None. That doesn't really help when you're trying to figure out if you're making progress, I'm afraid. If you forget to give credentials at all after setting up IIS and the config files, you will see a message indicating that you have to pass credentials though.

Here are some links that helped me:

Alan Smith's excellent webcast on WCF Security using Basic Authentication
http://bloggersguides.net/media/p/1804.aspx
(covers how to fake out the SSL for development and steps through setting up the security on a local machine with a local account)

Some MS resources:
http://msdn.microsoft.com/en-us/library/ms733775(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms731925.aspx

but much of my work was just trial and error. So hopefully google will pick this up and I'll help someone with these scattered thoughts.

Cheers!

Thursday, March 19, 2009

A must-read link on application security

A very interesting link from the Dept of Homeland Security regarding (you guessed it) application security:

http://cwe.mitre.org/top25/#CWE-20