﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <channel>
    <title>Atashbahar.com</title>
    <description>This is my personal blog!</description>
    <link>http://atashbahar.com/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.Net Syndication Generator 1.0.0.0 (http://dotnetblogengine.net/)</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://atashbahar.com/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Khaled Atashbahar</dc:creator>
    <dc:title>Atashbahar.com</dc:title>
    <item>
      <title>Contains in array list validation attribute for ASP.NET MVC</title>
      <description>&lt;p&gt;Following custom validation attribute checks if the posted value is one of the values available in the list of valida values for that attribute.&lt;/p&gt;
&lt;pre class="csharp" name="code"&gt;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;

namespace MyWebApplication.Models
{
    public sealed class ContainsAttribute : ValidationAttribute
    {
        private readonly IEnumerable&amp;lt;string&amp;gt; _values;

        public ContainsAttribute(string[] values)
        {
            _values = values;
        }

        public ContainsAttribute(int[] values)
        {
            _values = values.Select(x =&amp;gt; x.ToString());
        }

        public ContainsAttribute(double[] values)
        {
            _values = values.Select(x =&amp;gt; x.ToString(CultureInfo.InvariantCulture));
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
                return ValidationResult.Success;

            if (_values != null &amp;amp;&amp;amp; !_values.Contains(value))
            {
                var valuesString = string.Join(&amp;quot;, &amp;quot;, _values.Select(x =&amp;gt; $&amp;quot;&amp;#39;{x}&amp;#39;&amp;quot;));
                var message = $&amp;quot;Provided value for {validationContext.MemberName} property is not valid. Valid values are {valuesString}.&amp;quot;;
                return new ValidationResult(message);
            }

            return ValidationResult.Success;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;You can use it like this:&lt;/p&gt;
&lt;pre class="csharp" name="code"&gt;
[Contains(new[] { "first value", "second value", "third value" })]
public string MyValue { get; set; }
&lt;/pre&gt;</description>
      <link>http://atashbahar.com/post/Contains-in-array-list-validation-attribute-for-ASPNET-MVC.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Contains-in-array-list-validation-attribute-for-ASPNET-MVC.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=6096bb17-854d-4222-94d0-461f03344816</guid>
      <pubDate>Tue, 21 Jun 2016 00:53:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=6096bb17-854d-4222-94d0-461f03344816</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=6096bb17-854d-4222-94d0-461f03344816</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Contains-in-array-list-validation-attribute-for-ASPNET-MVC.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=6096bb17-854d-4222-94d0-461f03344816</wfw:commentRss>
    </item>
    <item>
      <title>Add "www" prefix to your website using IIS URL Rewrite</title>
      <description>&lt;p&gt;&amp;nbsp;You can use following URL Rewrite rule to force all URLs in your website to start with &amp;quot;www&amp;quot;:&lt;/p&gt;
&lt;pre class="xml" name="code"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;configuration&amp;gt;
&amp;lt;system.webServer&amp;gt;
    &amp;lt;rewrite&amp;gt;
        &amp;lt;rules&amp;gt;
              &amp;lt;rule name=&amp;quot;Add WWW&amp;quot; stopProcessing=&amp;quot;true&amp;quot;&amp;gt;
              &amp;lt;match url=&amp;quot;^(.*)$&amp;quot; /&amp;gt;
              &amp;lt;conditions&amp;gt;
                 &amp;lt;add input=&amp;quot;{HTTP_HOST}&amp;quot; pattern=&amp;quot;^(?!www\.)(.*)$&amp;quot; /&amp;gt;
              &amp;lt;/conditions&amp;gt;
              &amp;lt;action type=&amp;quot;Redirect&amp;quot; url=&amp;quot;http://www.{C:0}{PATH_INFO}&amp;quot; redirectType=&amp;quot;Permanent&amp;quot; /&amp;gt;
           &amp;lt;/rule&amp;gt;
        &amp;lt;/rules&amp;gt;
    &amp;lt;/rewrite&amp;gt;
&amp;lt;/system.webServer&amp;gt;
&lt;/pre&gt;</description>
      <link>http://atashbahar.com/post/Add-www-prefix-to-your-website-using-IIS-URL-Rewrite.aspx</link>
      <author>Admin</author>
      <comments>http://atashbahar.com/post/Add-www-prefix-to-your-website-using-IIS-URL-Rewrite.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=d8751f38-62bb-4e5a-90e5-61d5fd747543</guid>
      <pubDate>Wed, 15 Jul 2015 03:03:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Admin</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=d8751f38-62bb-4e5a-90e5-61d5fd747543</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=d8751f38-62bb-4e5a-90e5-61d5fd747543</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Add-www-prefix-to-your-website-using-IIS-URL-Rewrite.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=d8751f38-62bb-4e5a-90e5-61d5fd747543</wfw:commentRss>
    </item>
    <item>
      <title>Multiple indexes over an in memory collection for faster search</title>
      <description>&lt;p&gt;I have a big in-memory collection of following simplified class:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
public class Product 
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public int CategoryId { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;I need to search for products based on different properties like UserName or CategoryId. One way of searching would be using linq to objects like:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
var userProducts = products.Where(x =&amp;gt; x.UserName == &amp;quot;SomeValue&amp;quot;)
&lt;/pre&gt;
&lt;p&gt;This takes some processing when collection is too big and in my case it would be called hundreds of time each second.&lt;/p&gt;
&lt;p&gt;What I came up with was to introduce a new collection that supports indexing over different properties:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
public class FastCollection&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;
{
    private IList&amp;lt;T&amp;gt; _items;
    private IList&amp;lt;Expression&amp;lt;Func&amp;lt;T, object&amp;gt;&amp;gt;&amp;gt; _lookups;
    private Dictionary&amp;lt;string, ILookup&amp;lt;object, T&amp;gt;&amp;gt; _indexes;

    public FastCollection(IList&amp;lt;T&amp;gt; data)
    {
        _items = data;
        _lookups = new List&amp;lt;Expression&amp;lt;Func&amp;lt;T, object&amp;gt;&amp;gt;&amp;gt;();
        _indexes = new Dictionary&amp;lt;string, ILookup&amp;lt;object, T&amp;gt;&amp;gt;();
    }

    public void AddIndex(Expression&amp;lt;Func&amp;lt;T, object&amp;gt;&amp;gt; property)
    {
        _lookups.Add(property);
        _indexes.Add(property.ToString(), _items.ToLookup(property.Compile()));
    }

    public void Add(T item)
    {
        _items.Add(item);
        RebuildIndexes();
    }

    public void Remove(T item)
    {
        _items.Remove(item);
        RebuildIndexes();
    }

    public void RebuildIndexes()
    {
        if (_lookups.Count &amp;gt; 0)
        {
            _indexes = new Dictionary&amp;lt;string, ILookup&amp;lt;object, T&amp;gt;&amp;gt;();
            foreach (var lookup in _lookups)
            {
                _indexes.Add(lookup.ToString(), _items.ToLookup(lookup.Compile()));
            }
        }
    }

    public IEnumerable&amp;lt;T&amp;gt; FindValue&amp;lt;TProperty&amp;gt;(Expression&amp;lt;Func&amp;lt;T, TProperty&amp;gt;&amp;gt; property, TProperty value)
    {
        var key = property.ToString();
        if(_indexes.ContainsKey(key))
        {
            return _indexes[key][value];
        }
        else
        {
            var c = property.Compile();
            return _items.Where(x =&amp;gt; c(x).Equals(value));
        }
    }

    public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
&lt;/pre&gt;
&lt;p&gt;You can initialize the collection like this:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
var fc = new FastCollection&amp;lt;Product&amp;gt;(products);
fc.AddIndex(x =&amp;gt; x.Id);
fc.AddIndex(x =&amp;gt; x.UserName);
fc.AddIndex(x =&amp;gt; x.CategoryId);
&lt;/pre&gt;
&lt;p&gt;And finally you can search the collection like this:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
var userProducts = gc.FindValue(x =&amp;gt; x.UserName, &amp;quot;SomeValue&amp;quot;);
&lt;/pre&gt;
&lt;p&gt;The fast collection makes a big difference when it comes to performance.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Multiple-indexes-over-an-in-memory-collection-for-faster-search.aspx</link>
      <author>Admin</author>
      <comments>http://atashbahar.com/post/Multiple-indexes-over-an-in-memory-collection-for-faster-search.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=9191b6ae-58e3-42f8-b733-dd055e0a06ba</guid>
      <pubDate>Sun, 21 Sep 2014 13:12:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Admin</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=9191b6ae-58e3-42f8-b733-dd055e0a06ba</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=9191b6ae-58e3-42f8-b733-dd055e0a06ba</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Multiple-indexes-over-an-in-memory-collection-for-faster-search.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=9191b6ae-58e3-42f8-b733-dd055e0a06ba</wfw:commentRss>
    </item>
    <item>
      <title>Native apps vs. web apps; Are web apps there yet?</title>
      <description>&lt;p&gt;I think we have heard this argument a lot recently. These days there is an app for everything. But is it really necessary? Should everything be an app? What about web apps? Can web apps offer the same functionality as native apps?&lt;/p&gt;
&lt;p&gt;Native apps are a must have when you want to access the native functionality of the device or need all the raw power a device can offer.&lt;/p&gt;
&lt;p&gt;Web standards have grown a lot in recent years and browser&amp;rsquo;s adoption of standards is getting better and better especially on handheld devices.&lt;/p&gt;
&lt;p&gt;Benefit of having web applications is the big range of devices and platforms you can reach without doing any change. You can design and code your website to be accessible on huge range of devices. From desktop browsers to mobile browsers and even big screen tvs.&lt;/p&gt;
&lt;p&gt;Another big benefit would be discoverability by search engines. This is especially useful for websites that generate content and have a big user base.&lt;/p&gt;
&lt;p&gt;Recently I have been involved in developing &lt;a href="http://ecardcanvas.com"&gt;eCardCanvas.com&lt;/a&gt; website. The concept is very simple. Allow users to create and share greeting cards. But there were a few requirements that made it a little challenging. It must use no Flash and be accessible on handheld devices.&lt;/p&gt;
&lt;p&gt;No Flash part made it obvious we have to use &lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;html5&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Canvas_element&amp;lrm;"&gt;canvas&lt;/a&gt;. Html5 canvas is very well supported on all modern browsers and is very rich in the functionality.&lt;/p&gt;
&lt;p&gt;By using &lt;a href="http://en.wikipedia.org/wiki/Responsive_web_design"&gt;responsive design&lt;/a&gt; we were able to offer the same desktop experience on handheld devices. It was a bit challenging to optimize the card editor functionality for mobile devices but I think we did a good job in that area.&lt;/p&gt;
&lt;p&gt;Feel free to check the website at &lt;a href="http://ecardcanvas.com"&gt;eCardCanvas.com&lt;/a&gt; and try our card editor &lt;a href="http://ecardcanvas.com/editor"&gt;eCardCanvas.com/editor&lt;/a&gt;. Your input is welcome and highly appreciated.&lt;/p&gt;
&lt;p&gt;To go back to the original argument, you might not get the same performance you are getting in a native app but in most cases it is enough to offer a good user experience. And when you count in other benefits of having web as your platform it even gets more appealing.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/native-apps-vs-web-apps-are-we-there-yet.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/native-apps-vs-web-apps-are-we-there-yet.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=b3c4c4a2-974c-4c5e-a842-37dd8be942d2</guid>
      <pubDate>Sun, 29 Sep 2013 22:57:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=b3c4c4a2-974c-4c5e-a842-37dd8be942d2</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=b3c4c4a2-974c-4c5e-a842-37dd8be942d2</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/native-apps-vs-web-apps-are-we-there-yet.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=b3c4c4a2-974c-4c5e-a842-37dd8be942d2</wfw:commentRss>
    </item>
    <item>
      <title>ASP.NET MVC CSS Bundling Pitfalls</title>
      <description>&lt;p&gt;This might seem obvious to some but I think it is still worth mentioning.&lt;/p&gt;
&lt;p&gt;You should always bundle CSS files that are in the same folder and the Virtual Path of that bundle must match that folder&amp;rsquo;s path. For example if you are bundling multiple CSS files in &amp;quot;~/Content/CSS/&amp;quot; folder, your bundle&amp;rsquo;s Virtual path should be something like &amp;quot;~/Content/CSS/All&amp;quot;.&lt;/p&gt;
&lt;p&gt;The reason being images inside CSS files are relative to the location of the CSS file. So if the virtual path doesn&amp;rsquo;t match the CSS file location images won&amp;rsquo;t load.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/ASPNET-MVC-CSS-Bundling-Pitfalls.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/ASPNET-MVC-CSS-Bundling-Pitfalls.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=a6a1ace6-1ceb-420e-8ede-c0a80f2c8a01</guid>
      <pubDate>Tue, 23 Jul 2013 00:51:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=a6a1ace6-1ceb-420e-8ede-c0a80f2c8a01</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=a6a1ace6-1ceb-420e-8ede-c0a80f2c8a01</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/ASPNET-MVC-CSS-Bundling-Pitfalls.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=a6a1ace6-1ceb-420e-8ede-c0a80f2c8a01</wfw:commentRss>
    </item>
    <item>
      <title>Make your PNG images even smaller with PngOptimzer!</title>
      <description>&lt;p&gt;While ago I found this &lt;a target="_blank" href="http://psydk.org/PngOptimizer.php"&gt;amazing tool&lt;/a&gt; that optimizes PNG images and reduces the size effectively. I use &lt;a target="_blank" href="http://www.adobe.com/products/fireworks.html"&gt;Adobe Fireworks&lt;/a&gt; to create lots of PNG images for my work and using this tool makes them much smaller in size.&lt;/p&gt;
&lt;p class="img"&gt;&lt;img alt="PngOptimizer" width="585" height="278" src="http://atashbahar.com/userfiles/image/PngOptimizer.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://psydk.org/PngOptimizer.php"&gt;PngOptimizer&lt;/a&gt; is free and using it is very simple. Just drag-n-drop your files over the application and they get optimized!&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Make-your-PNG-images-even-smaller-with-PngOptimzer.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Make-your-PNG-images-even-smaller-with-PngOptimzer.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=42f9df4c-edf6-410b-8de9-95dea40ef3f9</guid>
      <pubDate>Wed, 27 Jul 2011 12:39:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=42f9df4c-edf6-410b-8de9-95dea40ef3f9</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=42f9df4c-edf6-410b-8de9-95dea40ef3f9</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Make-your-PNG-images-even-smaller-with-PngOptimzer.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=42f9df4c-edf6-410b-8de9-95dea40ef3f9</wfw:commentRss>
    </item>
    <item>
      <title>ASP.NET MVC tab-based navigation</title>
      <description>&lt;p&gt;First of all this is not one of those JavaScript tab navigation scripts. Actually we are going to use no JavaScript.&lt;/p&gt;
&lt;p&gt;Each tab is going to be linked to an ASP.NET MVC controller action. This is how end result is going to look like:&lt;/p&gt;
&lt;p class="img"&gt;&lt;img src="/userfiles/image/MvcTabNav.png" alt="ASP.NET MVC Tabbed Navigation" /&gt;&lt;/p&gt;
&lt;p&gt;And here is the sample website I have created which contains everything you need:&lt;/p&gt;
&lt;div class="dsrc"&gt;&lt;a href="http://atashbahar.com/userfiles/file/MvcTabNav.zip"&gt;Download Sample Website&lt;/a&gt; &lt;span class="sz"&gt;(15KB)&lt;/span&gt;&lt;/div&gt;
&lt;h4&gt;So how exactly this works?&lt;/h4&gt;
&lt;p&gt;We have a HTML helper method named SimpleNav that renders the HTML to the master page. This is how it is called:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
&amp;lt;div id=&amp;quot;menubar&amp;quot;&amp;gt;
    &amp;lt;%= Html.SimpleNav(new[] {
        new SimpleNavItem{Text=&amp;quot;Home&amp;quot;, Action=&amp;quot;Index&amp;quot;, Controller = &amp;quot;Home&amp;quot;},
        new SimpleNavItem{Text=&amp;quot;Blog&amp;quot;, Action=&amp;quot;Index&amp;quot;, Controller = &amp;quot;Blog&amp;quot;, GetSelected = ((a, c) =&amp;gt; (c == &amp;quot;Blog&amp;quot;))},
        new SimpleNavItem{Text=&amp;quot;About&amp;quot;, Action=&amp;quot;About&amp;quot;, Controller = &amp;quot;Home&amp;quot;, GetSelected = ((a, c) =&amp;gt; c == &amp;quot;Home&amp;quot; &amp;amp;&amp;amp; a == &amp;quot;About&amp;quot;)},
        new SimpleNavItem{Text=&amp;quot;Contact&amp;quot;, Action=&amp;quot;Contact&amp;quot;, Controller = &amp;quot;Home&amp;quot;, GetSelected = ((a, c) =&amp;gt; c == &amp;quot;Home&amp;quot; &amp;amp;&amp;amp; a == &amp;quot;Contact&amp;quot;)}
    }) %&amp;gt;  
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The code for this helper method is very straightforward. It simply generates an unordered list of links:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
public static string SimpleNav(this HtmlHelper html, IEnumerable&amp;lt;SimpleNavItem&amp;gt; navItems)
{
    var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
    string controller = html.ViewContext.RouteData.Values[&amp;quot;controller&amp;quot;].ToString();
    string action = html.ViewContext.RouteData.Values[&amp;quot;action&amp;quot;].ToString();

    TagBuilder ul = new TagBuilder(&amp;quot;ul&amp;quot;);
    ul.AddCssClass(&amp;quot;clearfix&amp;quot;);

    StringBuilder listBuilder = new StringBuilder();
    TagBuilder li = null;
    TagBuilder a = null;
    foreach (var item in navItems)
    {
        a = new TagBuilder(&amp;quot;a&amp;quot;);
        a.Attributes.Add(&amp;quot;href&amp;quot;, urlHelper.Action(item.Action, item.Controller));
        a.InnerHtml = item.Text;

        li = new TagBuilder(&amp;quot;li&amp;quot;);
        if (item.GetSelected != null &amp;amp;&amp;amp; item.GetSelected(action, controller))
            li.AddCssClass(&amp;quot;sel&amp;quot;);
        li.InnerHtml = a.ToString();

        listBuilder.Append(li.ToString());
    }

    ul.InnerHtml = listBuilder.ToString();

    return ul.ToString();
}
&lt;/pre&gt;
&lt;pre name="code" class="csharp"&gt;
public class SimpleNavItem
{
    public string Text { get; set; }
    public string Action { get; set; }
    public string Controller { get; set; }
    public Func&amp;lt;string, string, bool&amp;gt; GetSelected { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;The interesting part of the above code may be GetSelected which is an anonymous method. You might want a tab gets highlighted on certain conditions for example highlight the Blog tab for all Actions of the related Controller. The method accepts two Strings which are name of the current Controller and Action and returns a Boolean which indicated if the tab should be highlighted or not.&lt;/p&gt;
&lt;p&gt;The final step which I like the most is to make it pretty. By using a simple background image and a small amount of CSS magic you can easily achieve this:&lt;/p&gt;
&lt;pre name="code" class="css"&gt;
#menubar {
    border-bottom: solid 3px #8CC740;
    padding-left: 10px;
}
#menubar li {
    display: inline;
}
#menubar li a {
    float: left;    
    line-height: 21px;
    width: 80px;
    margin-right: 1px;
    background: url(tabs.gif) no-repeat 0px 0px;    
    color: #444;    
    text-align: center;
    text-decoration: none;
}
#menubar li a:hover {
    background-position: 0px -22px;
    text-decoration: none;
}
#menubar li.sel a {
    background-position: 0px bottom;
    color: #fff;
}
&lt;/pre&gt;
&lt;p&gt;This may not be the most complete solution but it has helped me in so many projects. Hopefully it does the same for you.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/ASPNET-MVC-tab-based-navigation.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/ASPNET-MVC-tab-based-navigation.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=a878795e-35cd-4d45-b671-3bc68fe239c8</guid>
      <pubDate>Thu, 16 Dec 2010 09:08:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=a878795e-35cd-4d45-b671-3bc68fe239c8</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=a878795e-35cd-4d45-b671-3bc68fe239c8</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/ASPNET-MVC-tab-based-navigation.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=a878795e-35cd-4d45-b671-3bc68fe239c8</wfw:commentRss>
    </item>
    <item>
      <title>Detect when a JavaScript popup window gets closed</title>
      <description>&lt;p&gt;A while ago in one of my projects I came into this problem that I wanted to detect when a child window that is created with window.open method gets closed.&lt;/p&gt;
&lt;p&gt;As you know it is possible to call a JavaScript function in parent page from a popup window using parent.[JavaScript-Method-Name]. But this didn't work for me because the page I was opening was from another domain and couldn't modify its content.&lt;/p&gt;
&lt;p&gt;Unfortunately the popup window does not have any close event that you can listen to but there is a closed property that is true when window gets closed. So the solution I came up with was to start a timer and check the closed property of the child window every second and clear the timer when the window gets closed. Here is the code:&lt;/p&gt;
&lt;pre class="javascript" name="code"&gt;
var win = window.open('http://www.google.com', 'google','width=800,height=600,status=0,toolbar=0'); 
var timer = setInterval(function() { 
    if(win.closed) {
        clearInterval(timer);
        alert('closed');
    }
}, 1000);

&lt;/pre&gt;
&lt;p&gt;Hope this helps.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Detect-when-a-JavaScript-popup-window-gets-closed.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Detect-when-a-JavaScript-popup-window-gets-closed.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=22fcabd5-9db2-4d37-b1bb-591efb0d9379</guid>
      <pubDate>Tue, 27 Apr 2010 13:05:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=22fcabd5-9db2-4d37-b1bb-591efb0d9379</pingback:target>
      <slash:comments>17</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=22fcabd5-9db2-4d37-b1bb-591efb0d9379</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Detect-when-a-JavaScript-popup-window-gets-closed.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=22fcabd5-9db2-4d37-b1bb-591efb0d9379</wfw:commentRss>
    </item>
    <item>
      <title>Can we build a document-sharing website like Scribd with .Net?</title>
      <description>&lt;p&gt;This is a question I had in my mind for a while. I was very interested to know how document-sharing websites work in general and if it is possible to build one using .Net and other free and open source technologies.&lt;/p&gt;
&lt;p&gt;After spending one Internet, readay searching through dig bnlogs and forums I came to the conclusion that it is possible! At least in theory it is possible.&lt;/p&gt;
&lt;p&gt;What websites like &lt;a href="http://en.wikipedia.org/wiki/Scribd" target="_blank"&gt;Scribd&lt;/a&gt; do is that they allow their users to upload documents in various formats, then this documents will be shown in a control that is implemented using &lt;a href="http://en.wikipedia.org/wiki/Adobe_Flash" target="_blank"&gt;Adobe Flash&lt;/a&gt;. So they convert documents from various formats to Adobe Flash but how they do it and what goes on behind the scene?&lt;/p&gt;
&lt;p&gt;I will try to explain different steps of the process and show you with which tool you can do the same with .Net. Just before we start this is not something official about how Scribd or any other websites of this type work, this is only how I think they work and how it is possible to do the same.&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Step 1: Convert documents from various formats to PDF&lt;/h4&gt;
&lt;p class="rimg"&gt;&lt;img width="200" height="66" src="/userfiles/image/Logos/OpenOffice.png" alt="OpenOffice Logo" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/OpenOffice" target="_blank"&gt;OpenOffice&lt;/a&gt; supports various formats (including Microsoft Office formats) and it can export them to &lt;a href="http://en.wikipedia.org/wiki/PDF" target="_blank"&gt;PDF&lt;/a&gt; format which is what we need.&lt;/p&gt;
&lt;p&gt;So we have the tool but how to call it from our code. Luckily there is a &lt;a href="http://www.codeproject.com/KB/files/generatepdf.aspx" target="_blank"&gt;great article in CodeProject&lt;/a&gt; which solves this problem in an elegant way. This article provides solution alongside the necessary code to easily call OpenOffice to convert documents to PDF format.&lt;/p&gt;
&lt;h4&gt;Step 2: Index document contents to be able to search through them&lt;/h4&gt;
&lt;p&gt;Another aspect of document-sharing sites is search. They allow their users to search for documents using keywords. They store hundreds of thousands of documents so having a proficient searching mechanism is very important.&lt;/p&gt;
&lt;p&gt;To index documents we need to extract text from the documents. In first step we convert all documents to PDF, so we need to find a way to extract text from PDF files. One way to do this is to use the IFilter interface which was designed by Microsoft for use in its Indexing Service. You can find a great article in CodeProject named &lt;a href="http://www.codeproject.com/KB/cs/IFilter.aspx" target="_blank"&gt;Using IFilter in C#&lt;/a&gt; which describes how you can use them to extract text from various document formats (which PDF is one of them).&lt;/p&gt;
&lt;p class="rimg"&gt;&lt;img width="200" height="20" src="/userfiles/image/Logos/lucene_net.gif" alt="Lucene.Net Logo" /&gt;&lt;/p&gt;
&lt;p&gt;After extracting text we need a tool for index the extracted text and also be able to search through this index in a proficient way. I have been using &lt;a href="http://incubator.apache.org/lucene.net/" target="_blank"&gt;Lucene.Net&lt;/a&gt; which is a port of famous &lt;a href="http://lucene.apache.org/java/" target="_blank"&gt;Lucene&lt;/a&gt; library for a while and I can say it is amazingly fast and also easy to use. Lucene.Net is exactly what we want here. It has all the necessary features to index the extracted text from documents and search through them very fast.&lt;/p&gt;
&lt;h4&gt;Step 3: Create thumbnails for the documents&lt;/h4&gt;
&lt;p class="rimg"&gt;&lt;img width="150" height="157" src="/userfiles/image/Logos/Ghostscript.png" alt="ghostscript logo" /&gt;&lt;/p&gt;
&lt;p&gt;This may look unnecessary but all of document-sharing websites have it and I think it&amp;rsquo;s cool. There are commercial libraries for .Net that allow you to create an image from pages of a PDF document. But we are looking for a free solution here so using commercial components is not an option.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Ghostscript" target="_blank"&gt;Ghostscript&lt;/a&gt; has the ability to raster PDF files. What we need is a .Net wrapper that can call it. There are many implementations that can be easily found by doing a simple search using your favorite search engine. &lt;a href="http://www.mattephraim.com/blog/2009/07/08/introducing-ghostscriptsharp/" target="_blank"&gt;GhostscriptSharp&lt;/a&gt; is one of them.&lt;/p&gt;
&lt;h4&gt;Step4: Convert the PDF files to Adobe Flash&lt;/h4&gt;
&lt;p class="rimg"&gt;&lt;img width="200" height="57" src="/userfiles/image/Logos/swftools.png" alt="SWFTools logo" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.swftools.org/" target="_blank"&gt;SWFTools&lt;/a&gt; is a collection of utilities which one of them is PDF2SWF. PDF2SWF is a command line utility which simply converts your PDF to SWF. I couldn't find a .Net wrapper for this utility but calling a command line program from .Net is very easy.&lt;/p&gt;
&lt;p&gt;After the conversion is done we get a SWF file of our PDF that simply is a collection of pages with no navigation. PDF2SWF provides the option to combine a simple navigation UI with the generated SWF but I think it would be better to use a more advanced viewer like &lt;a href="http://swfviewer.blogspot.com/" target="_blank"&gt;SWF Document Viewer&lt;/a&gt; and customize it based on your needs.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;I think the answer to this article title is yes and we can build such a website. I have not tried to do so but it seems we have all the tools necessary to do so.&lt;/p&gt;
&lt;p&gt;I would be glad to hear your thoughts about this and if anyone has tried this approach. I would also like to hear about alternate ways of doing each step in the process.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Can-we-build-a-document-sharing-website-like-Scribd-with-Net.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Can-we-build-a-document-sharing-website-like-Scribd-with-Net.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=dd4a0adb-5e06-4360-9027-a6c41e0e8d2c</guid>
      <pubDate>Sun, 26 Jul 2009 07:47:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=dd4a0adb-5e06-4360-9027-a6c41e0e8d2c</pingback:target>
      <slash:comments>16</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=dd4a0adb-5e06-4360-9027-a6c41e0e8d2c</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Can-we-build-a-document-sharing-website-like-Scribd-with-Net.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=dd4a0adb-5e06-4360-9027-a6c41e0e8d2c</wfw:commentRss>
    </item>
    <item>
      <title>Converting Multipage TIFF image to PDF</title>
      <description>&lt;p&gt;I thought I share this with you because I spent some time before finding the solution. What I wanted to do is to simply convert a multipage &lt;a href="http://en.wikipedia.org/wiki/Tagged_Image_File_Format" target="_blank"&gt;TIFF&lt;/a&gt; image to a PDF file. I wanted this for an ASP.NET project.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tallcomponents.com/" target="_blank"&gt;TallPDF&lt;/a&gt; does this but you have to pay a lot for a simple task (TallPDF does other things too though!). After some searching came to the conclusion that PDF Creation Libraries are my best option here. There are a few for .NET including &lt;a href="http://itextsharp.sourceforge.net/" target="_blank"&gt;iTextSharp&lt;/a&gt;, &lt;a href="http://www.pdfsharp.net/" target="_blank"&gt;PDFsharp&lt;/a&gt; and &lt;a href="http://www.stefanochizzolini.it/en/projects/clown/" target="_blank"&gt;PDF Clown&lt;/a&gt;. I used iTextSharp because it has a sample that was showing how to create a PDF file from a multipage TIFF image (exactly what I wanted).&lt;/p&gt;
&lt;p&gt;Here is the code that does the conversion:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
            // creation of the document with a certain size and certain margins
            iTextSharp.text.Document document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 0, 0, 0, 0);
            
            // creation of the different writers
            iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new System.IO.FileStream(Server.MapPath(&amp;quot;~/App_Data/result.pdf&amp;quot;), System.IO.FileMode.Create));

