Archive

Archive for the ‘ASP.NET’ Category

How To Display Your Amazon Reviews and Wish List (on your site) Using Amazon’s Web Services

October 6th, 2008

If you’ve ever landed on Amazon then you’re probably familiar with their reviews and wish lists. Amazon provides access to these items (and many-many more) through their extensive web services – the Amazon web services can be complex and overwhelming when all you want is a review list and a single user specific wish list. For this site I wanted to pull in my reviews and wish list – displaying them alongside my blog. It’s fair to note, that user reviews are available via an RSS feed (but this feed doesn’t include all the details I wanted) and the wish list page still doesn’t provide an RSS feed. So a custom Amazon web service request was in order.

Let me try to make this story short.

If you want to request your reviews and your wish list you need the following:

Once you have a wish list or review, you then need to:

Once you’ve collected all those bits, you need to:

  • Checkout and download the source code for the project and build the assembly or download the pre-compiled assembly.
  • Add the assembly reference to your project (remember, I’m assuming you’re using .NET).
  • Make a call to the application which will generate XML files containing your respective reviews and wish list.

Setting up the call would look something like this:

IAmazonRequest amazonRequest = new AmazonRequest() {
 AssociateTag = "adamkahtavaap-20",
  AWSAccessKeyId = "1MRF________MR2",
  CustomerId = "A2JM0EQJELFL69",
  ListId = "3JU6ASKNUS7B8"
};

IFileParameters fileParameters = new FileParameters() {
  ProductFileNameAndPath = @"Products.xml",
  ReviewFileNameAndPath = @"Reviews.xml",
  ErrorFileNameAndPath = @"Errors.xml"
 };

IAmazonApplication amazonApplication = new AmazonApplication(amazonRequest, fileParameters);

amazonApplication.Save();

And Viola!

If you’d like to provide some design guidance, fix a bug, or request a feature, then visit (or join) the project on Google Code.

Alternatively, you might also be interested in the LINQ To Amazon source featured in the book LINQ in Action.

Author: Adam Kahtava Categories: .NET, ASP.NET, Amazon, Open Source, Software, XML Tags:

Cross Language Naming Conventions: Avoiding Verbosity In The Presentation Layer

August 29th, 2008

Most languages and technologies used in web applications come with their own unique naming conventions – which is unfortunate, but necessary, because diversity is important. Languages like JavaScript and PHP use camelCase, CSS uses-hyphenated-delimiters, and ASP.NET / Java / and the like adhere to the conventions used in their respective libraries and frameworks. Managing the different naming conventions in a web application can be difficult, but with discipline, embracing each language’s conventions can provide some great benefits.

A common mistake I’ve made in the past, was trying to make all languages adhere to a single convention. As a budding PHP / ASP developer I took the-single-convention-for-all-languages approach. In retrospect, I used this approach because I didn’t completely understand the language I was using, and in order to compensate for this lack of knowledge, I’d try to meld the languages into the mental model I understood best. This was a mistake.

Today, I find that working with the conventions of the language facilitates re-use (experts in the language understand what I’m doing), promotes portability (modules can be used across projects regardless of server-side technologies), encourages global collaboration (open source modules and plug-ins can be easily consumed and contributed to), and helps to a nurture a more maintainable application (developers from other language domains can easily maintain the application with a relatively small learning curve). Like a carpenter working with fine material, I embrace working with the grain of each language. It’s also fair to mention that breaking free from the monocultured (one-size-fits-all) approach to naming conventions provides a broader perspective, and also makes your development skills more universal – it might even open the door to different development domains in the future.

Then there’s the discussion on name length, verbosity, and using meaningful names. Steve McConnell suggests that the optimum name size for a variable or function is between 8 and 20 characters (Chapter 11, Code Complete), but with tools like ReSharper (for renaming / refactoring etc…) I find myself using names well over 30 characters. So names like GetApproveeTotalFromNamedBasket are a common occurrence in my code. However, like most things, verbosity does need balance (everything in moderation right?). In the business layer, descriptive names are a godsend – they jog my memory as I rediscover what the module I wrote last month was supposed to do. But… in the presentation layer languages (like JavaScript, CSS,  ASP.NET, or XHTML) you may want to reconsider using long descriptive names. Since verbose, long running descriptive names in the presentation layer are passed over the network and can degrade performance. Often times these verbose names are combined together – throw in ASP.NET name mangeling, start hooking in verbose CSS definitions, and then start inserting JavaScript events. All this compounds quickly and result in large page payloads filled with elements like the following:

