Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

April 2010 - Posts

Why Software Sucks...and What You Can Do About It – book review

Why Software Sucks...and What You Can Do About It   
Why Software Sucks...and What You Can Do About It
How do our users see the products we are writing for them and how happy they are with our work? Are they able to get their work done without fighting with cool features and crashes or are they just switching off resistance part of their brain to survive our software? Yeah, the overall picture of software usability landscape is not very nice. Okay, it is not even nice. But, fortunately, Why Software Sucks...and What You Can Do About It by David S. Platt explains everything.

Why Software Sucks… is book for software users but I consider it as a-must reading also for developers and specially for their managers whose politics often kills all usability topics as soon as they may appear. For managers usability is soft topic that can be manipulated the way it is best in current state of project. Although developers are not UI designers and usability experts they are still very often forced to deal with these topics and this is how usability problems start (of course, also designers are able to produce designs that are stupid and too hard to use for users, but this blog here is about development).

I found this book to be very interesting and funny reading. It is not humor book but it explains you all so you remember later very well what you just read. It took me about three evenings to go through this book and I am still enjoying what I found and how author explains our weird young working field to end users. I suggest this book to all developers – while you are demanding your management to hire or outsource usability expert you are at least causing less pain to end users. So, go and buy this book, just like I did. And… they thanks to mr. Platt :)

There is one book more I suggest you to read if you are interested in usability - Don't Make Me Think: A Common Sense Approach to Web Usability, 2nd Edition by Steve Krug.

Editorial review from Amazon

Today’s software sucks. There’s no other good way to say it. It’s unsafe, allowing criminal programs to creep through the Internet wires into our very bedrooms. It’s unreliable, crashing when we need it most, wiping out hours or days of work with no way to get it back. And it’s hard to use, requiring large amounts of head-banging to figure out the simplest operations.

It’s no secret that software sucks. You know that from personal experience, whether you use computers for work or personal tasks. In this book, programming insider David Platt explains why that’s the case and, more importantly, why it doesn’t have to be that way. And he explains it in plain, jargon-free English that’s a joy to read, using real-world examples with which you’re already familiar. In the end, he suggests what you, as a typical user, without a technical background, can do about this sad state of our software—how you, as an informed consumer, don’t have to take the abuse that bad software dishes out.

As you might expect from the book’s title, Dave’s expose is laced with humor—sometimes outrageous, but always dead on. You’ll laugh out loud as you recall incidents with your own software that made you cry. You’ll slap your thigh with the same hand that so often pounded your computer desk and wished it was a bad programmer’s face. But Dave hasn’t written this book just for laughs. He’s written it to give long-overdue voice to your own discovery—that software does, indeed, suck, but it shouldn’t.

Table of contents

Acknowledgments xiii
Introduction

Chapter 1: Who’re You Calling a Dummy?
Where We Came From
Why It Still Sucks Today
Control versus Ease of Use
I Don’t Care How Your Program Works
A Bad Feature and a Good One
Stopping the Proceedings with Idiocy
Testing on Live Animals
Where We Are and What You Can Do

Chapter 2: Tangled in the Web
Where We Came From
How It Works
Why It Still Sucks Today
Client-Centered Design versus Server-Centered Design
Where’s My Eye Opener?
It’s Obvious—Not!
Splash, Flash, and Animation
Testing on Live Animals
What You Can Do about It

Chapter 3: Keep Me Safe
The Way It Was
Why It Sucks Today
What Programmers Need to Know, but Don’t
A Human Operation
Budgeting for Hassles
Users Are Lazy
Social Engineering
Last Word on Security
What You Can Do

Chapter 4: Who the Heck Are You?
Where We Came From
Why It Still Sucks Today
Incompatible Requirements
OK, So Now What?

Chapter 5: Who’re You Looking At?
Yes, They Know You
Why It Sucks More Than Ever Today
Users Don’t Know Where the Risks Are
What They Know First
Milk You with Cookies?
Privacy Policy Nonsense
Covering Your Tracks
The Google Conundrum
Solution

