CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

February 2005 - Posts

  • Weird IE Rendering Bug

    UPDATE: This is a very known issue (just not to me) and is called the  The Box Model Problem.

    I think my office mate, Brandon Boyd, found an IE table rendering bug.  Don’t know if this is a known issue or not, but this is interesting. Take this HTML Snippet, for example:

    <html>
    <body>
    <table>
       <tr>
      <td>
      <div style="padding: 20px; width: 430px; background-color: green;">
       <div style="border: black 1px solid; padding: 20px; background-color: purple;">
        <table cellspacing="0" width="100%">
         <tr><th>Column1</th><th>Column2</th><th>Column3</th></tr>
         <tr><td>1</td><td>2</td><td>3</td></tr>
         <tr><td>1</td><td>2</td><td>3</td></tr>
         <tr><td>1</td><td>2</td><td>3</td></tr>
        </table>
       </div>
      </div>
     </td>
       </tr>
    </table>
    </body>
    </html>

    In IE, this renders like so:

    But in FF, it renders nicely:

    See how it cuts off the left-hand side of the table! This looks to me to be a pretty blatant bug, not just a wierdy “my browser versus yours” rendering issue. You can view the page here, just to check for yourself.

    Anyone seen this before?

    -Brendan

    Listening to: Jens Lekman : When I Said I Wanted To Be Your Dog

  • Anyone Used Crystal Version 10 or XI?

    From Crystal Reports for .NET Feature Overview

    The Crystal Reports product as a whole resolved more than 1000 issues existing in previous versions of Crystal Reports. CR.NET was a major beneficiary of this focus in terms of product quality and stability.

    Wow. That’s a lot of issues. Good for them. Hope they got em all. Has anyone used the Version 10 in a production environment?

    Brendan

  • What is Air Code, and What's its Purpose?

    I think I first heard the term “Air Code” on DNR, although I’m not sure exactly who said it (Mark Miller maybe? Rory Blyth?)  but I think it’s a valuable and often overlooked as a tool for communicating programming concepts.  

    What is Air Code?

    Air Code  n. A bit of software code, written in a particular language, compiled using an imaginary compiler.

    This past week, I asked Sahil a question, and he replied with the following snippet of code, to illustrate a point he was making:

    partial class Program{
     static void Main(string[] args) {
     Man Brendan =
    new Man();
     
    Console.WriteLine(Brendan.MakeSound());
     Type t = Brendan.GetType();
     Console.WriteLine(t.BaseType.ToString());
     }
    }

    public class Monkey {
      public string MakeSound() {
        
    return ("RRR !!! RRR!!!");
      }
    }

    class Man : Monkey {
     
    public new string MakeSound() {
        
    return ("How do I find the base class?");
      }
    }

    The point of Air Code isn’t to write code that you expect will actually compile – it’s useful when you want to communicate how to do something in a particular language, but don’t want to worry too much about syntax. I mean, we all use ReSharper or CodeRush anyway, right? We’re going to know if the code has errors way before we hit that compile button, so why waste time compiling code?  Actually, I think Sahil’s code will compile (that’s just in his nature), but even if it didn’t it would still be good Air Code.

    How is Air Code different from pseudocode?  

    Pseudocode: n. a detailed yet readable description of what a computer program or algorithm must do, expressed in a formally-styled natural language rather than in a programming language.

    Air Code is often actually written in a particular language and it’s intentionally not formally styled.  Its main purpose is really to say “Here’s how to do this, but hey, I only compiled this with my air compiler, so don’t hold me accountable if there are errors.”  I think it’s a useful concept, because it allows you to quickly communicate an idea without worrying about someone actually trying to compile it, correct you in comments, or then email you, saying, “My compiler is saying that it can’t find the Sytsem.XML namespace!” 

    Are there any formal conventions to indicate that code is actually Air Code? 

    There are now!  I’m proposing the [AirCode] attribute to indicate that you shouldn't actually do anything as silly as try to compile the code you’re seeing.  So if if you see this attribute on my blog anywhere, it means, that the code probably won’t compile.  So  go ahead and email that code!  Blog it!  Don’t compile, use Air Code! You’ll feel liberated! 

    -Brendan

  • The Internet is Putting Companies out of Business, thank God.

    Yep. Get online or get got.  And I for one am so thankful for this.  Why? Because it’s better not to have to go to into a bank, or camera store, or even bookstore, to do the mundane business of every day life.  Wait, did I say it’s better not to go into a bookstore? Yes. Most of the time it is. Don’t get mad at me for saying this, let me explain.

    Yes, it’s better to get your books from Amazon, rather than schlep down to B&N, hope they have the book, stand in line, waste gas, etc.  But does this mean I hate bookstores?  No!  I love them.   But, only if they do more for me than simply let me buy a book.  Does this mean it’s good that the mom & pop bookstores are going to suffer?  Well, maybe if we end up with more bookstores that are fun places to be.  Think Kramerbooks, in DC.  Is Kramerbooks threatened by the Internet? I doubt it. Just look at their web site.  If they’re worried about the Internet, they’re not trying too hard to “join em.”

    But that only happens in a big city, like DC, right?  Well, not always. In my little city of Norfolk, there’s an example of a company in an industry that’s suffering the most, that’s actually doing quite well.

    Relative Theory Records, really deserves any Google Juice I can throw their way.  They’re such a great example of something done right. Great web site. Great place to go. Great community. A model for how business, especially those being threatened by the big bad Internet, can thrive.  It’s all about the community, and they’ve seemed to tap into it.

    Someday, the brick and mortar Barnes & Nobles, Blockbusters and Tower Records of the world will die or at least change, giving way to online commerce. In fact, Blockbuster seems to me to be throwing hail mary’s these days, in an effort to squeeze every dollar out of their dying brick and mortar business model, with their no-late fee policy. They see the writing on the wall.  Now, of course these big business will find new ways to get us into their stores, and everyone’s going to work harder, making the real-world experience better, otherwise, we’ll just do it from our living rooms.  Sounds good to me. Everyone wins!

    -Brendan

  • A Better ASP.NET State Pattern

    Creating a better way to manage ASP.NET state has been talked about quite a bit.  I’ve posted about it a few times, as have others.  A couple of weeks ago Raymond brought the topic up again, and it got me thinking that the way I've been doing it could probably be improved upon.  Today I needed to look at it again for our public web site, so I thought that it was a good time for a rewrite. 

    If you have a look at my StateClassBase Redux  there’s a number of problems with the implementation. For one, it’s a poor use of OO.  Yes, there is a base class, but it just contains a bunch of overloaded methods.  In fact, having a bunch of overloaded methods is usually a good indication that your design isn’t all that great.  For another, it was cumbersome to use, and required that it be initialized in your code before you use it.  Initializing the class in your OnInit worked okay sometimes, but could also be buggy in other situations, like when your control was dynamically loaded.  The new version lazy loads itself, via a singleton-ish Instance property, which helps sort out these issues.

    It also wasn’t easy to re-use. If I wanted to add another back-end session storage mechanism, it involved modifying the base class itself.  What was I thinking?

    Recent Updates (2/24/05):

    • Added  [Serializable] to the class and [XmlIgnore] to the Instance
    • Made the SessionStateObject class Abstract

    So, here’s my new and improved StateBase class:

      [Serializable]public abstract class StateBase

      {

        protected string stateKey;

        private object instance;

     

        /// <summary>

        /// Gets the instance.

        /// </summary>

        /// <value></value>

        [XmlIgnore]public virtual Object Instance

        {

          get

          {

            // Lazy Load

            if(instance == null)

            {

              // Try to restore

              Object o = Restore();

              if(o != null)
              {

                 instance = o;
                 return o;

              }

              // Create a new instance of the derived type

              Type type = this.GetType();

              instance = Activator.CreateInstance(type);

            }

     

            return instance;

          }

        }

     

        /// <summary>

        /// Gets or sets the state key.

        /// </summary>

        /// <value></value>

        public string StateKey

        {

          get { return stateKey; }

          set { stateKey = value; }

        }

     

        /// <summary>

        /// Creates a new <see cref="StateBase"/> instance.

        /// </summary>

        /// <param name="stateKey">State key.</param>

        public StateBase(string stateKey)

        {

          this.stateKey = stateKey;

        }

     

        /// <summary>

        /// Stores this instance.

        /// </summary>

        /// <returns></returns>

        public abstract void Store();

     

        /// <summary>

        /// Removes this instance.

        /// </summary>

        /// <returns></returns>

        public abstract void Remove();

     

        /// <summary>

        /// Restores this instance.

        /// </summary>

        /// <returns></returns>

        public abstract Object Restore();

     

      }

    And here’s a derived class that sores the state in Session. Note that you can create one that stores state in ViewState, or Application or Cache or in the Database, or on your cell phone. The point is, you just derive from StateBase, and implement the abstract methods.

    public abstract class SessionStateObject : StateBase

      {

        /// <summary>

        /// Creates a new <see cref="SessionStateObject"/> instance.

        /// </summary>

        /// <param name="stateKey">State key.</param>

        public SessionStateObject(string stateKey) : base(stateKey)

        {}

     

        /// <summary>

        /// Stores this instance.

        /// </summary>

        /// <returns></returns>

        public override void Store()

        {

          System.Web.HttpContext.Current.Session[stateKey] = this;

        }

     

        /// <summary>

        /// Removes this instance.

        /// </summary>

        /// <returns></returns>

        public override void Remove()

        {

          System.Web.HttpContext.Current.Session.Remove(stateKey);

        }

     

        /// <summary>

        /// Restores this instance.

        /// </summary>

        /// <returns></returns>

        public override Object Restore()

        {

            return System.Web.HttpContext.Current.Session[stateKey];

        }

      }

    And here’s how to use it in your code, simply derive from the SessionStateObject, adding any members you want to keep track of your state.

        /// <summary>

        /// Object for maintaining state

        /// </summary>

        public class SomeControlsState : SessionStateObject

        {

          public SomeControlsState() : base("SOMECONTROL_STATE")

          {}

     

          public new SomeControlsState Instance

          {

            get

            {

              return (SomeControlsState)  base.Instance;

            } 

          }

     

          private ShippingContainerCollection containers;

     

          public ShippingContainerCollection Containers

          {

            get { return containers; }

            set { containers = value; }

          }

        }

    Now, assuming that you’ve created an instance of state (you can now do this in-line in your class) to save your state, just call Store();

    state.Instance.Containers = someService.Instance.GetShippingContainerCollection();

    state.Instance.Store();

    Using in on subsequent postbacks is even easier:

    ShippingContainer sc = state.Instance.Containers.Find(Convert.ToInt32(e.CommandArgument));

    No more worrying about calling Restore() unless you specifically need to.  Hope you find this useful.  I really would like some feedback to this.  If this can be done better, I want make this thing sing!

    -Brendan

  • Welcome Ranjan

    Ranjan Sakalley is another DNJ refugee, and the most recent addition to CodeBetter.Com.  His _ideas are a welcome addition to our mix!

    -Brendan

  • Welcome David Hayden

    I’ve been following David’s old blog for a good while, and am happy to announce that he’s decided to join us here at CodeBetter.Com.  He’s a very prolific poster, .NET expert, and an all-around nice guy.  We’re all very happy he’s blogging with us. 

    Speaking of new bloggers, we’ve got one or two more bloggers coming in the near future, but don’t worry, we’re still committed to having a focused main feed. We think we’ve got a good system going, and we don’t want to ruin it with 100 posts/day.  The system is self-managing too… For example, if anyone here posts off-topic on the main feed, Geoff will personally fly to their house from Canberra, and proceed to flog them with a VB.NET mouse pad, and Sahil will check their last 100 posts for technical accuracy.  Needless to say, everyone’s pretty much stayed on topic so far.

    – Brendan

  • BlogJet

    A few weeks ago,  Ben asked What do you use to write blog entries?  This post, along with a need to rapidly publish to our LinkBlog, got me looking into blogging tools.  I’ve settled on using BlogJet.  In fact, I like it so much, that I’ve managed get copies for all of the bloggers here at CodeBetter.Com.. Not sure how many of us are using it yet, but I have a feeling that it’ll catch on..

    What’s so cool about it?  For one thing, it works with a bunch of weblog services (Blogger, DasBlog, MovableType, .Text, Blogger API, MetaWeblog API)For another, you can setup multiple blogs to publish to, so that you can easily switch back and forth if you publish to multiple blogs.  But, the coolest thing (IMO) is that it adds a “BlogJetThis” extension to FireFox, and IE, so that you can select content, right-click the selection and choose “BlogJetThis” from the context menu.

    Blogjet1

    This will launch BlogJet, with the text that you’ve highlighted, and also title your post and create a hyperlink (think Scoble’s link blog).

    Blogjet2

    One click and your post is published!  I don’t really know if it can get any easier.  In the interest of fairness, I should mention that we’re getting our copies license free (licenses normally cost $39.95), but I think I’d be using it and blogging about it anyway.  It really is that good.

    -Brendan

  • OT: The Next Star Wars Kid

    As featured on the Today Show. This is the hilarious Romanian (or is he Dutch) kid lip syncing!

    http://www3.ns.sympatico.ca/lyle_24/myhero.html

  • When You Work From Home, Do You Live At Work?

    There’s a comment in Ben’s post How does consulting work? from  Avonelle Lovhaug where he says 

    I love working from home, so I have resisted planting myself at a large organization for 40 hours/week.

    I worked from home for two years, and while I was doing it, I would have told you that I loved it.  Got up whenever I wanted. Wrote code in the wee hours.  Walked the dog. I thought it was great.  I didn’t have too much of a problem keeping diciplined, or at least no more than I do here at work.

    Then, I lost my overpaid, spoiled contract when the bubble burst. I had to schlep myself to a building everyday with other people, and those god awful overhead fluorescent lights. Yuck, I thought.

    Then something unexpected happened.  On my first job.  I met some cool people. Through these guys, I met more cool people. Our hatred of those god awful lights bonded us together.  They introduced me to blogging, and taught me a bunch of cool stuff, I’d have never learned at home by myself. I found that I liked going into a that god awful building every day.  I found that, even better, I liked being at home more too.  I would have never know this about myself, had I not been forced into it.  I’m wondering if anyone else has had a similar experience?

    Maybe some day, I’ll work from home again, but I don’t see that day coming in the near future.

    Brendan

  • System.DateTime in Entities - Dammed if you're nullable, Dammed if you're not

    Often when designing my entity objects, I've used System.Object instead of System.DateTime for dates that can be nullable.  (Sidebar: System.DateTime is a value type, so it can't be null) 

    In Whidbey, this is cake using Nullable types:
       public Nullable<DateTime> ShippedDate;
    But for now, I've decided to use Object.  Okay choice, I've always thought.  I could use the SqlDateTime which is a refrence type implements INullable but that seems just plain wrong.  I could roll my own reference type, but that wouldn't be good then if I exposed it at the end of a web service.    There's also projects like http://nullabletypes.sourceforge.net/ that I probably should be looking into. But, object was working for me, so I didn't look into it too much. DataGrids and other data bound objects nicely handle the null values, and can also nicely format the dates, if they're not null. 

    But, this bit me the other day, when I tried to sort a collection, using the code that I posted in my Sort and Filter Strongly-Typed Collection Classes post.  What happens is that when there's a null value ArrayList.Sort() will throw an exception.

    The solution for me turned out to be adding a null equivalent for the actual type that I was trying to sort on. 

        /// <summary>

        /// Gets the null equivalent.

        /// </summary>

        /// <param name="type">Type.</param>

        /// <returns></returns>

        private object GetNullEquivalent(Type type)

        {

          if(type == typeof(System.DateTime)) return DateTime.MinValue;

          if(type == typeof(System.String)) return String.Empty;

          return null;

        }


    But, this gets even more complicated, because you don't know the type before hand, so you have to do some looping to find out.   Perhaps there's an attribute that I could use to make this easier, and specify the actual intended type, for stuff like this. Anyhow, because of this, I've had to change the code that does the sorting from this:

        /// <summary>

        /// Does the sort.

        /// </summary>

        private void DoSort()

        {

          sortedList.Clear();

          if (sortBy == null)

          {

            foreach (object obj in BaseList)

            {

              sortedList.Add(new ListItem(obj, obj));

            }

          }

          else

          {

            foreach (object obj in BaseList)

            {

              sortedList.Add(new ListItem(sortBy.GetValue(obj), obj));

            }

          }

          sortedList.Sort();

          isSorted = true;

          if (ListChanged != null)

          {

            ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0));

          }

        }


    To this:

        /// <summary>

        /// Does the sort.

        /// </summary>

        private void DoSort()

        {

          sortedList.Clear();

          if (sortBy == null)

          {

            foreach (object obj in BaseList)

            {

              sortedList.Add(new ListItem(obj, obj));

            }

          }

          else

          {

     

            System.Type objectType = null;

     

            // Get the type

            foreach (object obj in BaseList)

            {

              object sorter = sortBy.GetValue(obj);

     

              if(sorter != null && objectType == null)

              {

                objectType = sorter.GetType();

              }

              else if(sorter == null && objectType != null)

              {

                sorter = GetNullEquivalent(objectType);

              }

              else if(sorter == null && objectType == null)

              {

                // Loop through, and find the object's type

                foreach(object obj2 in BaseList)

                {

                  object sorter2 = sortBy.GetValue(obj2);

     

                  if(sorter2 != null)

                  {

                    objectType = sorter2.GetType();

                    break;

                  }

                }

     

                // We didn't find the object's type, set it to a string.

                if(objectType == null) objectType = typeof(String);

     

                sorter = GetNullEquivalent(objectType);

              }

     

              sortedList.Add(new ListItem(sorter, obj));

            }

          }

     

          sortedList.Sort();

          isSorted = true;

          if (ListChanged != null)

          {

            ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0));

          }

        }


    -Brendan
  • Fix for System.DirectoryServices error "Operation is not valid due to the current state of the object."

    If you use the System.DirectoryServices namespace to do Active Directory stuff, you may have run into this error:

    Operation is not valid due to the current state of the object.at System.DirectoryServices.PropertyValueCollection.OnInsertComplete(Int32 index, Object value) at System.Collections.CollectionBase.System.Collections.IList.Add(Object value) at System.DirectoryServices.PropertyValueCollection.Add(Object value)
    This problem is mentioned in KB886541, which refers the hotfix in KB35763.  This is one of those hotfixes that you have to call in for, but it does in fact fix this error. 
  • Just when I thought I was out, IE pulls me back in

    I've been doing an experiment to see if I can use Firefox as my browser, instead of IE.  Seems like it should be a pretty simple thing to do.  A couple of global settings here and there, and every time I encounter an internet resource of some type,  Firefox should pop up, right?  Isn't that how it should work?  Well, it doesn't work. It's turned out to be nearly impossible for me keep IE from popping up, or to keep from having to launch IE for one thing or another.

    Has anyone out there managed to become IE Free?

  • FTB 3.0 .TEXT Integration (or, now we can blog with Firefox)

    After an unsuccessful attempt at integrating the new FreeTextBox 3.0 release into our .TEXT engine at CodeBetter.Com, last night I finally got it working.  I started with a post from Paul (see Adding FreeTextBox 3.0 to .Text Version 0.95), but wasn't fully successful, and I found that the process involved a couple of extra steps.  Here's how to update a production .TEXT deployment with the new FreeTextBox, should you need to do the same thing:

    Step 1: Add FTB 3.0 dll to your local .TEXT project
    Download and drop the new freetextbox.dll into the "OtherStuff\ThirdParty" directory.   This is where the Admin and Dottext.Web projects reference the freetextbox.dll.

    Step 2: Modify EntryEditor.ascx.cs Source
    The EntryEditor page does some browser checking to only update the FTB content for IE.  You'll need to modify the following lines of code.

      351 entry.Body = Globals.StripRTB(Utilities.CheckIsIE55() ? ftbBody.Text : txbBody.Text,Request.Url.Host);

    to

      351 entry.Body = Globals.StripRTB(ftbBody.Text,Request.Url.Host);


      421 valftbBodyRequired.Visible = ftbBody.Visible = Utilities.CheckIsIE55();

    to

      421 valftbBodyRequired.Visible = ftbBody.Visible = true;


      434 private void SetEditorText(string bodyValue)

      435     {

      436       if (Utilities.CheckIsIE55())

      437         ftbBody.Text = bodyValue;

      438       else

      439         txbBody.Text = bodyValue;

      440     }

    to

      434 private void SetEditorText(string bodyValue)

      435     {

      436       ftbBody.Text = bodyValue;

      437     }


    Step 3: Modify EntryEditor.ascx

    Update your FTB control tag, since the new version breaks the old  version's type..

       95       <FTB:FreeTextBox id="ftbBody" runat="server" width="98%" visible="False"

       96         ToolbarImagesLocation="ExternalFile"

       97         ButtonImagesLocation="ExternalFile"

       98         JavaScriptLocation="ExternalFile"

       99         SupportFolder="~/aspnet_client/FreeTextBox/" 

      100         toolbarlayout="Bold,Italic,Underline,Strikethrough;

                   Superscript,Subscript,RemoveFormat|FontFacesMenu,

                   FontSizesMenu,FontForeColorsMenu|JustifyLeft,

                   JustifyRight,JustifyCenter,JustifyFull;BulletedList,

                   NumberedList,Indent,Outdent;CreateLink,Unlink,Insert,

                   InsertRule|Cut,Copy,Paste;Undo,Redo|ieSpellCheck,

                   WordClean,InsertDate,InsertTime,InsertImage"

      101         toolbarbackcolor="Transparent" backcolor="Transparent" height="300px"

      102         gutterbackcolor="Transparent" GutterBorderColorDark="Transparent"

      103         EditorBorderColorDark="Transparent" EditorBorderColorLight="Transparent" />


    Step 4: Rebulid
    You'll need to build your .TEXT Admin and Dottext Web Projects, not rebuilding the DLLs will give you some nasty runtime errors.

    Step 5: Deploy
    Copy the aspnet_client directory included with FTB to the root of your .TEXT installation.
    Copy your new EntryEditor.ascx page into your Admin/UserControls directory
    Re-Deploy the Dottext.* dlls and the freetextbox.dll to your production environment.

    That should be it!  Good luck!

    -Brendan (posting entirely from Firefox)
  • Indigo Out in the Open

    Should start seeing lots of Indigo-related stuff soon (see Indigo - now we can talk...  and Today and tomorrow: Will Indigo heal... ?)  as an example, Rockford's blogging about Indigo: the future of asmx/wse/es/msmq/remoting.   I'm particularly interested in the Reliable Messaging pieces, since it relates to WSMQ.  So far, it looks exciting, Rocky alludes to the fact that with a few attributes, you'll be able to get rid of all that System.Messaging code.  Great!

More Posts Next page »