<div id="ctl00_ContentPlaceHolderForAllTheBestImprotantContent
 _PanelForTheBestReviews"
<a onclick="LinkButtonClick_ThankYouForTakingTheTimeToReadThis();" 
 id="ctl00_ContentPlaceHolderForAllTheBestImprotantContent_
 RepeaterForAllMyFavoriteBookReiews_ctl00_
 LinkButtonMarkReviewAsFavorite"
 class="LinkFormatingCssClass SelectedLinkFormatingCssClass" 
 href="javascript:__doPostBack( 
 ctl00$ContentPlaceHolderForAllTheBestImprotantContent$ 
 RepeaterForAllMyFavoriteBookReiews$ctl00$LinkButtonMarkReviewAsFavorite'
 ,'')">Mark As Favorite </a> 

Note: That mess of code above would fire a JavaScript event then an ASP.NET event. It’s the result of placing an ASP.NET LinkButton, inside a Repeater, inside a Panel, inside a Masterpage, and adding a JavaScript event along with some CSS. We can see that using long names in the presentation layers results in a mess of text. It’s also fair to mention that the ASP.NET MVC Framework lets developers write cleaner presentation code.
Sure, everyone cites premature optimization as the root of all evil, and we do live in a world of gzip file compression and JavaScript minifiers. But… keeping names short in CSS, ASP.NET, and XHTML isn’t hard as long as you’re mindful of the final goal. Smaller names in the presentation layer will reduce the amount of data transferred over the network which increase the performance of the application.

Joseph Smarr of Plaxo.com once said:

Web applications are only slow if you let them get slow – Douglas Crockford, Alex Russell and Joseph Smarr: On the Past, Present and Future of JavaScript [30:00]

My preference (project requirements warranting) is to keep things short and concise in the presentation languages while using longer descriptive names outside the presentation languages. What’s your preference?

Getting a Job at Google: A Web Developer Fizzbuzz

May 24th, 2008

Back when the web turned 2.0, AJAX was all the rage, and gas was cheap, a Google recruiter contacted me. We worked through a couple screening interviews – I explained how I was a .NET / ASP.NET / C# developer with some experience with Java and PHP, I described how C# was somewhat similar to Java. Things went great, I moved on to the next step of the process – writing code (a JavaScript widget for Gmail) with a 2 day (weekend) hard deadline. At the time I was wearing JavaScript diapers, but tried the exercise anyways – I'm still convinced the recruiter confused my Java / C# experience with JavaScript. Anyhow…

The Google Web Developer Exercise:

Web Developer Exercise

Attached are three states of a new contacts widget. This widget will be used across Google and may be anywhere on the page. Designers will also use this in mocks for usability tests. Create the HTML, CSS, and JavaScript for the widget as described in the image. Your solution must work in Firefox v1.5+ and IE v6+. Bonus points for a solution that degrades nicely on older browsers.



After my first attempt, I concluded that:

  1. My JavaScript knowledge was embarrassing
  2. Dynamic programming languages like JavaScript using prototypical inheritance were awesome – as a monocultured .NET developer I had sorely been missing out
  3. Framework Web Developers (ASP.NET, Ruby on Rails, and so on) aren't really Web Developers – we depend on a framework (an API) as a crutch, where the law of Leaky Abstractions is very real, and often when it rears it's head we use our golden hammer (our multipurpose language of choice), but there are better tools at hand
  4. Web Developers claiming n years of experience need to at least know JavaScript, CSS, HTML / XHTML, a server-side language, and some XML / XSL – NOT just a single multipurpose language or framework
  5. Innovation can only happen when you become one with the technologies surrounding your realm – for example: Jesse James Garrett probably would not have publicized AJAX had he been an exclusive ASP.NET developer. Diversity is essential for innovation