Chapter 6: Ten Thousand Geeks, Crazed on Jolt Cola
See Them in Their Native Habitat
All These Geeks
Who Speaks, and When, and about What
Selling It
The Next Generation of Geeks—Passing It On

Chapter 7: Who Are These Crazy Bastards Anyway?
Homo Logicus
Testosterone Poisoning
Control and Contentment
Making Models
Geeks and Jocks
Jargon
Brains and Constraints
Seven Habits of Geeks

Chapter 8: Microsoft: Can’t Live With ’Em and Can’t Live Without ’Em
They Run the World
Me and Them
Where We Came From
Why It Sucks Today
Damned if You Do, Damned if You Don’t
We Love to Hate Them
Plus ça Change
Growing-Up Pains
What You Can Do about It
The Last Word

Chapter 9: Doing Something About It
1. Buy
2. Tell
3. Ridicule
4. Trust
5. Organize

Epilogue
About the Author

Agile Database Techniques: Effective Strategies for the Agile Software Developer – book review

agile-database-techniques  
Agile Principles, Patterns, and Practices in C# (Robert C. Martin Series)
Agile development expects mind shift and developers are not the only ones who must be agile. Every chain is as strong as it’s weakest link and same goes also for development teams. Agile Database Techniques: Effective Strategies for the Agile Software Developer by Scott W. Ambler is book that calls also data professionals to be part of agile development.

Often are DBA-s in situation where they are not part of application development and later they have to survive large set of applications that all use databases different way. Of course, only some of these applications are not problematic when looking what database server has to do to serve them. I have seen many applications that rape database servers because developers have no clue what is going on in database (~3K queries to database per web application request – have you seen something like this? I have…)

Agile Database Techniques covers some object and database design technologies and gives suggestions to development teams about topics they need help or assistance by DBA-s. The book is also good reading for DBA-s who usually are not very strong in object technologies. You can take this book as bridge between these two worlds.

I think teams that build object applications that use databases should buy this book and try at least one or two projects out with Ambler’s suggestions.

Table of contents

Foreword by Jon Kern.
Foreword by Douglas K. Barry.

Acknowledgments.
Introduction.
About the Author.

Part One: Setting the Foundation.

Chapter 1: The Agile Data Method.
Chapter 2: From Use Cases to Databases — Real-World UML.
Chapter 3: Data Modeling 101.
Chapter 4: Data Normalization.
Chapter 5: Class Normalization.
Chapter 6: Relational Database Technology, Like It or Not.
Chapter 7: The Object-Relational Impedance Mismatch.
Chapter 8: Legacy Databases — Everything You Need to Know But Are Afraid to Deal With.

Part Two: Evolutionary Database Development.

Chapter 9: Vive L’ Évolution.
Chapter 10: Agile Model-Driven Development (AMDD).
Chapter 11: Test-Driven Development (TDD).
Chapter 12: Database Refactoring.
Chapter 13: Database Encapsulation Strategies.
Chapter 14: Mapping Objects to Relational Databases.
Chapter 15: Performance Tuning.
Chapter 16: Tools for Evolutionary Database Development.

Part Three: Practical Data-Oriented Development Techniques.

Chapter 17: Implementing Concurrency Control.
Chapter 18: Finding Objects in Relational Databases.
Chapter 19: Implementing Referential Integrity and Shared Business Logic.
Chapter 20: Implementing Security Access Control.
Chapter 21: Implementing Reports.
Chapter 22: Realistic XML.

Part Four: Adopting Agile Database Techniques.

Chapter 23: How You Can Become Agile.
Chapter 24: Bringing Agility into Your Organization.
Appendix: Database Refactoring Catalog.

References and Suggested Reading.
Index.

ASP.NET: Using conditionals in data binding expressions