            // load the tiff image and count the total pages
            System.Drawing.Bitmap bm = new System.Drawing.Bitmap(Server.MapPath(&amp;quot;~/App_Data/source.tif&amp;quot;));
            int total = bm.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);

            document.Open();
            iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
            for (int k = 0; k &amp;lt; total; ++k)
            {
                bm.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, k);
                iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(bm, System.Drawing.Imaging.ImageFormat.Bmp);
                // scale the image to fit in the page
                img.ScalePercent(72f / img.DpiX * 100);
                img.SetAbsolutePosition(0, 0);
                cb.AddImage(img);
                document.NewPage();
            }
            document.Close();
&lt;/pre&gt;
&lt;p&gt;As you can see it is very simple and straightforward.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Converting-Multipage-TIFF-image-to-PDF.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Converting-Multipage-TIFF-image-to-PDF.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=57c5b7f6-9ac2-4512-a17f-aadcf8eea9a6</guid>
      <pubDate>Thu, 30 Apr 2009 06:55:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=57c5b7f6-9ac2-4512-a17f-aadcf8eea9a6</pingback:target>
      <slash:comments>22</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=57c5b7f6-9ac2-4512-a17f-aadcf8eea9a6</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Converting-Multipage-TIFF-image-to-PDF.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=57c5b7f6-9ac2-4512-a17f-aadcf8eea9a6</wfw:commentRss>
    </item>
    <item>
      <title>Stream contents of a folder to output as a zip file</title>
      <description>&lt;p&gt;You have all seen &amp;quot;Download All&amp;quot; feature of popular email providers like Yahoo! And Gmail that allows you to download multiple attachments as a single zip file.&lt;/p&gt;