In retrospect this exercise is brilliant, it's a more complex derivation of a Fizzbuzz exercise, which effectively weeds out the knowledgeable candidates from the n00bs. JavaScript is notorious for being one of the world's most misunderstood language, many developer (and the ASP.NET Framework) still use JavaScript techniques from the old days of Netscape. For example: <a onclick=”return false;” …, or <a href=”Javascript: do something;” … are common DOM Level 0 inline techniques that should be avoided. These techniques have been replaced, but finding developer that use these JavaScript techniques can be hard.

By having a developer complete this exercise you effectively determine that the they understands these concepts:

  • Cross browser compatibilities and work arounds for both JavaScript and CSS – with a preference given to feature detection (object detection) vs browser detection, an understanding of the different event handling models between browsers
  • An understanding of the separation of concerns – JavaScript, markup, and CSS should be separate files, or at least separated within the document
  • Event registration and listening – DOM events, the different browser event models, no inline level 0 event declarations, no pseudo JavaScript protocol inline declarations within markup
  • An understanding of functional languagesclosures, namespaces, lambdas, recursion where necessary
  • Node manipulation – creating, swapping, removing elements
  • Knowledge of non-obtrusive JavaScript techniques
  • Importance of modular / compartmentalization of CSS and JavaScript – defensive programming techniques that minimize the risk of interfering with other scripts and elements within the page, part of the non-obtrusive techniques, how to avoid global variables
  • An understanding on how to debug JavaScript from both IE (link) and Firefox (link)
  • JavaScript code conventions – naming conventions, statement conventions
  • CSS naming conventions
  • General DHTML / AJAX techniques – showing and hiding elements
  • A gauge on their attention to details and UI design intuition – what their gut tells them to do when things aren't spelled out

My latest crack at the Google Web Developer Exercise:

You'll have to visit my site (view this blog post outside a RSS reader) to view the code in action.

The code: GoogleExercise.js, index.html, GoogleExercise.css

Today I'm wearing JavaScript training wheels – feel free to comment on the code, I'm always looking for improvements and suggestions. I did take a couple shortcuts on the CSS / UI side of things as I was focusing more on the functionality.

Using one of the AJAX Libraries (like jQuery) we could certainly do this exercise in significantly fewer lines of code.

Today I still think about Getting that job at Google, Yahoo!, Amazon, or Microsoft. How well do you know JavaScript?

Update: I redid the Google Exercise using jQuery and more semantics, you can find my latest version here: The Google Exercise Revisited: Semantic Markup with jQuery.

Book Reviewed: ASP.NET AJAX in Action by Alessandro Gallo, David Barkol, Rama Vavilala

April 20th, 2008

The authors of ASP.NET AJAX in Action did an OK (Average) job at presenting the ASP.NET AJAX Framework. However; this book lacked objectivity and suffered from hype. The authors didn't seem to have proficient experience with the JavaScript language, or enough experience with other AJAX Frameworks / Libraries, or sufficient experience using the ASP.NET AJAX Framework in real world projects. This book sadly felt like most technical books – average.

Comments like “we recommend that…”, “because it makes no sense…”, “you must rely on a special method…”, “you must understand X,Y,Z to run complex client-side code without writing a single line of JavaScript” were discouraging. Many of the “whys” were left answered and the technical inner workings of the framework often trivialized. Don't get me wrong, writing a book is incredibly time consuming, but if you're an author, presenter or the like, and you don't fully understand something then admit it. Do some research, provide some links, or move on. Consistently making comments like these bring the integrity of the whole text into question.

The ASP.NET AJAX Framework itself is technically flawed, bloated, and almost entirely impractical. I was disappointed with the server-centric approach that both the book and ASP.NET AJAX Framework takes. I was disappointed that the book continually pushed JavaScript under the carpet as magic and at the end of the book I was pleased to see the promise of making “the JavaScript code disappear” never was  fulfilled. JavaScript is the very most important part of AJAX, without the 'J' in AJAX, we're left with nothing – just 'Asynchronous', 'And', heaps of more ugly 'XML'.

