Archives / 2004 / January
  • Mixing Forms and Windows Security in ASP.NET

    My latest article, Mixing Forms and Windows Security in ASP.NET, has finally been published on MSDN's ASP.NET Developer Center -- yeah!  I see questions almost daily in the forums from people asking how to combine Forms and Windows authentication -- so here's the answer finally.  This article details how to use Windows authentication for Intranet users, including capturing their username, while still providing a custom login screen for Internet users.  Thanks Kent for making this happen.

  • WilsonORMapper, EntityBroker, and LLBLGenPro

    I've apparently really annoyed Frans, and Thomas a little too, so I thought I would do something different. First, let me just say that I've never spoken bad about either EntityBroker or LLBLGenPro that I can recall. In fact, I said publicly many times that both of their products are very good and highly recommended. Why? Because as Frans noted, my WilsonORMapper is "severely crippled" if you need more than simple CRUD. That's right -- my O/R mapper is a simple tool for simple minds only -- and that's all I want it to be. Yes, I want to add cool features, and yes I have a blog to announce it, but I try to also share what I learned in the process. Does that make me arrogant? I hope not, but its not the first time I've been called that, so I'm sorry and I'll try harder, but I hope my accusers can also try a little harder please.

  • WilsonORMapper works well with MySQL

    I spent a couple of hours yesterday testing my WilsonORMapper with MySQL (note the My, not MS). I designed my O/R mapper to work with any ANSI compliant database, so I had high hopes. Note that I do of course have a few optimizations for MS SQL, Access, and Oracle, so I don't mean everything is or should be generic. I'm very experienced with Oracle, although its been a few years back, but I had never touched MySQL until now. I started by downloading MySQL v4.0.17, which was the recommended version, MySQL Control Center, and MySQL Odbc Driver v3.51. I installed everything, then I figured out how to start the server and create a database and a table pretty easily. The next thing was configuring Odbc and figuring out my connection string, and do a few small regular ADO.NET tests. So far so good -- by the way, MySQL seems surprisingly comparable to MS SQL in ease of use.

  • WilsonORMapper now tested with Oracle

    I just finished updating my WilsonORMapper to v1.1 today.  I added support for many-to-one and many-to-many relationships (already had the one-to-many case) which proved pretty painless.  I also added support for some common requests, like loading object collections with stored procedures (already supported stored procs for insert, updates, and deletes), loading datasets with only a subset of fields (instead of always loading all fields), and directly executing set-based updates and deletes (along with expressions for updates).  Anyhow, the hardest thing was that I finally got around to testing everything with Oracle 9i, so everything now works with Sql Server, Access, and Oracle (including my paged collections).  I'm using a new feature of Oracle 9i to do my inserts that rely on database-generated keys, the RETURN INTO clause, which assumes that a trigger exists that gets the next value from the appropriate sequence and includes it in the insert -- almost like identities in Sql Server and Access.  I also did go ahead and break out my “Commands” class into a provider model that makes it easy to replace my ANSI SQL for the special cases in Sql Server, Access, and Oracle, while still supporting the generic cases for all other databases!

  • Running .NET WinForm Applications on Citrix

    We have been creating a major .NET WinForm application that will be deployed in Citrix for a few months now.  Basically, think of it as a custom rewrite of MS Access (note that this wasn't a techie's idea) that works against MS SQL Server.  Of course, business as usual doesn't like any limitations, so we have way too much data and far too many features to work in a shared environment like Citrix.  Or do we?  That has been the bane of my existence for the last couple of months, and unfortunately there doesn't appear to be many others that have such experience to share.  My main concern has been whether or not the .NET garbage collector would see the 4GB of RAM and think it could have it all, unaware of the other users on the box.  I have posted that concern to various forums several times, and I've seen a few others with similar concerns, but no one ever answered, other than people telling about .NET works in general without any Citrix experience.

  • Moving from Wise to VS.NET Deployment

    What was wrong with Wise? First, I need to state that its probably just as good, if not better, if you are a build engineer that knows WiseScript, and the idiosyncrasies of Wise. I assume something similar can be said about InstallShield, but I don't have any recent experience with it to even talk about. The first problem I had with Wise was that it kept removing valid references or adding unnecessary ones, including duplicates, which became very annoying. I also started to experience crashes when I was doing several things, which forced me to start saving after every change. Then there was the fact that I simply don't know WiseScript, so I had no idea how to do the custom things that were starting to arise. The final blow was that Wise, at least not in my simpleton attempts, did not install assemblies in the GAC when it was told to do so! All the help documentation, and rave reviews, say its trivial -- just drag the file into the GAC folder in Wise -- but that did not work for us. My one attempt to fix this in a workaround by including GacUtil in the install, and then calling it to manually register my assemblies with one of their custom actions, did not work either. Again, maybe it was all a case of my being a stupid user, and I'll admit that I also never called Wise for help.

    So why the VS.NET Installer? First, I started hearing more people ask me why I wasn't using the one built into VS.NET, which got me at least thinking. Then I read an article somewhere that really opened my eyes -- sorry, I can't find it anywhere now. So I finally decided to convert my Wise project to a VS.NET Deployment project, which the wizard in VS.NET made very easy to do. I now have my assemblies getting deployed to the GAC as effortlessly as should be, and I haven't encountered many idiosyncrasies, at least none that keep happening. One problem I found is that the deployment packages won't automatically uninstall old versions, even when you tell them to check for them they just stop and tell you to do the uninstall yourself. The fix for this was to change both the version number and the GUID product code of the deployment project itself before every build. This was easy to automate since the project file is plain text, unlike Wise's project file, so I just have a command-line app that is called from my batch file that changes these things, much like it already changed the application version numbers in all my AssemblyInfo files. I also no longer have a single EXE that includes the .NET framework, but that's not a big deal with the Setup.exe bootstrapper, so I can live with that. The main thing is that now I look forward to working with it, since I can use C# or VB to write my custom actions in the future, and therefore be far more productive. Its also nice that its free (if you have VS.NET), so all of our developers can open the deployment project now if necessary, and all of our other projects can also use it, so I guess I can even say I've saved my company thousands of dollars!

  • SOA Is Not New -- Its Just Easier and "In"

    Steve and others have been talking about SOA and it got me thinking that we basically had an SOA architecture where I previously worked (Roche Diagnostics), we just didn't know that was the terminology then.  We had a GUI application that needed to talk to a variable number of medical devices, which typically had a life of their own, so that any given task initiated from the GUI could take anywhere from a second or two to 15 minutes.  They could also start doing things on their own in some cases, and we also needed to be able to easily integrate new devices on the fly as customers bought more devices, or when we came out with new ones.  The first thing we did to solve this was specify that each device could only talk to its own "controller", which knew its own unique features (or problems), that ran in its own process.  Then we defined a set of common interfaces that the GUI and each controller had to do all of their communication through, which we then registered with the COM+ Event subsystem.  This allowed us to add new devices on the fly very easily, or even "test or monitoring controllers, since neither the GUI nor any of the controllers ever talked directly to each other.  We also specified that all communication with the COM+ Events interface was done through MSMQ Queued Components, which allowed everything to occur in its own time asynchronously, without blocking, while still being guaranteed.  Finally, we also had an "aspect" service for event logging and tracing, which was totally configurable to allow us to turn on different levels of logging, for all or just some devices.  This may not have been anything "sexy" by today's standards (no .NET or web services), but it was very much a service-oriented architecture, built on COM and COM+, taking advantage of COM+ Events and MSMQ.  The only thing that I never really liked about our architecture was our data tier, which always felt way too convoluted with its stored procedures that were wrapped by COM+ components, that were finally called by the GUI.  It was too late when I started learning about O/R mappers, which would have greatly simplified things by basically making an entity service.  Of course I would have had a hard time selling the O/R mapping stuff at Roche, but then again maybe not since the business upside would have been that we could have sold our product with any database rather easily.  So in my opinion SOA systems are not anything new, although there are certainly new ways to build them, which are easier than ever, although the downside of this is that many people are building SOA systems that don't need them.  Anyhow, the principles have been around for a long time -- loosely coupled contracts, whether that be interfaces or web services, often with asynchronous independence, possibly with guaranteed delivery, running in different processes or machines, or possibly even different networks.

  • MasterPages Template Properties in .NET v1.*

    I've been asked one question about my MasterPages for .NET v1.* often enough that I suppose I should blog about it for everyone's benefit.  The question is how do you access public properties that have been exposed by the template user control from your pages that implement MasterPages.  This will be very easy in .NET v2.0, since MasterPages will contain a Master property in the Page class that will automatically be strongly typed to your master. But how do you do it today, in .NET v1.1?

  • O/R Mappers: Avoiding Reflection

    Steve Eichert posted his findings yesterday about the performance cost of reflection.  I knew reflection was slower, but I had no clue it was that bad potentially.  I haven't done many tests yet myself to see if it really is that bad, but it doesn't really matter since I can agree that reflection is definitely slow.  So why does this matter -- well, right now my WilsonORMapper uses a lot of reflection to get and set the field values.  I was planning on doing something to fix that sooner or later, but Steve's post got me thinking about making it my next priority.

  • Finishing my own Basement

    My basement consists of our drive-under two-car garage and originally two unfinished room locations.  I finished the first room as our kid's playroom in January of 2001, and then I finished the second room as my wife's craft/sewing room in January 2002.  Last year we worked outside to install a patio under the deck, and then finished with a pond in the spring.  Anyhow, my point that I'm getting to is that I never did do anything for a ceiling in the two rooms when I created them.  I don't really know why, other than the fact that I had never messed with the drop-down suspended ceilings before.  I didn't have those same reservations about building walls and installing wiring, since I had helped my Dad and others many times with similar tasks over the years.  But drop-down ceilings just seemed weird to me, and all the books and stuff have barely a page or two about doing it yourself.  Well, we really needed to do these ceilings, especially since we may try to sell our house and get a bigger one in the next year or two, so I committed to doing it this month.  As it turns out, one of my friends had recently done a drop-down ceiling in his basement, and he gave me a day of his help last weekend as my Christmas present.  It turned out to be really easy -- just careful measuring and other routine tasks.  We probably could have done both rooms, but I didn't want to ask my friend for too much when we could better spend his time drinking and watching movies.  So yesterday I did the second room's drop-down ceiling by myself, which was just a wonderful couple of hours.  What does this have to do with .NET -- nothing really, but I'll make something up if you insist.  I put off my building my own O/R mapper for similar reasons, that being that it was just something I hadn't done before.  But in the end, as long as you have all the basics down, sometimes it is relatively easy to just do things yourself.  You get the pleasure of doing it, learn something in the process, potentially save lots of money, and end up with something customized just for you, instead of something costly that someone else did that may have somewhat better quality but isn't really exactly to your liking.

  • O/R Mappers: Simple Database Features ?

    I'm going to get grilled for saying this, but I don't see why most O/R mappers leave out some very simple database things.  Note that I'm not saying I have everything down, nor do I really have any of the more complex things that some will need.  What I'm saying is that there are some things that everybody wants and are very simple that are often left out of O/R mappers.

  • O/R Mappers: Base Class or Not ?

    One of the main criticisms I've seen of most O/R mappers is that they typically require you to have your entity objects inherit from a base class provided by the mapping framework.  This can be a headache if you have your own class framework, and it can also contribute to other problems if you aren't careful.  I started out to also require a base class, since it does make things easier for the mapping framework, but I noticed that Microsoft does not have this restriction in ObjectSpaces.

  • O/R Mappers: To Attribute or Xml ?

    I learned a lot while I was creating my own O/R Mapper, so I thought a few lessons learned would be good to blog. I'll be adding a few of these over the next couple of days, so stay tuned for some other interesting observations.