&lt;p&gt;Recently we needed something like that in one of our projects. We wanted to download contents of a folder as a zip file. It was very important to stream the compressed result to the client as we were compressing them on the server.&lt;br /&gt;
You may say that you could have zipped the folder on server so users could download it directly, but that was not an option in our case because contents of the folder were changing always.&lt;/p&gt;
&lt;p&gt;When comes to compression for .NET, &lt;a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/" target="_blank"&gt;SharpZipLib&lt;/a&gt; is one of the best options you got. At start I thought solving this problem is not going to be very easy but I was in luck because SharpZipLib has a special class name &lt;span class="mnsp"&gt;FastZip&lt;/span&gt; that was exactly what I was looking for. &lt;span class="mnsp"&gt;FastZip&lt;/span&gt; class has a &lt;span class="mnsp"&gt;CreateZip&lt;/span&gt; method that has few overloads. One of the overloads gets an output stream and a path to a folder on disk; what it does is to send the compressed contents of the folder to output stream. This was exactly what I was looking for so I created static &lt;span class="mnsp"&gt;DownloadFolder&lt;/span&gt; method in my &lt;span class="mnsp"&gt;Utility&lt;/span&gt; class that accepts two parameters; first one is the path to the folder that we want to zip and second parameter is of type &lt;span class="mnsp"&gt;HttpResponse&lt;/span&gt;. We use &lt;span class="mnsp"&gt;HttpResponse OutputStream&lt;/span&gt; to send the zipped content to user. Here is the code for this method:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
using System;
using System.Web;