When reading this book, take the contents and the ASP.NET AJAX Framework with a grain of salt, if you're really serious about learning AJAX then read JavaScript: The Definitive Guide by David Flanagan.

I typically only contribute positive reviews, but I don't agree with the majority of reviews found on Amazon and hope this review provides some objectivity. I commend the authors on their hard work, I'm probably being too harsh with this review – I know it's tough to write a book, and imagine they made many sacrifices as they worked towards tight deadlines.

View my review on Amazon.

Author: Adam Kahtava Categories: .NET, AJAX, ASP.NET, ASP.NET AJAX, Book, JavaScript, Review Tags:

A Reflection on Themes, Skins, and Cascading Style Sheets (CSS) in ASP.NET 2.0 (A Final Conclusion)

April 7th, 2008

A couple years ago I was thrown into a web application that made heavy use of ASP.NET Themes and Skins. Prior to this I depended exclusively on Cascading Style Sheet (CSS) for my web development / web design needs. A first glance at ASP.NET Themes and Skins looked promising, but a number of flaws surfaced – see the links and issues listed at the end of this post.

In addition to these issues, here are a couple other considerations when thinking about ASP.NET Themes:

  • Themes do not adequately separate the levels of concerns within your application. When using Themes all design related files are baked into the application. From a maintainability standpoint, this doesn’t bode well in large web applications. Hosting design related files on a single server or an external Content Delivery Network (CDN) is an effective way for managing site wide UI updates and increasing a sites performance, ASP.NET Themes works against this technique.
  • Themes add unneeded complexity by obscuring the real technologies at work (CSS). Everything that ASP.NET Themes offer can be better achieved outside of the ASP.NET Theme Framework. Technologies like Cascading Style Sheets (CSS),  alternate Style Sheets, and JavaScript can achieve more than Themes can provide.
  • Themes are a server-side mechanism. Themes become a nuisance in client-side dependent, heavily dynamic, Web 2.0, DHTML, AJAX type web applications.
  • Themes discourage developers from learning more about web design and the technologies surrounding it. Themes offer a seemingly simple API, which shelters developers from the complexities of CSS and JavaScript, but sooner or later The Law of Leaky Abstractions comes into play and knowing the fundamentals of these technologies is a necessity.
  • Professional web designers don’t use ASP.NET Themes, CSS is the language of web designers.

Default Skins on the other hand can be useful for defining consistent CSS hooks into common ASP.NET controls. It’s unfortunate that we can’t use Skins without Themes.

Related posts:

Author: Adam Kahtava Categories: .NET, ASP.NET, CSS, Themes and Skins Tags:

Free: Win a Copy of Professional ASP.NET 2.0 Design: CSS, Themes, and Master Pages

February 25th, 2008

Professional ASP.NET 2.0 Design: CSS, Themes, and Master Pages by Jacob Sanford is a great book for ASP.NET developers looking to expand their knowledge on the ASP.NET 2.0 Web Design front.

I've read this book, re-read it, edited it, and would like to give it away – I was the Technical Editor. The books is like new and (did I mention) it's free!

Contest Rules:

  • Updated! Just Leave a comment with a valid email address!
  • Post a 500 x 200 pixel image of something you're working on in the comments of this post – this image could be code, web design, or anything work related.
  • Include an optional description of your work
  • The winner will be chosen April 1st May 1st, they'll be drawn at random, and will be notified through email.
  • I pay for shipping.

* I've included a sample entry in the comments. If you're looking for a great free photo editing application then try Paint.net. If you're looking to host your image you might want to consider Flickr or Photobucket.

Good Luck!

The contest has ended, and the winner is….. Andrew Hinde. Nice!

Author: Adam Kahtava Categories: .NET, ASP.NET, Book, CSS, Contest, Themes and Skins Tags:

How Well Do You Know JavaScript?

January 13th, 2008

JavaScript is probably the world’s most popular and misunderstood programming languages and for good reason.
When a developer claims to know JavaScript this generally equates to one or all of the following:

  • “I know what JavaScript is, I can learn JavaScript in 30 minutes
  • “JavaScript is for kids, it’s a toy language, it’s easy”
  • “I just copy and paste my JavaScript snippets / scripts from the internet”
  • “JavaScript is just another programming language like C++, C#, VB.NET, or Java”