ASP.NET 2.0 has no support for using conditionals in data binding expressions but it will change in ASP.NET 4.0. In this posting I will show you how to implement Iif() function for ASP.NET 2.0 and how ASP.NET 4.0 solves this problem smoothly without any code.

Problem

Let’s say we have simple repeater.


<asp:Repeater runat="server" ID="itemsList">

    <HeaderTemplate>

        <table border="1" cellspacing="0" cellpadding="5">

    </HeaderTemplate>

    <ItemTemplate>

        <tr>

        <td align="right"><%# Container.ItemIndex + 1 %>.</td>

        <td><%# Eval("Title") %></td>

        </tr>

    </ItemTemplate>

    <FooterTemplate>

        </table>

    </FooterTemplate>

</asp:Repeater>


Repeater is bound to data when form loads.


protected void Page_Load(object sender, EventArgs e)

{

    var items = new[] {

                    new { Id = 1, Title = "Headline 1" },

                    new { Id = 2, Title = "Headline 2" },

                    new { Id = 2, Title = "Headline 3" },

                    new { Id = 2, Title = "Headline 4" },

                    new { Id = 2, Title = "Headline 5" }

                };

    itemsList.DataSource = items;

    itemsList.DataBind();

}


aspnet-data-binding-expression-conditional We need to format even and odd rows differently. Let’s say we want even rows to be with whitesmoke background and odd rows with white background. Just like shown on screenshot on right.

Our first thought is to use some simple expression to avoid writing custom methods. We cannot use construct like this


<%# Container.ItemIndex % 2==0 ? "white" : "whitesmoke"  %>


because all we get are template compilation errors.

ASP.NET 2.0: Iif() method

For ASP.NET 2.0 pages and controls we can create Iif() method and call it from our templates. This is out Iif() method.


protected object Iif(bool condition, object trueResult, object falseResult)

{

    return condition ? trueResult : falseResult;

}


And here you can see how to use it.


<asp:Repeater runat="server" ID="itemsList">

  <HeaderTemplate>

    <table border="1" cellspacing="0" cellpadding="5">

    </HeaderTemplate>

  <ItemTemplate>

    <tr style='background-color:'

      <%# Iif(Container.ItemIndex % 2==0, "white", "whitesmoke") %>'>

      <td align="right">

        <%# Container.ItemIndex + 1 %>.</td>

      <td>

        <%# Eval("Title") %></td>

    </tr>

  </ItemTemplate>

  <FooterTemplate>

    </table>

  </FooterTemplate>

</asp:Repeater>


This method does not care about types because it works with all objects (and value-types). I had to define this method in code-behind file of my user control because using this method as extension method made it undetectable for ASP.NET template engine.

ASP.NET 4.0: Conditionals are supported

In ASP.NET 4.0 we will write … hmm … we will write nothing special. Here is solution.


<asp:Repeater runat="server" ID="itemsList">

  <HeaderTemplate>

    <table border="1" cellspacing="0" cellpadding="5">

    </HeaderTemplate>

  <ItemTemplate>

    <tr style='background-color:'

      <%# Container.ItemIndex % 2==0 ? "white" : "whitesmoke" %>'>

      <td align="right">

        <%# Container.ItemIndex + 1 %>.</td>

      <td>

        <%# Eval("Title") %></td>

    </tr>

  </ItemTemplate>

  <FooterTemplate>

    </table>

  </FooterTemplate>

</asp:Repeater>


Yes, it works well. :)

Measuring ASP.NET and SharePoint output cache

During ASP.NET output caching week in my local blog I wrote about how to measure ASP.NET output cache. As my posting was based on real work and real-life results then I thought that this posting is maybe interesting to you too. So here you can read what I did, how I did and what was the result.

Introduction

Caching is not effective without measuring it. As MVP Henn Sarv said in one of his sessions then you will get what you measure. And right he is. Lately I measured caching on local Microsoft community portal to make sure that our caching strategy is good enough in environment where this system lives. In this posting I will show you how to start measuring the cache of your web applications.