public static class Utility
{
    public static void DownloadFolder(string path, HttpResponse res)
    {
        // cleat the response so we don't send any unwanted data to user
        res.Clear();
        // set the content type ZIP file
        res.ContentType = &amp;quot;application/zip&amp;quot;;
        // setting Content-Disposition to attachement causes the save dialog of the 
        // browser to be shown. We also can set the name of the zip file in this header
        res.AppendHeader(&amp;quot;Content-Disposition&amp;quot;, &amp;quot;attachment; filename=Download.zip;&amp;quot;);
        // it is very important to set BufferOutput to false. Default behavior is to buffer
        // the output before sending it to client and this is not the behavior we want
        res.BufferOutput = false;
        // flush the response so user will get the save dialog as soon as possible
        res.Flush();

        // FastZip is the easies way to zip all the file and folders in the
        // path and stream it through the Response OutputStream
        ICSharpCode.SharpZipLib.Zip.FastZip fz = new ICSharpCode.SharpZipLib.Zip.FastZip();
        fz.CreateZip(res.OutputStream, path, true, null, null);
    }
}
&lt;/pre&gt;
&lt;p&gt;Using this method is very easy. You have two options one is to create an Http Handler; Users download the zipped content by access its address (for example by clicking a link that points to it).&lt;/p&gt;
&lt;pre class="csharp" name="code"&gt;
using System;
using System.Web;