If thoughts similar to these have crossed your mind when sizing up your JavaScript knowledge, then you probably don’t know JavaScript.

I would argue that if you’ve never programmed in a functional programming language (like: Lisp, Scheme, F#), never read a GOOD book on JavaScript, or never watched a video on JavaScript, then you probably don’t understand JavaScript at all. JavaScript is starkly different than any other mainstream programming language.

When it comes to JavaScript, if you don’t understand the fundamentals then you’re only punishing yourself.

Here are some things every JavaScript developer should probably understand:

  • JavaScript, Mocha, LiveScript, JScript, and ECMAScript are all essentially the same.
  • JavaScript is a prototypically inherited (prototype-based programming) language which is very different than the classically inherited (class-based programming) languages like C++, Java, and most of the .NET languages – you know the difference between a prototype-based programming and class-based programming language.
  • JavaScript is a loosely typed language – you know the difference between strongly-typed programming languages and weak-typed or loosely typed languages.
  • JavaScript is a functional lambda language – you understand lambdas and that functions in JavaScript can be lambdas.
  • JavaScript functions can be defined inside functions, inside functions, inside functions, and so on – you can demonstrate this.
  • JavaScript uses function scope, has no curly brace ‘{}’ block scope – you understand that this is common attribute of most functional programming languages.
  • JavaScript has no private, public, protected assessors, no classes, no enums, no structs – you understand that all these language features can be achieved through objects and function closures.
  • JavaScript is classless, but instead it uses objects as general containers.
  • JavaScript makes use of garbage collection.
  • JavaScript uses truthy and falsy values – you understand which values are truth and falsy.
  • JavaScript makes use of the ‘nan’ (not a number) and ‘undefined’ values – you understand the difference between these values.
  • JavaScript has pretty good debuggers – you understand how to debug JavaScript from both IE (link) and Firefox (link).
  • You appreciate recursion, and understand that recursion is a useful technique in JavaScript.
  • You understand that JavaScript Namespaces should be used – you understand the importance of namespaces, and know how to create one (Namespacing Your JavaScript).
  • You know how to avoid the JavaScript pseudo-protocol (<a href=”Javascript:alert(‘hello’);”), and appreciate avoiding it.
  • You know how to avoid embedding DOM Level 0 JavaScript events (<a onclick=”alert(‘hello’);”) in your mark-up / document structure, and appreciate this technique.
  • You know that JavaScript can make use of two different event models (event capturing and bubbling), but we should only ever make use of bubbling.
  • You understand what JSON is and how it’s used.
  • You know how to keep you JavaScript, CSS, document structure separate, and appreciate non obtrusive JavaScript.

If any of these points seem foreign, then it may be time to learn JavaScript. With all the hype and buzz around Web 2.0 and AJAX it could be a great way to augment your career while broadening your programming language vocabulary.

Great resources for learning more about JavaScript:

Videos:

Books:

Links:

Author: Adam Kahtava Categories: .NET, AJAX, ASP.NET, CSS, DOM, Firefox, IE, JavaScript, Software, Videos Tags:

A Resolution to The Problems with Themes, Skins, and Cascading Style Sheets (CSS) – Putting the Cascades back into ASP.NET 2.0 Themes (taking control over CSS Cascades / Load Order, Media Types, and Overrides)

April 2nd, 2007

ASP.NET 2.0 Themes have a couple design flaws, all of which center around the way Themes reference Cascading Style Sheets (CSS). I’ve been posting Theme and CSS related issues and work arounds as I encountered them, and in one of my first posts I outlined the possibility of using a VirtualPathProvider to ignore the CSS files within a directory. In this post I share David Marzo’s implemented of this solution. This resolution resolves most of the issues surrounding Themes and CSS, and essentially puts the Cascades back into CSS.

The Problem / Question:
ASP.NET 2.0 Themes automatically includes all the Style Sheets (.css files) found in the active Theme (App_Theme) directory into the Head of the rendered document. This severely limits the robust CSS language, and works against the last decade of Cascading Style Sheet progress. For more specific details on the problems with ASP.NET 2.0 Themes start reading the articles found here.

A Solution / Work Around:
Add a custom VirtualPathProvider to ignore the Style Sheets (CSS files) found in the App_Theme directory. For more background on this solution see my article and David Ebbo’s article titled Overriding ASP.NET combine behavior using a VirtualPathProvider.

An example of the problem:

The directory structure:

Notice all the Style Sheets (.css files), there are more in the Adapters directory too.

Before including the CustomVirtualPathProvider (code provided below) into the project’s build – the XHTML rendered by Themes:

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head><title>The Problems With Themes and Skins in ASP.NET 2.0</title>
    <link href="App_Themes/Default/CSS/Adapters/ChangePassword.css" type="text/css" rel="stylesheet" /> 

    ... The other 17 externally linked Style Sheets go here, they were removed to improve readability ...

     <link href="App_Themes/Default/CSS/PrinterFriendly.css" type="text/css" rel="stylesheet" />
  </head>
<body>

The Style Sheets are automagically inserted into the Head tag from the active Theme directory. Keep in mind that Internet Explorer has a 30 Style Sheet limitation (see article Q262161).

After including the CustomVirtualPathProvider (code provided below) into the project’s build – the XHTML rendered by Themes:

<html xmlns="http://www.w3.org/1999/xhtml" > 
  <head><title>The Problems With Themes and Skins in ASP.NET 2.0</title>
  </head>
<body>

Notice the complete lack of Style Sheets – ahhh simplicity is bliss, the very foundations of CSS Zen Enlightenment… :) Now we can manually include our Style Sheets, use Conditional Comments, and so on.