Although the application measured is built on SharePoint Server publishing infrastructure, all those counters have same meaning as similar counters under pure ASP.NET applications.

Measured counters

I used Performance Monitor and the following performance counters (their names are similar on ASP.NET and SharePoint WCMS):

  • Total number of objects added – how much objects were added to output cache.
  • Total object discards – how much objects were deleted from output cache.
  • Cache hit count – how many times requests were served by cache.
  • Cache hit ratio – percent of requests served from cache.

The first three counters are cumulative while last one is coefficient. You can use also other counters to measure the full effect of caching (memory, processor, disk I/O, network load etc before and after caching).

Measuring process

The measuring I describe here started from freshly restarted web server. I measured application during 12 hours that covered also time ranges when users are most active. The time range does not include late evening hours and night because there is nothing to measure during these hours.

During measuring we performed no maintenance or administrative tasks on server. All tasks performed were related to usual daily content management and content monitoring. Also we had no advertisement campaigns or other promotions running at same time.

The results

You can see the results on following graphic.

The result of cache performance monitoring

Output cache: Total number of objects added   Total number of objects added
Output cache: Total object discards   Total object discards
Output cache: Cache hit count   Cache hit count
Output cache: Cache hit ratio   Cache hit ratio

You can see that adds and discards are growing in same tempo. It is good because cache expires and not so popular items are not kept in memory. If there are more popular content then the these lines may have bigger distance between them.

Cache hit count grows faster and this shows that more and more content is served from cache. In current case it shows that cache is filled optimally and we can do even better if we tune caches more. The site contains also pages that are discarded when some subsite changes (page was added/modified/deleted) and one modification may affect about four or five pages. This may also decrease cache hit count because during day the site gets about 5-10 new pages.

Cache hit ratio is currently extremely good. The suggested minimum is about 85% but after some tuning and measuring I achieved 98.7% as a result. This is due to the fact that new pages are most often requested and after new pages are added the older ones are requested only sometimes. So they get discarded from cache and only some of these will return sometimes back to cache. Although this may also indicate the need for additional SEO work the result is very well in technical means.

Conclusion

Measuring ASP.NET output cache is not complex thing to do and you can start by measuring performance of cache as a start. Later you can move on and measure caching effect to other counters such as disk I/O, network, processors etc. What you have to achieve is optimal cache that is not full of items asked only couple of times per day (you can avoid this by not using too long cache durations). After some tuning you should be able to boost cache hit ratio up to at least 85%.

How to avoid the exception “Substitution controls cannot be used in cached User Controls or cached Master Pages.”

Recently I wrote example about using user controls with donut caching. Because cache substitutions are not allowed inside partially cached controls you may get the error Substitution controls cannot be used in cached User Controls or cached Master Pages when breaking this rule. In this posting I will introduce some strategies that help to avoid this error.

How Substitution control checks its location?

Substitution control uses the following check in its OnPreRender method.


protected internal override void OnPreRender(EventArgs e)

{

    base.OnPreRender(e);

    for (Control control = this.Parent; control != null;
         control = control.Parent)

    {

        if (control is BasePartialCachingControl)

        {

            throw new HttpException(SR.GetString("Substitution_CannotBeInCachedControl"));

        }

    }

}


It traverses all the control tree up to top from its parent to find at least one control that is partially cached. If such control is found then exception is thrown.

Reusing the functionality

If you want to do something by yourself if your control may cause exception mentioned before you can use the same code. I modified the previously shown code to be method that can be easily moved to user controls base class if you have some. If you don’t you can use it in controls where you need this check.


protected bool IsInsidePartialCachingControl()

{

    for (Control control = Parent; control != null;
        control = control.Parent)

        if (control is BasePartialCachingControl)

            return true;

 

    return false;

}


Now it is up to you how to handle the situation where your control with substitutions is child of some partially cache control. You can add here also some debug level output so you can see exactly what controls in control hierarchy are cached and cause problems.

More Posts