in

Fort Worth .NET Users Group

Dot Net Tricks

  • Deleting all records in all tables in the entire database using NHibernate


    This is a great little code snippet I thought I'd share.

    Before each one of my NUnit or NBehave tests, I clear out all the records from the database using NHibernate.  Unfortunately, NHibernate's HQL doesn't seem to do cascade deletes, so you have to delete your tables in the right order.  Otherwise you'll get referential integrity errors such as "The DELETE statement conflicted with the FOREIGN KEY constraint" and the query will fail.  I didn't want to have to explicitly delete each table in order either--I just wanted to loop through all my NHibernate mapped domain objects and wipe them out.

    Fortunately there is a system stored procedure built in to sql server 2008 (and presumably 2005) as well that will disable all constraints in the whole database.  Then you can loop through all the tables and wipe out all the records, then re-enable all the constraints.

    Below is the final code:

    protected virtual void DeleteAllObjects()
    {
        var types =
            typeof(DomainObject).Assembly.GetTypes().Where(
                type => type.BaseType == typeof(DomainObject) &&
                !type.IsAbstract)
                .ToArray();

        GetSession().Clear();
       
        using (ISession session = GetSession())
        {
           

            this.RunSqlNonQuery("EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' ");
            foreach (Type type in types)
            {
                session.Delete("from " + type.Name + " o");
            }
            session.Flush();
            this.RunSqlNonQuery("EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'");
        }
    }

    protected void RunSqlNonQuery(string sql)
    {
        var session = GetSession();
        var cmd = session.Connection.CreateCommand();
        cmd.CommandText = sql;
        cmd.CommandTimeout = 120;
        cmd.CommandType = CommandType.Text;
        cmd.ExecuteNonQuery();

        session.Flush();
    }

    The first method uses reflection and linq to find all classes that inherit from "DomainBase" which is my base class for all NHibernate persisted domain objects.  If you have an interface or attribute something that should work as well, although I like having a base class to put in "global" domain logic. 

    The second method is a utility method I use to run straight sql commands against NHibernate.  I"m not sure if it could be refactored to use NHibernate's built in ISession.CreateSqlQuery() method because this doesn't return any results.

    So that should be all you need.  Just turn off constraints, loop through and delete all the types using HQL and turn the constraints on again.

    I know its cliche' but happy coding. 

     

  • ASP.NET MVC - Multiple buttons on a single form.

    I haven't posted in a while do to being busy with my new job, but I thought I'd just share this code snippet. 

    In the new asp.net mvc framework, you often have the need for a single form, but multiple buttons that each post to a different controller action.  In webforms you didn't have to worry about this as all forms did a postback and asp.net created event wiring magic to wire up each button to an event handling method.  But with MVC, we're forced to go a little old school.  So I created a little helper method that I'll probably submit to MvcContrib or something if they don't have one like this already.  It lets you wire up controller methods to each submit button in a strongly typed fashion using lambda expresssions. 

    Here's an example:

       <% using (Html.BeginForm())
          { %>
      
        <h2>About</h2>
        <p>
            Put content here.       
            <%= Html.SubmitButton<HomeController>(x => x.DoSomething(), "Do something now")%>
            <%= Html.SubmitButton<HomeController>(x => x.DoSomethingElse(), "Do something else")%>
        </p>
        <% } %>

    Obviously the generic parameter above called "HomeController" is the controller class and the DoSomething() is the method in that class.  I also let you specify the button label and optionally the name of the button and other html attributes.

    Here's the source code:

        public static class SubmitHelper
        {
            public static string SubmitButton<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string buttonText) where TController : Controller
            {           
                var name = buttonText.Replace(" ", ":");
                name = "SUBMIT_BUTTON:" + name;
                return SubmitButton<TController>(helper, action, name, buttonText);
            }

            public static string SubmitButton<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string name, string buttonText, IDictionary<string,object> dictionary) where TController : Controller
            {           
                return helper.SubmitButton(name, buttonText, dictionary  );
            }

            public static string SubmitButton<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string name, string buttonText) where TController : Controller
            {
                var link =  LinkBuilder.BuildUrlFromExpression<TController>(helper.ViewContext.RequestContext, helper.RouteCollection, action);
                  var dictionary = new Dictionary<string,object>();
                  dictionary.Add("OnClick", "this.form.action = '" + link + "';");
                return helper.SubmitButton(name, buttonText, dictionary);
                           
            }

        }

    For this to build, you must reference the Microsoft.Web.Mvc dll and namespace, which can be found here:
    http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471

    or click below to download directly:
    http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471#DownloadId=61773

    Enjoy!
  • Giving up on the community


    I know nobody reads my blog anyway, but I still feel the need to comment (rant) to the blogosphere. 

    The back story goes like this.  Joel Spoelsky said some pretty irresponsible things in an interview, calling SOLID principles bureaucratic and saying "(code) quality doesn't matter."  Jeff Atwood more or less agreed with him and posted the Ferengi Programmer.  There has been a lot of outrage and debate and even Jeffrey Palermo has commented on his blog as well as various codebetter people.

    Here's some context I borrowed from  Jeffrey's site.
    Original published audio programFirst response by Robert MartinAttempt at clarification by Jeff AtwoodFurther backing of SOLID principles by Robert Martin.

    So there's all this discussion flowing about, about whether or not SOLID principles are useful to programmers or not and finally we have Jeff Atwood's latest response:
    Read Ulimate Programming Power

    I feel the need to respond, because in the second paragraph of this post, he quotes my comment:

    The majority of developers do not suffer from too much design patterns, or too much SOLID, or agile, or waterfall for that matter. They suffer from whipping out cowboy code in a pure chaos environment, using simplistic drag & drop, data driven, vb-like techniques.  

    And Jeff responds:

    Absolutely.

    But here's the paradox: the types of programmers who would most benefit from these guidelines, rules, principles, and checklists are the least likely to read and follow them. Throwing a book of rules at a terrible programmer just creates a terrible programmer with a bruise on their head where the book bounced off

    He's basically that we can't help the people that aren't interested in learning.  And I think thats true to some extent.  The problem is, he wants to throw up his hands and not help everyone else.  They'll just "figure it out" on their own somehow.

    My first career programming was done in Coldfusion.  After working on a few web projects, I became dismayed out how quickly things deteriorated into what would now be considered "spaghetti code".  Of course, at the time I didn't know that the code was the problem.  I thought maybe the vendors would eventually come out with better tools or a better IDE to manage all this complexity. 

    Instead, my friend and co-worker Ashe, came across a methodology for Coldfusion, called "Fusebox."  Fusebox was a set of rules and conventions for structuring your web application.  I wasn't even Layered or MVC or Object-Oriented or anything like that, although there were some shared principles, such as separating your data access code into separate files.  Mostly it was bringing structured programming to a procedural environment and some naming conventions.   After I started using Fusebox for a while, the light bulb (ha ha) went off in my head.  "The real problem," I thought, "is not the tools or the IDE or the Coldfusion language.  The real problem...is ME!"

    After that I was hooked.  Hooked on not just learning new tools or syntax or libraries from vendors, but on improving myself as a programmer, on improving my craft.  When I migrated my skills to .NET, I kept trying to not only absorb syntax, but also OOP, layered design, patterns anything that would help me tame the chaos that is always at our heels when writing code.

    Yes there are those that will never learn and don't want to learn.  I'd like to think that they are in the minority, but probably not.  But there are also some who just need some guidance, some little push in the right direction, and aren't there yet.  And there's a lot of us that really want to improve that are hungry to become better at their craft.

    I can tell that i'm not nearly done yet.  I have been coding professionally for almost 10 years now, and I can tell that I still have a lot to learn.  Frankly, I can tell I'm not near where a lot of the Codebetter guys are, in overall knowledge and skill.  I'm certainly no uncle Bob or Martin Fowler.  I wish i could learn faster, but its hard with a family and bills to pay.  But I'm always trying.

    For those of that want to be learning, we really need Design Patterns, SOLID, TDD, DDD, Agile, OOP and the rest.   OOP has helped me so much with complex business logic.  I'll probably never do another work flow application without some strategy or state pattern.  MVC has helped me make sense of how to better structure web applications.  Domain Driven Design has really helped me figure out how to structure large enterprise development with databases.  How did I learn about all this stuff?  I read books.  I read blogs.  I asked questions.  In essence, I took from the knowledge of those that came before me.  Yes its a lot to learn and I still don't have it all down.  But each piece I absorb is another notch in my belt that makes me a better programmer. 

    Jeff also talks about marketing and relgion, and I agree there's a lot of that in the programming community and also a lot of the agile and alt.net world.  But there's also marketing that's been coming out of Microsoft and other vendors, as well as hundreds of "24 hours to learning Foo Programming" books that seem to suggest that if you learn a few drag and drop techniques and some basic syntax, you can be a professional programmer.  Just recently, a friend of mine who was learning .NET for the first time was asking me some questions about data access and code behind and I started talking about OOP and ORMs and layered applications.  He said "None of the books on .NET teach you any of that!"  He's right of course.  Part of this is natural.  If you are reading beginners book you're unlikely to hear about something like Repository Pattern or Separation of Concerns.  But some of this is because this is how the vendors market programming. 

    There's no paradox Jeff.  All these "Rules and Regulations" are here for those of us that want to find them.  Certainly we all need them.  Yes there will be some that remain oblivious.  There will be some that have it sink in only a little.  There will also be some who really start absorbing it to become professional programmers.

    So I feel we need other voices standing up as professionals to balance out the natural apathy as well as the bad marketing that comes from vendors.  As others have already mentioned, our industry is so young.  Every other industry has a deep set of rules, guidelines and principles to work off, even if they break them once in a while.   Right now, we need people shouting out principles and better ways of doing things in the hopes that some people who get hit the with the book will turn and look around and see whats up.   Stop coding for a second, and start learning how to be a coder!

  • Introducing SNARF


    I'm now part of two open source project, although this one I really want to be hands off.  So if anyone is interested in taking it over, feel free.  Here's a description from google code:

    SNARF (Simple, Nhibernate, ActiveRecord Framework)

    This is a C# .NET class library and set of Codesmith templates for generating code using the ActiveRecord pattern.  It uses NHibernate for the underlying persistence in a fashion similar to Castle ActiveRecord.  However, it differs in that the database generates the classes as well as xml mappings and does not use attributes.  It does make some assumptions about your database schema. 

    Its been used in production, but has only been tested with Sql Server 2000 and 2005.

    Snarf is good for small-medium size projects because we feel thats also what the ActiveRecord pattern is good for.  However, should you need to switch to something heavier (DataMapper/Repository) you have the full power of NHibernate at your disposal.


    I released SNARF on google code.  Its something I built in my spare time for work, but since I no longer use the ActiveRecord pattern for larger projects and want to concentrate more on upgrading/rewriting WilsonORM, i'm releasing snarf to the wild. 

    You can find Snarf here:
    http://snarf.googlecode.com/

  • I'm part of an open source project!

    I'm contributing to the Wilson O/R Mapper project which is now open source and on google code.  I'm adding fluent mappings for WORM in the same manner as Fluent NHibernate.  Exciting stuff!

    http://code.google.com/p/wilsonormapper/source/browse/#svn/branches/FluentMappings/Wilson.ORMapper/FluentMappings



  • Found some good code today

    I'm hoping this won't offend any of you out there, but most of us developers write crappy code.  I'm not fully sure why this is, but even if the database isn't a steaming pile of horse poo, the code usually is.  There's often a lot of code duplication, methods and property names that don't make much sense, large, "god-like" classes, massive amounts of nested "if" or "case" statements, etc.

    I'm not even getting into ORMs, design patterns, DI, Loose Coupling and High Cohesion, Unit Tests or anything like that.  Many programmers don't follow basic, good, structured programming tactics.  You have to walk before you can run but it often seems like a lot of programmers, even those with 10+ years of experience are still crawling.  My screaming about database normalization at Telerik is an example of this, and we just ran into another vendor with few relationships in their database, zero constraints and a whole lot of duplication.  Fortunately we do not have their source code (although I hear its in VB.NET.)

    But enough of that.  Today I found some REALLY GOOD CODE.  Its not perfect--no code is--but its really high quality.  It comes from a little product that always has a soft spot in my heart, the Wilson O/R Mapper.  This was the first ORM I really liked.  You should pull it down and take a look at the source code. It used to be a commercial product but Paul Wilson open sourced it some time ago.

    Even though NHibernate is our standard right now and does a lot of great things, I've been toying.with the idea of writing a new ORM or extending an existing one.  NHibernate has a lot of complexity, and as Robert pointed out to me, its difficult to get working with a remoting or WCF type architecture for smart clients.  NHibernate also has a lot of other warts, including a sometimes ugly API that is dated and based on its java sibling, complex mappings, surprises when it comes to bidirectional relationships (those of you having to create a method that looks something like this: Customer.AddOrder(order) know what i'm talking about...) and other nastiness.  Its probably one of the best ORMs out there but by no means perfect.  EF still isn't out as far as I know and has a lot of growing up to do.  So i've been thinking of working on my own ORM, without starting from scratch.

    I could try extending the NHibernate codebase, but its plain ugly.  Many of the failings I just mentioned above live within the NHibernate source.  I'm not sure if this is NHibernate showing its age or what, but I'm afraid to try to alter anything within it.  Everything is big, complex and hairy.

    So imagine my surprise when I downloaded the latest source code to Wilson ORM.  Small, concise methods.  Highly cohesive classes.  Appropriately named classes, methods and properties.  Good use of interfaces.  Minimal duplication.  Everything is broken up into logical chunks.   In short: "GOOD CODE".  To be fair, Wilson doesn't do everything that NHibernate or some of the other mappers do, but even still, the codebase and API simplicity is impressive.  Its so easy to be bitter and jaded about bad programming, so I thought it appropriate to say "well done" to Paul Wilson and the other developers that have worked on it.

    I encourage you to download the thing just as a learning experience. 
  • Die Code-Behind DIE!!!

    As mentioned in previous episodes, my team is standardizing on the ASP.NET MVC Framework for web development.  One thorn in our sides has been that by default, Visual Studio would create a code-behind for your views automatically, and if you wanted a view that used a strongly typed model, such as ViewPage<Person> or ViewPage<ProductCollection> then you had to create a code-behind file.  There were CLR hacks to do this in the code in front, but they were just awful.

    In webforms, code-behind made sense, in MVC not so much.  I think they tend to encourage developers to write code in the old webforms way, and not use the controllers and helper methods as much.  One of the reasons to move to MVC is to return to simplicity--no page events, no controls, no viewstate.  Code-Behind is a blemish on that simplicity.

    Well the nail has officially been driven into the coffin for our old friend code-behind.  In the next version of MVC, it can go away completely:

    http://weblogs.asp.net/scottgu/archive/2008/12/19/asp-net-mvc-design-gallery-and-upcoming-view-improvements-with-the-asp-net-mvc-release-candidate.aspx

    You can still add code-behind if you are perverted, twisted, abomination of a developer, but its no longer there by default.

    DIE Code-Behind!  DIE!!!

    (oh and normalize your fucking databases.)
  • For the love of God, Normalize you databases!


    Despite that stupid presentation about "normalization is for sissies" that went around the net for a while, I'm very pro-normalization. Normalization and the standard Third Normal Form (3nf) simplify data management and application development greatly.  This is especially true when writing object-oriented code or using an ORM, but I normalized long before I knew what an object was.  For SOME reason, there's developers still out there that choose not to normalize.  I ran into this problem quite a bit when I worked for a certain online matchmaking company.  They had a lot of denormalized tables and it made the application more complicated, although that was the tip of the iceberg in the IT and general mismanagement at that company.  I won't say what company it was except that it was a truly interesting experience.  In a bad way.

    Again, denormalization has reared its ugly head today.  This time with a company and product I WILL mention, Telerik's Sitefinity.  Overall, Sitefinity has some good features but upgrading from one version to another is always a pain.  Today we ran into an issue that that we blew hours on and could have been easily avoided with a little 3NF magic.  Below is the forum post to Sitefinity.  Its a bit of a rant, but I want to illustrate to all you other developers the kind of extra problems you run into when not normalizing.  Note that I DO say there are times for denormalization, but its one of those cases where you have to know the rule in order to know when to break it.

    Posted at:
    http://www.sitefinity.com/support/forums/support-forum-thread/b1043S-bthhde.aspx

    We did a 3.x to 3.5 upgrade this week on one of our existing websites, and ran into some pain.  On of our other developers spent 4 hours working on it, which in fairness is partly because we have our own customizations in the site.  However, he got stuck on one particular error.  The error could have easily been avoided if you would just NORMALIZE YOUR DATABASE.  Its really not that hard and would help us developers greatly.  I'm not sure if its your developers that don't normalize certain things or if its Nolics itself, but not normalizing means more room for these types of errors and more data that has to be touched when somethings changed.  Below are the steps I as the lead developer had to go thru to debug and correct this problem:

    So the other developer was getting this error related to the Sitefinity upgrade that said “Key not found for value UpcommingEvent.”

    "Upcomming" was misspelled so i figured the error was related to the Sitefinity developers correcting the spelling.

    Looking through the stack trace, I saw it was trying to parse this value from into an enum and not finding that string in the enum thus throwing the error.

    Since all the code had been completely replaced by the new version (3.5) I assumed the problem had to be in the database.

    There are like 100+ something tables in Sitefinity, so going thru them one by one was out of the question.

    I opened up sql profiler, ran the page again and collected all the generated queries to the database from sitefinity.

    Nothing in the queries mentioned “UpcommingEvent” so instead I ran all the queries that profiler found and looked at the results.

    I converted the query results from grid view to text view in sql management studio.

    I then did a find for UpcommingEvents, and found the text!

    I found the query that got that result to find the table and column holding that event, something like "sf_cmscontrolproperty" and "value".

    I did a LIKE search on that table and column to find all the records that had “UpcommingEvents”.  19 records had this text in it!

    Not knowing what the right value was to put in there, I did a search in vs.net in object browser for anything that had “Upcoming” (spelled correctly) in the hopes I would find an enum with this value and that this would be the correct value.

    Sure enough there WAS an enum and it had 3 values, something like PastEvents, CurrentEvents, UpcomingEvents (spelled correctly.)

    I copied the exact enum value into sql query analyzer and updated the 19 records from “UpcommingEvents” to “UpcomingEvents”

    I ran the site again, and it was fixed.

    This took over an hour.

    If the database had been normalized, with just the value of the enum (the integer) in the database, this could have been avoided.  You could have changed the names of the enums without hurting the data at all, as long as you didn't change the underlying values.

    Anytime you see repeating data (in this case "UpcommingEvents" your breaking normalization and creating work for yourselves and/or your customers.  3NF has been around for a long time, I'm not sure why so some people choose not to use it when it prevents a slew of problems.  Its okay to denormalize certain data thats non-authoratative and can be recreated from normalized data (such as for reporting) but this wasn't the case.

    Thanks,
    Craig

  • TDD + Resharper Payoff - Refactoring

    So the project i mentioned the other day in my last post has had minimal need for refactoring.  Part of that is because I'm such a super badass developer who always gets things right the first time (yeah right), and part of it is that the project is small enough and young enough that there isn't need for massive changes yet.

    But today, there was some stuff that had been bugging me, so I decided to do some cleanup, aka refactoring.  Specifically:

    • I changed the names of 4 classes.
    • I changed the names of a bunch of interfaces for the above classes.
    • I changed the name of a persisted property.
    • I changed the field in the database for that property.
    So I made these changes and Resharper took me 50% of the way there towards keeping my existing functionality intact.  It renamed all the references, strings, my NHibernate XML Mapping files, dictionary names, and all sorts of things.

    But then I ran my unit tests.  I found all kinds of things broken from the refactoring.  Within minutes i had all this fixed and working properly.  Finally I had to do a quick regression test thru the web layer, and found a few things here and there that had to be fixed.  This was only necessary because I haven't really tried creating Unit Tests for my Views, although apparently other people have.

    In another, testless, project this would have taken a lot longer, in the realm of a few hours instead of only minutes.  But this was only a small project that i've been working on and off for a few months.  Imagine something on the scale of a 6 month project or a 2 year project with multiple developers. 

    I'm starting to get hooked.  TDD hasn't really started to pay off until now.   If you care about refactoring, you owe it to yourself to really try TDD.



  • My current architecture

    For the six or seven of you in the world that actually read my blog, you've noticed that i've been pretty quiet lately.  So while i'm chomping down breakfast before work, I thought I'd give you a rundown on what i've been doing lately.

    I'm working on a medium size project that eventually may blow into something larger, which given the current economy would be great.  Its a front facing, product catalog, type web project, but there will soon be a comprehensive suite of admin tools, reporting, integration with other systems, etc.  So I'm trying out a new (for me) architecture for this site because I can tell it may grow into something much bigger than it already is.

    So without further adieu, here is my current architecture and toolkit for this project.

    1. ASP.NET MVC - Microsoft should have done this years ago.  Its a refreshing return to simplicity.  I've already written about why webforms suck.  So if you haven't checked out MVC you should.
    2. NHibernate - Its not perfect, but if you are practicing Domain Driven Design and want to build objects that have little or no coupling to persistence logic, this is the defacto standard ORM among open sources ORMs.  I tend to shy away from the HQL as there always seems to be something missing from the language, but the criteria classes work nicely.  Of course, you can always drop back down to HQL or SQL and there's a LINQ to NHibernate in the works.  Overall, I've been pretty happy with it.
    3. DDD - First off, I'm not a domain driven design expert.  But I'm trying to incorporate it as much as possible into this project.  I have domain objects for domain logic, repositories for data access (which use NHibernate) and service objects for other business logic that doesn't belong to a single domain object. 
    4. Service Objects - While I'm on the DDD topic, i've started using "services" a lot more, which is a DDD concept.  What's an example of this?  Well, I have a UserRegistration service that takes a user object, saves it using a UserRepository, and sends an email notification using an EmailService which sends the email.  I didn't want all that logic in my controller (and you webforms people shouldn't put that stuff in the code behind!), so I refactored it into a UserRegistration service.  I also didn't want it in any domain object, because it needed to coordinate domain logic, persistence logic and the email service. I have another situation where I have a purchase inquiry where the user submits a PurchaseInquiry object that has a reference to the user, and a reference to the product they're interested in and a few other fields and saves it to the database.  But I also need to send an email and integrate into a third party CRM.  So I have a PurchaseService that saves the PurchaseInquiry (again using a "PurchaseInquiryRepository" ), sends the email using an email service and then calls into the CRM service to do the integration.  I've really been pleased with how  this "service layer" works in these complex scenarios and keeps this logic in the business layer where it belongs. I don't make service object for everything--just the places where coordination between different domain objects, services and repositories is necessary.  Also, you want to avoid the dreaded "anemic domain model" that can be a temptation when using services.  My domain objects still have a lot of behavior, but they don't cross network boundaries into outside systems (such as database, email, web services, etc.)  For these sort of thigns, I put the logic into services.  I'm not sure this is the "official" DDD way of using services, but this has been very useful to me.
    5. JQuery - So we're not using webforms, so what do we use for controls?  Although you can use controls in MVC, part of the extra complexity in traditional webforms came from controls that contained server side and client side code (C#, Javascript, CSS) and tried to package them all together.  Styling and customization was a constant issue with many of the controls I've used and many of the useful things that controls did (such as maintaining state) no longer work in MVC's non-postback environment.  Fortunately Jquery has a suite of UI widgets, called JQuery UI and you can use these almost like server controls--you just add markup and a tiny bit of javascript to wire them up and you have tabs, menus, etc.  I'm very pleased with JQuery so far.  Ajax is especially simple.  With asp.net ajax, you have to have that stupid script manager tag, (but ONLY ONE script manager tag or you get an error), and the web.config settings, and the tags in the page to set up specifically what you are doing.  With JQuery, i write 2-3 small lines of code and they can call a controller method in MVC directly, get the results and update any part of my page. 
    6. TDD + NUnit - I'm trying out this whole Test First methodology. I've done some TDD in the past but never went gung-ho the way I am with this project.  I have integration tests for all my data access and unit tests for domain objects, services and controllers.  Eventually I'm going to swap this out with MBUnit which is supposed to be more feature rich, but I started with NUnit because that's what I know.  So far, I can definitely see SOME of the benefits of doing Test First development.  It definitely makes refactoring easier, but I don't see a massive drop in defects.  I usually code in a somewhat loosely coupled and OO manner and don't normally have dozens or hundreds of bugs in my projects, but on the other hand the projects i've done lately have been pretty small.  Maybe as this thing grows, TDD will shine even more.  Right now its taking some getting used to, and all the "extra" code is annoying me.  I'm also using Rhino mocks for mock objects, but as this was a huge learning curve for me I'm not ready to write about it now.
    7. General "Onion Architecture" - Much of what I've talked about above comes straight from Jeffrey Palermo's Onion Architecture and his Agile Bootcamp class.  So I'm also doing things like loose coupling between layers using Dependency Injection and Structuremap.  If you haven't looked at DI, you should.  The learning curve is very minimal and changes very little about how you write your code.  A few interfaces here, a constructor there, a tiny bit of configuration and poof!--Loosely coupled architecture!  Okay there's a little more too it than that, but TDD by far is a much larger paradigm shift.  With the DI, I've got my NHibernate mappings and repositories in a separate project that gets hooked up to my domain layer at runtime, so the implementation of the ORM and data access stuff is completely decoupled from the rest of the application.  
    I thought about scattering links to all this cool stuff in my post, but instead I'll just put it all here at the bottom in one convenient place:

    ASP.NET MVC
    http://www.asp.net/mvc/

    Also see MVCContrib for other MVC goodies:
    http://www.codeplex.com/MVCContrib

    NHibernate
    http://www.hibernate.org/

    Domain Driven Development
    http://domaindrivendesign.org/

    There's also the classic book by Eric Evans:
    http://domaindrivendesign.org/books/index.html

    But i cheated and got the cliff notes version:
    http://www.infoq.com/news/2006/12/domain-driven-design

    JQuery and JQuery.UI respectively:
    http://jquery.com/
    http://ui.jquery.com/

    NUnit and MBUnit:
    http://www.nunit.org/index.php
    http://www.mbunit.com/

    Onion Architecture
    http://jeffreypalermo.com/blog/the-onion-architecture-part-1/


  • ASP.NET Sucks and It DOES Matter

    This is partially in response to this somewhat infamous article by Jeff Atwood:

    http://www.codinghorror.com/blog/archives/001119.html

    In this Jeff mentions that although PHP as a language and platform sucks, it doesn’t matter.  Its low barrier to entry has allowed PHP to become the defacto standard for major and minor websites all over the internet, as well as many decent software packages, such as shopping carts and Content Management Systems.  The fact is there is a lot of great software written in PHP, despite the language’s overall suckiness. 

    With ASP.NET, my web framework of choice, things are a little different.  Sadly, I must confess that ASP.NET also sucks, although in a different way, and in my opinion it does matter.  This limits the number of decent free and even commercial software packages.  Trying to find a decent, user friendly, engaging software package such as a shopping cart or CMS in ASP.NET is difficult at best, especially if you want one for free.  ASP.NET may hold a place of distinction among enterprise applications and large corporate websites, but in the world of social networking sites, shopping carts and the like it’s virtually a no show.  On the enterprise ASP.NET has done rather well, competing with the other heavyweight: Java.  But for basic websites, it well….sucks.  At the web shop I work at now, I had almost come to the conclusion that asp.net is the wrong choice of technology for us or at least for the majority of our small business customers.   Our sites are too small, the work and overhead of ASP.NET make development too slow for these simple projects and the lack of good software packages such as shopping carts and Content Management Systems put us behind our competition.

    Take for example, our CMS.  We’re using arguably one of the best commercial CMS applications on the market for asp.net and still the software is complicated to install, upgrade, extend, style and manage.  Our clients have issues as well.  Drag and drop is supposed to work, but it doesn’t in certain circumstances.  The WYSIWYG editor adds extra span tags or shifts formatting and spacing around seemingly at a whim.  The user experience could be a lot better and faster.  I can feel the weight of viewstate with every click in that CMS.  In the shopping cart arena, things are nearly as bad.

    So why is it that PHP sucks and yet there are tons of websites and really good software packages for it, many of them for free?  With ASP.NET, it’s difficult to find good applications, especially among the open source community.

    First, there is the overall learning curve of ASP.NET.  I’ve already documented a lot of the ways in which ASP.NET sucks so I won’t go into too much of that here.   Search google for “ASP.NET sucks” and you’ll get a lot of really valid points from people that apparently are a lot smarter or less stubborn than I am, because they gave up on it back in version 1.1.  Suffice it to say, ASP.NET development is complicated and much harder than it needs to be.  But it goes beyond that.  Its also a very difficult paradigm to understand for anyone familiar with other web technologies: html, css, flash, javascript, php, java/jsp, coldfusion or even classic asp. ASP.NET looks, feels and acts different than almost any other server-side web technology, and integrates poorly with the client technologies.   ASP.NET is almost entirely ignored by web designers.  The barrier to entry for the average web developer or designer means that it has not become the standard it could be, at least for the average website market.   I can some up this barrier to entry in two words: “Web Forms”. 

    The Web Forms paradigm that ASP.NET is based on is both a blessing and a curse.  On the enterprise where ASP.NET does well, web forms is a blessing, at least historically.  This is because it mimics a forms-based, stateful, event-driven technology such as win forms or even java desktop applications.  The web forms abstraction makes web development seem similar to desktop development.  Where this created hurdles for existing web designers and developers trying to learn ASP.NET, it lowered the barrier of entry for existing desktop programmers doing Visual Basic, Java, Visual C++ and heck, even Microsoft Access.  In addition, the object-orientation of the .NET Framework and Microsoft’s two revered languages, C# and Visual Basic.NET, was attractive to programmers coming from a Java, C++ or Visual Basic 6 background.  .NET has a simpler class library and structure than COM or VB did, and is familiar to the point of Déjà vu for java developers.

    But for your average web designer, who may be an Html, CSS and Javascript guru, ASP.NET is an anathema.  Take for example the ASP.NET control hierarchy.  Using server controls in ASP.NET means that Html is generated in a way that interface designers can’t control very well.  Sure they can slap a “CssClass” attribute on most controls but the actual Html generated is hidden from them and can throw a lot surprises their way.  Worst still, this generated code messes with the Html tag hierarchy that a lot of designers rely on in their CSS and Javascript.  Usually designers will get used to the built in server controls and figure out their idiosyncrasies, but as soon as you throw in a 3rd party control, it’s a whole new ball game with a new set of rules, quirks and surprises.  We’ve gone thru a lot of this trying to skin third party controls and both myself and our interface guys have pulled our hair out trying to get the CSS “just right” in order to properly style a control that spits out mountains of Html and javascript and CSS of its own that we can’t see until runtime and which has a lot of dependencies on certain CSS classes, Ids and tags.  Its just TOO HARD.

    But the cardinal sin of ASP.NET is how it deals with the all-important Html ID attribute.  I can’t say this strong enough, so forgive my crudeness, but ASP.NET RAPES the ID attribute.  At my second ASP.NET job, my manager was constantly asking us to do challenging and interesting user interface tweaks using JavaScript, and every time he did I just groaned inwardly in a way that I never had to with Coldfusion or classic ASP.  ASP.NET in its effort to emulate that stateful, event driven, desktop paradigm, goes and wreaks havoc with the all the server controls’ ID attributes.  ASP.NET dynamically changes the ID attributes of any Html that is generated by a server control.  So you have to ask for the generated ID through server-side code.  The ID can’t just be hardcoded because it may change at runtime depending on the hierarchy.   So what was once a simple integration between Javascript and server-generated Html now requires the developer to expose the control’s ClientID to javascript thru nonsense like this:

    <%# this.textBox1.ClientID %>

    Which also requires a call to Databind() somewhere because using Response.Write or <%= %> causes the infamous “control collection could not be modified because the control contains code blocks” exception. 

    In addition, web designers also rely very, very heavily on the ID attribute and tag hierarchy for coding CSS.  So when the tag hierarchy and IDs either are not known or they change for the same reason, this breaks the designers CSS and causes them a lot of headaches to get them working.  Unfortunately, ASP.NET does both, so it makes styling a page like trying to hit a moving target. 

    In other words, it now requires a programmer who remembers all these ASP.NET quirks to get the user interface working, and looking, right.

    Finally, ASP.NET’s web form model adds a huge learning curve from those coming from other server-side technologies.  PHP, Classic ASP, Ruby-on-Rails, Coldfusion, JSP  (perhaps excluding Java-server faces, which I know almost nothing about) all have similar ways of doing something.  You markup an Html page and embed server side code in it, usually using some kind of separate tag syntax.  Web Forms don’t really work this way and Microsoft doesn’t really encourage it.  What they were trying to do was noble—they were trying to separate markup (html) from presentation logic (C#, Java, VB, etc.)  Whereas the other technologies mix them together, Microsoft was rightly trying to separate them out.  And I have to admit that a well designed aspx page and its code-behind is a beautiful thing to behold.  The aspx contains only Html and Server-Control tags, and the code-behind contains only C#. 

    But consider this, let’s say I have a  grid on the page full of tabular data containing customers and their current balance.   I want the Customers being displayed on this grid that have a balance greater than zero to have their balance highlighted in red.  What is involved in accomplishing this relatively simple presentation task?  Just breeze thru the following steps…

    1. Wire up the GridView’s ItemRowBound event to an event handling method.
    2. In the event handling method, check that the current row’s data item isn’t null (this avoid exceptions because the headers and footers don’t have data associated with them.)
    3. Create a local variable for the Customer data, like a Customer object, dataset, etc. 
    4. Now cast the row’s data item to whatever you’re binding to—the Customer object, DataRow, etc.
    5. Oh, wait if you’re binding to a dataset, you have to cast the row’s data item to a DataRowView, not a DataRow.  After 6 years of ASP.NET, I still don’t know why that’s necessary. 
    6. Now that you have your data, check the customer’s balance to see if its greater than zero.
    7. Now use FindControl on the current row of the GridView to find the control  (label, textbox, etc.) that contains the balance, or use the row’s Cells properties if there’s not a control nested in there.  If you have a control, you also have to cast it to a control.

    Now, I’m not being completely fair, because part of the work above is not the fault of ASP.NET, it’s the fault of a strongly typed language with all its casting necessity.  But much of the casting would be unnecessary even in JSPs which use another strongly typed language. 

    When I first was learning asp.net and tried to do the above tasks, I was lost.  My instinct was to start a “for loop” and put in one “if” statement and be done with it, but that was not really feasible with a DataGrid, and probably wouldn’t be recommended by Microsoft or the ASP.NET community.  I had a long learning curve ahead of me.  Now after 6 years of ASP.NET development under my belt, it’s a piece of cake and I do enjoy the separation of concerns.  But I suspect a lot of web programmers coming from other server-side platforms, took a look at all this crazy web forms stuff and swore it off.  Its different, its complicated and it slows down development. 

    Which goes back to what spawned this post.  Why is it so many public facing websites are written in PHP, and there are so many great shopping carts, CMS’s and other free software for it?    Why are there so few for ASP.NET?  Its because ASP.NET was designed for desktop programmers and almost completely ignored existing web designers and web developers. For all its flaws, for all its lack of object orientation, its global functions, its quirkiness and ugly syntax, PHP is friendlier to web designers and web developers.  It’s friendlier with CSS, Javascript and by extension, all the cool UI toolkits out there like Dojo, Scriptaculous and Prototype.  This doesn’t make it better, and I’d certainly choose ASP.NET in a heartbeat for a complex, line of business, web application over PHP.  But if you need a small to medium size website up quickly and cheaply, nothing beats PHP and its slew of free, open source, scripts and applications.

    I believe there is hope for ASP.NET however.   Ironically, this comes not from some quick and dirty code-generating, drag and drop toolkit that Microsoft is throwing over the wall, but for something that was designed to fix some of the alleged flaws in the web forms model for enterprise development.  Enter the ASP.NET MVC framework. 

    According the ASP.NET website, the MVC framework and the design pattern its based upon has the following benefits:

    • It enables you to achieve and maintain a clear separation of concerns
    • It facilitates test driven development (TDD)
    • It provides more control over the URLs you publish in the application and over the HTML that is emitted by the application

    The first two bullets will probably not make a blip on the radar of most web designers.  But the last part, about full control of the Html, as well as other deviations from web forms, could actually lower the barrier of entry to ASP.NET development.  MVC styled development isn’t going to muck with my html tags, it’s not going to change the ID attributes, there’s no viewstate, there’s far less reliance on events and controls.  Forms can post anywhere.   You can throw an “if” statement or a “for loop” in the middle of the page to generate Html without it being quite a sacrilege.

    So besides solving a lot of the “enterprisey” problems such as better separation of concerns and TDD, it may actually make web development friendlier to web designers and non-ASP.NET web programmers.  Maybe there won’t be an immediate slew of well designed MVC shopping carts and CMS applications, but there might be a renewed interest in the ASP.NET platform from designers.  So in a sense, ASP.NET developers can now get the best of both worlds: Enterprise friendly architecture, and web designer friendly simplicity.  I can get my nice C# objects and the elegance of the .NET framework class library, without dealing with web forms complexity.  There might be hope for ASP.NET yet.

     

     

     

  • sql server management studio has “backup sets” and “destinations on disk” disabled

    I ran into this little gotcha a little while ago, so I thought I’d share it and break my blog silence.

    One of our clients hosts their own sql server (express) and website, and I kept noticing that there was no way to do a backup.  When I went into sql management studio and tried to add a backup destination, it didn’t give an option for file name, only tape.  And the “Backup device” section was disabled. 

    Even running the “backup” command from t-sql didn’t work.   It gave me an access error.  This was my clue.  The problem was that the sql express service was running as the “Network Service” login, which didn’t have access to any folders on the file system.  I gave it access to one folder, and then Management Studio let me pick destinations from the file system.  I was also able to add backups sets and run backups from the command line.  I could have changed the network service to run as “system” but didn’t to mess with someone else’s box. 

    Pretty simple fix, but not very obvious what the problem was.
  • FWDNUG Meeting Notes and Slides

    Thanks to Stephen and the other members at the Fort Worth .NET User Group for having me speak.  I enjoyed it and hopefully my audience did too.

    I'm sorry this has taken a while to post, but as promised I have all the slides and a list of resources like Fowler's POEA book in a big zip file.  Also there is a VS 2008 solution with a code snippet using ADO.NET Entity Framework Beta 3.  You can download the whole thing here:

    http://www.dotnettricks.com/downloads/orm_presentation.zip

    Finally, Kevin here at Enilon was kind enough to record the whole session for posterity.  So if you missed it, you can listen to it on your mp3 player:

    http://www.dotnettricks.com/downloads/FWDNUG-03-08-MP3.zip

    Thanks,

    Craig

  • I'm speaking at the Fort Worth .NET user group

    On March 18th I'll be speaking at the Fort Worth .NET user group at Justin Brands.  The topic will be a favorite of mine: O/R Mapping Patterns and Tools. 

    Come by say hello or throw tomatoes.  Info is below:

    http://fwdnug.com/blogs/meetings/archive/2008/03/11/march-2008-meeting.aspx


  • Warn3d By CrueLSaw

    Today I got a very interesting request from my boss.  There was one of our sites that had suddenly been defaced with the following text:

    "Warn3d By CrueLSaw"

    After some research by one of our Senior Developers (Thanks Pete) he found that this CrueLSaw guy was very busy hacking into and defacing classic asp and even a few PHP websites. 

    It was our old friend sql injection--the guy had found the admin part of our site, and plopped in some sql into the password text box like this:

    ' OR 0=0 --

    Of course the long gone developer of this code didn't parameterize their sql or use a stored procedure.  This effectively let him into our site to deface it.  We're lucky that CrueLSaw only warns people and didn't truncate our tables. 

    To be fair, this site was a Classic ASP website done around 6 years ago and the developer back then probably didn't know a thing about sql injection, because few people did at the time. But some lessons are painfully learned.  The solution was simple--just use a stored proc or a ADO provider that allows paratmeterized SQL.

    If you're company's website is having this problem, then fire me an email here and I can fix it for a small fee:

    http://www.craigbowes.com/Contact.aspx

    Thanks for the warning CrueLSaw.

More Posts Next page »
Copyright FWDNUG 2008
Powered by Community Server (Commercial Edition), by Telligent Systems