The source code for the CustomVirtualPathProvider provided by David Marzo in C#:

namespace Arfila.Web.Logic {
 
 [AspNetHostingPermission(SecurityAction.Demand,
   Level = AspNetHostingPermissionLevel.Medium)]
 [AspNetHostingPermission(SecurityAction.InheritanceDemand,
   Level = AspNetHostingPermissionLevel.High)]
 public class CustomVirtualPathProvider : VirtualPathProvider {
 
   public static void AppInitialize() {
     HostingEnvironment.RegisterVirtualPathProvider(new CustomVirtualPathProvider());
   }
 
   public CustomVirtualPathProvider() : base() { }
 
   private bool IsThemeDirectory(string virtualPath) {
     String checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
     return checkPath.StartsWith("~/App_Themes/", 
       StringComparison.InvariantCultureIgnoreCase);
   }
 
   public override VirtualDirectory GetDirectory(string virtualDir) {
     if (IsThemeDirectory(virtualDir)) {
       return new ThemeDirectory(Previous.GetDirectory(virtualDir));
     }
     else {
       return Previous.GetDirectory(virtualDir);
     }
   }
 }
 
 [AspNetHostingPermission(SecurityAction.Demand,
   Level = AspNetHostingPermissionLevel.Minimal)]
 [AspNetHostingPermission(SecurityAction.InheritanceDemand,
   Level = AspNetHostingPermissionLevel.Minimal)]
 public class ThemeDirectory : VirtualDirectory {
 
    VirtualDirectory _toFilter;
    private ArrayList _children = new ArrayList();
    private ArrayList _directories = new ArrayList();
    private ArrayList _files = new ArrayList();
 
    public override IEnumerable Children {
      get { return _children; }
    }
 
    public override IEnumerable Directories {
      get { return _directories; }
    }
 
    public override IEnumerable Files {
      get { return _files; }
    }
 
    public ThemeDirectory(VirtualDirectory toFilter) : base(toFilter.VirtualPath) {
      _toFilter = toFilter;
      BuildChild();
    }
 
    private void BuildChild() {
      foreach (VirtualDirectory dirToFilter in _toFilter.Directories) {
        ThemeDirectory themeDir = new ThemeDirectory(dirToFilter);
        _children.Add(themeDir);
        _directories.Add(themeDir);
      }
 
      foreach (VirtualFile fileToFilter in _toFilter.Files) {
        string fileExtension = VirtualPathUtility.GetExtension(fileToFilter.VirtualPath).TrimStart('.');
        if (string.Compare(fileExtension, "css", true) != 0) {
          _children.Add(fileToFilter);
          _files.Add(fileToFilter);
        }
        else {
          //archivo .css no incluir
        }
      }
    }
  }
}