public class DownloadAll : IHttpHandler {
       
    public void ProcessRequest (HttpContext context) 
    {
        Utility.DownloadFolder(context.Server.MapPath(&amp;quot;~/App_Data/Storage&amp;quot;), context.Response);
    }
 
    public bool IsReusable {
        get {
            return true;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Second method is to use it inside your ASPX page, for example when you click a button on your page. Here's how it is done:&lt;/p&gt;
&lt;pre class="html" name="code"&gt;
&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;

&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;

&amp;lt;script runat=&amp;quot;server&amp;quot;&amp;gt;

    protected void Page_Load(object sender, EventArgs e)
    { }

    protected void btnDownload_Click(object sender, EventArgs e)
    {
        Utility.DownloadFolder(Server.MapPath(&amp;quot;~/App_Data/Storage&amp;quot;), Response);
    }
&amp;lt;/script&amp;gt;

&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;
&amp;lt;head runat=&amp;quot;server&amp;quot;&amp;gt;
    &amp;lt;title&amp;gt;Download All&amp;lt;/title&amp;gt;    
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form id=&amp;quot;form1&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;asp:Button ID=&amp;quot;btnDownload&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;Download All&amp;quot; onclick=&amp;quot;btnDownload_Click&amp;quot; /&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;a href=&amp;quot;DownloadAll.ashx&amp;quot;&amp;gt;Download All&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Well, that's it for now! As you can see it was very easy to do something that looked a little hard at start all thanks to SharpZipLib library.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Stream-contents-of-a-folder-to-output-as-a-zip-file.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Stream-contents-of-a-folder-to-output-as-a-zip-file.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=f6b7d028-cc6c-474c-8c40-2049e3623cad</guid>
      <pubDate>Sat, 14 Feb 2009 12:09:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=f6b7d028-cc6c-474c-8c40-2049e3623cad</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=f6b7d028-cc6c-474c-8c40-2049e3623cad</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Stream-contents-of-a-folder-to-output-as-a-zip-file.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=f6b7d028-cc6c-474c-8c40-2049e3623cad</wfw:commentRss>
    </item>
    <item>
      <title>ASP.NET GridView makeover using CSS</title>
      <description>&lt;p&gt;I use ASP.NET GridView in my projects a lot. It is a great control with powerful functionality that can be customized in many ways. GridView has many settings that you can use to alter its look and also offers you some predefined formats that you can use (you can access them by clicking Auto Format link on the bottom of GridView properties panel). What formats do is to modify different styling properties of the GridView such as row style, alternate row style, header style and so on.&lt;/p&gt;
&lt;h4&gt;What is the problem?&lt;/h4&gt;
&lt;p&gt;Modifying different styling properties of the GridView control to create a custom look may be simple but has a few problems. The biggest problem is the styling information will be included in the generated html and that causes the resulting page size to be bigger. Another problem is that you have to modify a lot of properties to find a look that satisfies you. Also later if you want to do a change in the look of GridView you have to modify all&amp;nbsp;instances of the&amp;nbsp;controls in your website.&lt;/p&gt;
&lt;h4&gt;The Solution&lt;/h4&gt;
&lt;p&gt;The good news is that you can use CSS to control the look of the GridView easily. You will add a few hooks to the GridView control and you are ready to write some CSS to completely change the look of the control. I have created a sample website to demonstrate this; you can download it from the link below.&lt;/p&gt;
&lt;div class="dsrc"&gt;&lt;a href="http://atashbahar.com/userfiles/file/GridViewMakeover.zip"&gt;Download Sample Website&lt;/a&gt; &lt;span class="sz"&gt;(10KB)&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Modifying GridView look is very easy using CSS. By spending a little time you can create really cool styles that can reuse in your projects easily. Following picture is a screen shot of the final result of this article.&lt;/p&gt;
&lt;p class="img"&gt;&lt;img src="/userfiles/image/GridViewMakeover/GridView.png" alt="ASP.NET GridView" /&gt;&lt;/p&gt;
&lt;h4&gt;Implementation&lt;/h4&gt;
&lt;p&gt;Here's the GridView control syntax in our ASP.NET page. The only properties that we need to change to provide the custom look are &lt;span class="mnsp"&gt;CssClass&lt;/span&gt;, &lt;span class="mnsp"&gt;PagerStyle-CssClass&lt;/span&gt; and &lt;span class="mnsp"&gt;AlternatingRowStyle-CssClass&lt;/span&gt;.&lt;/p&gt;
&lt;pre name="code" class="html"&gt;
&amp;lt;asp:GridView ID=&amp;quot;gvCustomres&amp;quot; runat=&amp;quot;server&amp;quot;
    DataSourceID=&amp;quot;customresDataSource&amp;quot; 
    AutoGenerateColumns=&amp;quot;False&amp;quot;
    GridLines=&amp;quot;None&amp;quot;
    AllowPaging=&amp;quot;true&amp;quot;
    CssClass=&amp;quot;mGrid&amp;quot;
    PagerStyle-CssClass=&amp;quot;pgr&amp;quot;
    AlternatingRowStyle-CssClass=&amp;quot;alt&amp;quot;&amp;gt;
    &amp;lt;Columns&amp;gt;
        &amp;lt;asp:BoundField DataField=&amp;quot;CompanyName&amp;quot; HeaderText=&amp;quot;Company Name&amp;quot; /&amp;gt;
        &amp;lt;asp:BoundField DataField=&amp;quot;ContactName&amp;quot; HeaderText=&amp;quot;Contact Name&amp;quot; /&amp;gt;
        &amp;lt;asp:BoundField DataField=&amp;quot;ContactTitle&amp;quot; HeaderText=&amp;quot;Contact Title&amp;quot; /&amp;gt;
        &amp;lt;asp:BoundField DataField=&amp;quot;Address&amp;quot; HeaderText=&amp;quot;Address&amp;quot; /&amp;gt;
        &amp;lt;asp:BoundField DataField=&amp;quot;City&amp;quot; HeaderText=&amp;quot;City&amp;quot; /&amp;gt;
        &amp;lt;asp:BoundField DataField=&amp;quot;Country&amp;quot; HeaderText=&amp;quot;Country&amp;quot; /&amp;gt;
    &amp;lt;/Columns&amp;gt;
&amp;lt;/asp:GridView&amp;gt;
&amp;lt;asp:XmlDataSource ID=&amp;quot;customresDataSource&amp;quot; runat=&amp;quot;server&amp;quot; DataFile=&amp;quot;~/App_Data/data.xml&amp;quot;&amp;gt;&amp;lt;/asp:XmlDataSource&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The CSS to provide the custom look is very short and you can change the view and create new looks really easy.&lt;/p&gt;
&lt;pre name="code" class="css"&gt;
.mGrid { 
    width: 100%; 
    background-color: #fff; 
    margin: 5px 0 10px 0; 
    border: solid 1px #525252; 
    border-collapse:collapse; 
}
.mGrid td { 
    padding: 2px; 
    border: solid 1px #c1c1c1; 
    color: #717171; 
}
.mGrid th { 
    padding: 4px 2px; 
    color: #fff; 
    background: #424242 url(grd_head.png) repeat-x top; 
    border-left: solid 1px #525252; 
    font-size: 0.9em; 
}
.mGrid .alt { background: #fcfcfc url(grd_alt.png) repeat-x top; }
.mGrid .pgr { background: #424242 url(grd_pgr.png) repeat-x top; }
.mGrid .pgr table { margin: 5px 0; }
.mGrid .pgr td { 
    border-width: 0; 
    padding: 0 6px; 
    border-left: solid 1px #666; 
    font-weight: bold; 
    color: #fff; 
    line-height: 12px; 
 }   
.mGrid .pgr a { color: #666; text-decoration: none; }
.mGrid .pgr a:hover { color: #000; text-decoration: none; }
&lt;/pre&gt;
&lt;p&gt;I have used three images for header, alternate rows and pager to create a&amp;nbsp;more appealing look. There images are tiled horizontally using CSS to fit the whole row. You can find the images in the sample website code.&lt;/p&gt;
&lt;p class="img"&gt;&lt;img src="/userfiles/image/GridViewMakeover/grd_images.png" alt="GridView Style Images" /&gt;&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;Creating custom looks for GridView control is very easy. You can create a completely different look using only a few lines of CSS. You can use the same CSS style for all&amp;nbsp;GridView controls in your project and later if you want to change the look you can do it from one location in your style sheet file.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/GridView-makeover-using-CSS.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/GridView-makeover-using-CSS.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=66df26df-061e-4a18-bc0a-400e1b1b517a</guid>
      <pubDate>Fri, 23 Jan 2009 10:11:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=66df26df-061e-4a18-bc0a-400e1b1b517a</pingback:target>
      <slash:comments>281</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=66df26df-061e-4a18-bc0a-400e1b1b517a</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/GridView-makeover-using-CSS.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=66df26df-061e-4a18-bc0a-400e1b1b517a</wfw:commentRss>
    </item>
    <item>
      <title>Combine, minify and compress JavaScript files to load ASP.NET pages faster</title>
      <description>&lt;p&gt;Websites are getting more interactive these days and most of this interactivity comes from JavaScript. People are using different JavaScript libraries and frameworks to make their websites more interactive and user friendly.&lt;/p&gt;
&lt;h4&gt;What is the problem?&lt;/h4&gt;
&lt;p&gt;After a while you end up referencing to more than a few JavaScript files in your page and that causes a problem! Your pages will load slower; this happens for two reasons:&lt;/p&gt;
&lt;ul class="vlst"&gt;
    &lt;li&gt;You have used too much JavaScript. Total size of JavaScript files in some websites may reach more than 500KB and that's a lot, especially for users with slow connections. The best solution to this problem is to use gzip to compress JavaScript files as we do later in this article.&lt;/li&gt;
    &lt;li&gt;JavaScript files are loaded one by one after each other by the browser. As you know there is a response time for each request that varies depending on your connection speed and your distance from the server. If you have many JavaScript files in your page these times are added together and cause a big delay when loading a page. I have tried to show this using &lt;a href="http://en.wikipedia.org/wiki/Firebug_(Firefox_extension)" target="_blank"&gt;Firebug&lt;/a&gt; (A very popular and necessary &lt;a href="http://en.wikipedia.org/wiki/Mozilla_Firefox" target="_blank"&gt;FireFox&lt;/a&gt; extension for web developers) in the following screenshot.&lt;br /&gt;
    This is not the case for CSS or image files .If you reference multiple CSS files or images in your page they are loaded together by the browser.&lt;br /&gt;
    The best solution to this problem is to combine JavaScript files into one big file to remove the delay caused when loading multiple JavaScript files one by one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="img"&gt;&lt;img src="/userfiles/image/scriptcombiner/FireBug.png" alt="Firebug shows networl activity for multiple JavaScript files loading" /&gt;&lt;/p&gt;
&lt;h4&gt;What can we do?&lt;/h4&gt;
&lt;p&gt;The answer is simple! Combine the files and &lt;a href="http://en.wikipedia.org/wiki/Gzip" target="_blank"&gt;gzip&lt;/a&gt; the response. Actually we are going to take few extra steps to create something more useful and reusable. But how we are going to do that?&lt;/p&gt;
&lt;p&gt;The easiest way to do this is to use an HTTP Handler that combines JavaScript files and compresses the response. So instead of referencing multiple JavaScript files in our pages we reference this handler like this:&lt;/p&gt;
&lt;pre name="code" class="html"&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ScriptCombiner.axd?s=Site_Scripts&amp;amp;v=1&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;ScriptCombiner.axd&lt;/span&gt; is our HTTP Handler here. Two parameters are passed to the handler, s and v. s stands for set name and v stands for version. When you make a change in your scripts you need to increase the version so browsers will load the new version not the cached one.&lt;br /&gt;
Set Name indicates list of JavaScript files that are processed by this handler. We save the list in a text file inside &lt;span class="mnsp"&gt;App_Data&lt;/span&gt; folder. The file contains relative paths to JavaScript files that need to be combined. Here is what &lt;span class="mnsp"&gt;Site_Scripts.txt&lt;/span&gt; file content should look like:&lt;/p&gt;
&lt;pre name="code" class="html"&gt;
~/Scripts/ScriptFile1.js
~/Scripts/ScriptFile2.js
&lt;/pre&gt;
&lt;p&gt;Most of work is done inside the HTTP Handler; I try to summarize what happens in the handler:&lt;/p&gt;
&lt;ul class="vlst"&gt;
    &lt;li&gt;Load the list of paths JavaScript files from the text files specified by the set name.&lt;/li&gt;
    &lt;li&gt;Read the content of each file and combine them into one big string that contains all the JavaScript.&lt;/li&gt;
    &lt;li&gt;Call &lt;a href="http://www.crockford.com/javascript/jsmin.html" target="_blank"&gt;Minifier&lt;/a&gt; to remove comments and white spaces from the combined JavaScript string.&lt;/li&gt;
    &lt;li&gt;Use gzip to compress the result into a smaller size.&lt;/li&gt;
    &lt;li&gt;Cache the result for later references so we don't have to do all the processing for each request.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also take few extra steps to make referencing this handler easier. I have created a sample website to demonstrate the whole process. You can download it from the link below:&lt;/p&gt;
&lt;div class="dsrc"&gt;&lt;a href="http://atashbahar.com/userfiles/file/ScriptCombiner.zip"&gt;Download Sample Website&lt;/a&gt; &lt;span class="sz"&gt;(64KB)&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Here is a screenshot of the website opened in solution explorer so you get a better idea of how file are organized in the sample website.&lt;/p&gt;
&lt;p class="img"&gt;&lt;img src="/userfiles/image/ScriptCombiner/solution.png" alt="Sample website opened inside solution explorer" /&gt;&lt;/p&gt;
&lt;h4&gt;The implementation&lt;/h4&gt;
&lt;p&gt;I have got most of the code for the handler from &lt;a href="http://weblogs.asp.net/omarzabir/" target="_blank"&gt;Omar Al Zabir&lt;/a&gt; article named &amp;quot;&lt;a href="http://www.codeproject.com/KB/aspnet/HttpCombine.aspx" target="_blank"&gt;HTTP Handler to Combine Multiple Files, Cache and Deliver Compressed Output for Faster Page Load&lt;/a&gt;&amp;quot; so most of the credit goes to him.&lt;/p&gt;
&lt;p&gt;HTTP Handler contains a few helper methods that their purpose is very clear. I try to describe each shortly.&lt;/p&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;CanGZip&lt;/span&gt; method checks if the browser can support gzip and returns true in that case.&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
private bool CanGZip(HttpRequest request)
{
    string acceptEncoding = request.Headers[&amp;quot;Accept-Encoding&amp;quot;];
    if (!string.IsNullOrEmpty(acceptEncoding) &amp;amp;&amp;amp;
         (acceptEncoding.Contains(&amp;quot;gzip&amp;quot;) || acceptEncoding.Contains(&amp;quot;deflate&amp;quot;)))
        return true;
    return false;
}
&lt;/pre&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;WriteBytes&lt;/span&gt; writes the combined and compresses bytes to the response output. We need to set different content type for response based on if we support gzip or not. The other important part of this method sets the caching policy for the response which tells the browser to cache the response for &lt;span class="mnsp"&gt;CACHE_DURATION&lt;/span&gt; amount of time.&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
private void WriteBytes(byte[] bytes, bool isCompressed)
{
    HttpResponse response = context.Response;

    response.AppendHeader(&amp;quot;Content-Length&amp;quot;, bytes.Length.ToString());
    response.ContentType = &amp;quot;application/x-javascript&amp;quot;;
    if (isCompressed)
        response.AppendHeader(&amp;quot;Content-Encoding&amp;quot;, &amp;quot;gzip&amp;quot;);
    else
        response.AppendHeader(&amp;quot;Content-Encoding&amp;quot;, &amp;quot;utf-8&amp;quot;);

    context.Response.Cache.SetCacheability(HttpCacheability.Public);
    context.Response.Cache.SetExpires(DateTime.Now.Add(CACHE_DURATION));
    context.Response.Cache.SetMaxAge(CACHE_DURATION);

    response.ContentEncoding = Encoding.Unicode;
    response.OutputStream.Write(bytes, 0, bytes.Length);
    response.Flush();
}
&lt;/pre&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;WriteFromCache&lt;/span&gt; checks if we have the combined script cached in memory, if so we write it to response and return true.&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
private bool WriteFromCache(string setName, string version, bool isCompressed)
{
    byte[] responseBytes = context.Cache[GetCacheKey(setName, version, isCompressed)] as byte[];

    if (responseBytes == null || responseBytes.Length == 0)
        return false;

    this.WriteBytes(responseBytes, isCompressed);
    return true;
}
&lt;/pre&gt;
&lt;p&gt;But most of the work is done inside ProcessRequest method. First we take a look at the method and I will try to explain important parts.&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
public void ProcessRequest(HttpContext context)
{
    this.context = context;
    HttpRequest request = context.Request;        

    // Read setName, version from query string
    string setName = request[&amp;quot;s&amp;quot;] ?? string.Empty;
    string version = request[&amp;quot;v&amp;quot;] ?? string.Empty;

    // Decide if browser supports compressed response
    bool isCompressed = this.CanGZip(context.Request);

    // If the set has already been cached, write the response directly from
    // cache. Otherwise generate the response and cache it
    if (!this.WriteFromCache(setName, version, isCompressed))
    {
        using (MemoryStream memoryStream = new MemoryStream(8092))
        {
            // Decide regular stream or gzip stream based on whether the response can be compressed or not
            using (Stream writer = isCompressed ? (Stream)(new ICSharpCode.SharpZipLib.GZip.GZipOutputStream(memoryStream)) : memoryStream)                
            {
                // Read the files into one big string
                StringBuilder allScripts = new StringBuilder();
                foreach (string fileName in GetScriptFileNames(setName))
                    allScripts.Append(File.ReadAllText(context.Server.MapPath(fileName)));

                // Minify the combined script files and remove comments and white spaces
                var minifier = new JavaScriptMinifier();
                string minified = minifier.Minify(allScripts.ToString());

                // Send minfied string to output stream
                byte[] bts = Encoding.UTF8.GetBytes(minified);
                writer.Write(bts, 0, bts.Length);
            }

            // Cache the combined response so that it can be directly written
            // in subsequent calls 
            byte[] responseBytes = memoryStream.ToArray();
            context.Cache.Insert(GetCacheKey(setName, version, isCompressed),
                responseBytes, null, System.Web.Caching.Cache.NoAbsoluteExpiration,
                CACHE_DURATION);

            // Generate the response
            this.WriteBytes(responseBytes, isCompressed);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;this.WriteFromCache(setName, version, isCompressed)&lt;/span&gt; returns true if we have the response cached in memory. It actually writes the data from cache to the response and returns true so we don&amp;rsquo;t need to take any extra steps.&lt;/p&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;MemoryStream&lt;/span&gt; is used to hold compressed bytes in the memory. In case that browser does not support gzip no compression is done over bytes.&lt;/p&gt;
&lt;p&gt;We use &lt;a href="http://www.icsharpcode.net/OpenSource/SharpZipLib" target="_blank"&gt;SharpZipLib&lt;/a&gt; to do the compression. This free library does gzip compression slightly better than .NET. You can easily use .NET compression by replacing line&amp;nbsp;20 with the following code:&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
using (Stream writer = isCompressed ?  (Stream)(new GZipStream(memoryStream, CompressionMode.Compress)) : memoryStream)
&lt;/pre&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;GetScriptFileNames&lt;/span&gt; is a static method that returns a string array of JavaScript file paths in the set name. We will use this method for another purpose that we discuss it later.&lt;/p&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;JavaScriptMinifier&lt;/span&gt; class holds the code for &lt;a href="http://www.crockford.com/javascript/jsmin.html" target="_blank"&gt;Douglas Crockford JavaScript Minfier&lt;/a&gt;. Minifer removes comments and white spaces from JavaScript and results in a smaller size. You can download the latest version from &lt;a href="http://www.crockford.com/javascript/jsmin.html" target="_blank"&gt;http://www.crockford.com/javascript/jsmin.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After we wrote minified and compressed scripts to MemoryStream we insert them into cache so we don&amp;rsquo;t need to take all these steps for each request. And finally we write the compressed bytes to the response.&lt;/p&gt;
&lt;h4&gt;Make it a little better&lt;/h4&gt;
&lt;p&gt;We can take one extra step to make the whole process a little better an easier to use. We can add a static method to our handler that generates JavaScript reference tag. We can make this even better by doing different actions when application is running in debug or release mode. In debug mode we usually don&amp;rsquo;t want to combine our JavaScript files to track error easier, so we output reference to original files and generate all JavaScript references as if we have included in our page manually.&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
public static string GetScriptTags(string setName, int version)
{
    string result = null;
#if (DEBUG)            
        foreach (string fileName in GetScriptFileNames(setName))
        {
            result += String.Format(&amp;quot;\n&amp;lt;script type=\&amp;quot;text/javascript\&amp;quot; src=\&amp;quot;{0}?v={1}\&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;quot;, VirtualPathUtility.ToAbsolute(fileName), version);
        }
#else
    result += String.Format(&amp;quot;&amp;lt;script type=\&amp;quot;text/javascript\&amp;quot; src=\&amp;quot;ScriptCombiner.axd?s={0}&amp;amp;v={1}\&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;quot;, setName, version);
#endif
    return result;
}
&lt;/pre&gt;
&lt;p&gt;&lt;span class="mnsp"&gt;GetScriptFileNames&lt;/span&gt; as described before returns an array of file names for a specified set.&lt;/p&gt;
&lt;pre name="code" class="csharp"&gt;
// private helper method that return an array of file names inside the text file stored in App_Data folder
private static string[] GetScriptFileNames(string setName)
{
    var scripts = new System.Collections.Generic.List&amp;lt;string&amp;gt;();
    string setPath = HttpContext.Current.Server.MapPath(String.Format(&amp;quot;~/App_Data/{0}.txt&amp;quot;, setName));
    using (var setDefinition = File.OpenText(setPath))
    {
        string fileName = null;
        while (setDefinition.Peek() &amp;gt;= 0)
        {
            fileName = setDefinition.ReadLine();
            if (!String.IsNullOrEmpty(fileName))
                scripts.Add(fileName);
        }
    }
    return scripts.ToArray();
}
&lt;/pre&gt;
&lt;pre name="code" class="html"&gt;
&amp;lt;%= ScriptCombiner.GetScriptTags(&amp;quot;Site_Scripts&amp;quot;, 1) %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;So whenever we want to reference a handler in an ASP.NET page we only need to add the following tag inside the head section of our page:&lt;/p&gt;
&lt;p&gt;There is a final step you need to take before making all this work. You need to add HTTP Handler to &lt;span class="mnsp"&gt;Web.config&lt;/span&gt; of your website. To do so make the following changes to your &lt;span class="mnsp"&gt;web.config&lt;/span&gt; file:&lt;/p&gt;
&lt;pre name="code" class="xml"&gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;system.web&amp;gt;
		&amp;lt;httpHandlers&amp;gt;
			&amp;lt;add verb=&amp;quot;POST,GET&amp;quot; path=&amp;quot;ScriptCombiner.axd&amp;quot; type=&amp;quot;ScriptCombiner, App_Code&amp;quot;/&amp;gt;
		&amp;lt;/httpHandlers&amp;gt;
	&amp;lt;/system.web&amp;gt;
	&amp;lt;!-- IIS 7.0 only --&amp;gt;
	&amp;lt;system.webServer&amp;gt;
		&amp;lt;handlers&amp;gt;
			&amp;lt;add name=&amp;quot;ScriptCombiner&amp;quot; verb=&amp;quot;POST,GET&amp;quot; path=&amp;quot;ScriptCombiner.axd&amp;quot; preCondition=&amp;quot;integratedMode&amp;quot; type=&amp;quot;ScriptCombiner, App_Code&amp;quot;/&amp;gt;
		&amp;lt;/handlers&amp;gt;
	&amp;lt;/system.webServer&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;If you search the Internet you will find many similar methods. I have tried to combine the best parts of them to make something more useful. I hope you have enjoyed it.&lt;/p&gt;</description>
      <link>http://atashbahar.com/post/Combine-minify-compress-JavaScript-files-to-load-ASPNET-pages-faster.aspx</link>
      <author>Atashbahar</author>
      <comments>http://atashbahar.com/post/Combine-minify-compress-JavaScript-files-to-load-ASPNET-pages-faster.aspx#comment</comments>
      <guid>http://atashbahar.com/post.aspx?id=fcd5d779-3620-4423-999e-4de9a83b8d05</guid>
      <pubDate>Sun, 18 Jan 2009 05:54:00 +0300</pubDate>
      <category>Atashbahar.com</category>
      <dc:publisher>Atashbahar</dc:publisher>
      <pingback:server>http://atashbahar.com/pingback.axd</pingback:server>
      <pingback:target>http://atashbahar.com/post.aspx?id=fcd5d779-3620-4423-999e-4de9a83b8d05</pingback:target>
      <slash:comments>54</slash:comments>
      <trackback:ping>http://atashbahar.com/trackback.axd?id=fcd5d779-3620-4423-999e-4de9a83b8d05</trackback:ping>
      <wfw:comment>http://atashbahar.com/post/Combine-minify-compress-JavaScript-files-to-load-ASPNET-pages-faster.aspx#comment</wfw:comment>
      <wfw:commentRss>http://atashbahar.com/syndication.axd?post=fcd5d779-3620-4423-999e-4de9a83b8d05</wfw:commentRss>
    </item>
  </channel>
</rss>