Some of the code has been modified for readability, download the original source code here.

Note: In order to use this VPP you’ll have to copy the code above into a new class in your App_Code directory.

Caveat: If a Web site is precompiled for deployment, content provided by a VirtualPathProvider instance is not compiled, and no VirtualPathProvider instances are used by the precompiled site. – Taken from the article titled VirtualPathProvider Class on MSDN.


Conclusion:
This is one of the nicest work arounds or resolution to the issues surrounding ASP.NET 2.0 Themes. It allows us to leverage the power of ASP.NET 2.0 default Skins, allows us to logically group design related resources (Style Sheets, images, default Skins, videos, etc…) in the App_Theme directory, allows us to control the loading order (cascades) of style sheets, allows us to use Conditional Comments, to define Media Types, to override / inherit Styles, and to continue using CSS as it’s intended. In addition we can now easily integrate the ASP.NET 2.0 CSS Friendly Control Adapters into our web applications.

Author: Adam Kahtava Categories: .NET, ASP.NET, CSS, Themes and Skins Tags:

In Favor of Using Style Elements / Embedded Style Sheets / Style Blocks / Style Tags or Whatever You Want To Call Them inside the HTML / XHTML Body.

March 20th, 2007

I’ve been using Style Elements within the HTML Body tag to work around some of the design flaws presented in ASP.NET 2.0 Themes – see the second solution in this post for more details. I’ve been leary of using this method because it’s not a best practice, since it compromises the validity of the HTML / XHTML document. I decided to do a little more research on this subject and made the following discoveries.

Discoveries:

  1. Some of the more complex web sites (Amazon and Yahoo!) make use of Style Elements within the Body Element – see the source snippets below.
  2. Gecko (Firefox, Flock, Mozilla, etc…) based browsers automatically move Style Elements found within the Body Element into the Head Element and render the page as expected – see the rendered Document Object Model (DOM) image below.
  3. Internet Explorer doesn’t move the Style Element into the Head Element, but renders the page as expected.
  4. Opera… well I wish I knew what Opera did, but the page renders as expected.

Source snippet from Amazon:

</table>
    </td>
  </tr>
</table

<style type=”text/css”>
.lol-hr-center { margin: 5px; border-top-width: 1px;
/* and so on… */
}
</style>

<div id=”listoflists_data” style=”display:none”>
Note how the Style element is located between the <table> and <div> tags.


Source snippet from Yahoo!:

<h4>
<
a id=”paweather” class=”details” href=”r/wb/*-http://weather.yahoo.com/forecast/USKS0448_f.html”><span class=”icon”>Weather <b><strong>51&deg;</strong>F</b></span></a>

<style type=”text/css”>#patabs #weather .icon{background:url(http://us.i1.yimg.com/us.yimg.com/i/us/we/31/b/26.gif) 3px 2pxno-repeat;}</style>

</h4>
Note how the Style element is located within the <h4> tag.

A snapshot of the Document Object Model (DOM) as seen through Firebug:


Note the highlighted area references the Yahoo! source snippet from above.
Conclusion: Although the Style Element within the Body Element compromises the validity of a document, some of the leaders in web design and accessibility use this approach, so it may not be as big a work around or hack.

Author: Adam Kahtava Categories: .NET, ASP.NET, CSS, DOM, Firebug, Firefox, IE, Opera, Themes and Skins Tags:

The Problems with Themes, Skins, and Cascading Style Sheets (CSS) in ASP.NET 2.0 – Creating Printer Friendly Pages (defining a CSS Print Media Type) with CSS While Using Themes (Work Around #5)

February 25th, 2007

In this post I outline a couple alternate ways of defining the CSS Print Media Type with Themes. ASP.NET 2.0′s Themes and Skins have a number of design flaws – Themes and Skins depend almost entirely on Cascading Style Sheets (CSS), but don’t fully support CSS – I’ve listed some “Work Arounds” for a couple design flaws. I don’t recommend any of these “Work Arounds” since they contribute to software entropy before your application is even developed, instead I suggest sticking with CSS and perhaps using some default Skins that define CSS selectors like classes or IDs.

The Problem / Question:
How can I use the CSS Print Media Type with Themes? In the past I’ve used an External Style Sheet which defined the Print Media Type, but ASP.NET 2.0 omits the Media Type attribute when it automatically includes all my CSS files (from the active Theme directory) into the HTML Head tag.

A Solution / Work Around:
The Print Media Type isn’t constrained to External Style Sheets and can be defined in the Style Element, in the @Media rule, and even specified through the @Import rule.

An example of the problem:

The directory structure:

The rendered XHTML:
<head>
<title>The Problems With Themes and Skins in ASP.NET 2.0</title>
<link href=“App_Themes/Default/PrinterFriendlyStyleSheet.css”
type=”text/css” rel=”stylesheet” />
<link href=“App_Themes/Default/StyleSheet.css”
type=”text/css” rel=”stylesheet” />
</head>
Note each externally linked Style Sheet lacks a media type.

Our desired XHTML (using an Externally Linked Style Sheet and a Print Media Type) would have looked something like this:
<head>
<link href=“App_Themes/Default/PrinterFriendlyStyleSheet.css”
type=”text/css” rel=”stylesheet” media=”all” />
<link href=”App_Themes/Default/PrinterFriendlyStyleSheet.css”
type=”text/css” rel=”stylesheet” media=”print” />
</head>
Note the Media Type (media=”print”) in bold.

The solutions:

Option 1. Use the Media Rule (@Media) to define the print Media Type inside an Externally Linked Style Sheet.

An example:
@Media Print {
body {
background-color: #FFFFFF;
}
/*… your CSS here …*/
#Menu, #AdvertismentContainer {
display: none;
}
#Content {
width: 100%;
}
}
Discussion: This is probably the best alternative to defining the Media Type in an Externally Linked Style Sheet – the other solutions introduce problems of their own.

Option 2. Use the Import Rule (@Import) to load your printer friendly Style Sheet from an alternate location and define a Media Type – this involves removing your printer friendly Style Sheet from the Themes (App_Theme directory).

An example:
@Import url(“/AppName/CSS/PrinterFriendlyStyleSheet.css”) Print;

Discussion: This solution requires moving our Printer Friendly Style Sheet outside the Theme directory, since Themes don’t allow us to exclude a Style Sheet folder (see Excluding a CSS folder for more details). Once we start moving Style Sheets outside the Themes directory we should probably ask ourselves why we’re even using Themes, and consider regaining complete control over our CSS by moving all the CSS files outside the Theme directory. At this point we could revert to Externally Linking our Style Sheets where we could define our Media Type attributes. In addition the CSS URL function used in this solution confuses many.

Option 3. Use the Style Element to define a Print Media Type.

An example:
<style type=”text/css” media=“print”>
/*… your CSS here …*/
</style>

Discussion: This solution doesn’t work if the Style Elements are defined in the HTML head (see Using Internal (Embedded) Style Sheets with Themes for more details), you can however move the Style Element into the Body of the document, this compromises the HTML validation, but large e-commerce sites like Amazon and Yahoo! make heavy use of this method.

Option 4. Sub class the HtmlHead class to enumerate through the child controls and add new Meta attributes to the child controls using the HtmlLink class. See my post titled Defining a Media Type(s) for more details.
Discussion: This solution requires a fair amount of work and only solves one of the many problems with Themes, pursuing this solution would probably be a case of not seeing the forest for the trees.

In conclusion; Themes are a nice addition to ASP.NET, but have some significant design flaws particularly in the way it uses CSS – in this case how printer friendly (print) CSS Media Types are defined. I wouldn’t recommend using Themes on a complex web applications that make heavy use of CSS or AJAX, but for small projects they may be a nice option.

Related links:

Related posts:

Author: Adam Kahtava Categories: .NET, ASP.NET, CSS, Themes and Skins Tags: