<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mohammed Al-Atari</title>
	<atom:link href="http://al-atari.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://al-atari.net</link>
	<description>The Gate to Microsoft .Net Technology</description>
	<lastBuildDate>Wed, 01 Sep 2010 21:15:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Web Site Project Life Cycle</title>
		<link>http://al-atari.net/?p=434</link>
		<comments>http://al-atari.net/?p=434#comments</comments>
		<pubDate>Mon, 30 Aug 2010 04:07:15 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=434</guid>
		<description><![CDATA[Download : Web Project Process Diagram URL: http://www.leonamarant.com/ Working on different web teams within various organizations throughout the years, a common issue that I’ve often encountered was the lack of process when it came to designing and developing web sites. Virtually everywhere that I have worked there has not been a standard, documented method or [...]]]></description>
			<content:encoded><![CDATA[<p>Download : <a href="http://al-atari.net/wp-content/uploads/2010/08/WebProcessDiagram.pdf">Web Project Process Diagram</a><br />
URL: <a href="http://www.leonamarant.com/">http://www.leonamarant.com/</a></p>
<p>Working on different web teams within various organizations throughout the years, a common issue that I’ve often encountered was the lack of process when it came to designing and developing web sites. Virtually everywhere that I have worked there has not been a standard, documented method or strategy that the “web team” could use to guide a project from start to completion. Thankfully, in one of my most recent roles, my team and I were tasked with doing just that, creating a process that made sense and that we could all use collectively to get our work done.</p>
<p>We called our process “The 4 D’s”</p>
<ol>
<li>Definition</li>
<li>Design</li>
<li>Development</li>
<li>Deployment</li>
<li>Support (OK…not a D…but you get the picture)</li>
</ol>
<p>The documents attached to this post are what we ultimately ended up with. A lot of what we created is based on common methods and best practices in project management and software development….so don’t expect any of this to be ground breaking stuff. We found that having a process like this in place kept projects well organized, kept all team members fully informed of client expectations, and minimized common issues like scope-creep, missed deadlines, blown budgets, and dissatisfied clients. Every member of the web team as well as our external clients were involved in creating this process, so at the end of the day everyone was comfortable with working within it.</p>
<p>Note that it is crucial to work very closely with your clients in the beginning stages of the development process (Definition/Design). The client should expect to deliver and sign off on clear business requirements (a member of the web team would work with the client to create the necessary documents) and also be readily available to answer any questions and sign off on milestones throughout the process. As development of the web site/application progresses, the client should be given periodic status updates. The bottom line is to keep an open line of communication between the web team and the client. In doing so, the chances of delivering a successful product will be greatly improved.</p>
<p>This process is intended as a <strong>general guideline</strong> in developing web sites and applications and is not meant to be followed rigidly. The scope and complexity of every project is different and as is the case, the degree of process/documentation required should vary depending on the project. Also, some clients require more visibility into projects than others so the level of detail in documentation  may vary as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=434</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Weather.com Asp.net User Control (in VB)</title>
		<link>http://al-atari.net/?p=431</link>
		<comments>http://al-atari.net/?p=431#comments</comments>
		<pubDate>Mon, 30 Aug 2010 04:01:03 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ascx]]></category>
		<category><![CDATA[aspx.net]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Weather]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=431</guid>
		<description><![CDATA[  Download From CodePlex Introduction After looking around for a simple, customizable ASP.NET control that reads weather and forecast data from weather.com’s xml feed…and finding nothing, I decided to create one myself. This ascx control displays current weather and weather forecast data on your ASP.NET website straight from an xml feed on weather.com. This is [...]]]></description>
			<content:encoded><![CDATA[<p> </p>
<p><a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=aspnetweather&amp;ReleaseId=13422" target="_blank">Download From CodePlex</a></p>
<p><a title="Weather Control Screenshot" href="http://www.theseabreezeinn.com/" target="_blank"></a></p>
<p><strong>Introduction</strong></p>
<p>After looking around for a simple, customizable ASP.NET control that reads weather and forecast data from weather.com’s xml feed…and finding nothing, I decided to create one myself.</p>
<p>This ascx control displays current weather and weather forecast data on your ASP.NET website straight from an xml feed on weather.com. This is meant to be very easy to implement and extremely easy to customize. All you need to do is add a few files to your site, copy and paste a couple lines of code, switch a few variables, and you’re off and running.</p>
<p>Oh…and this control also caches the xml data from weather.com so it doesn’t ping the xml data with every user request. I have it set to clear and refresh the cached data every 15 minutes, but you can set it to any time frame you want…or even turn off caching if you so chose.</p>
<p>Without further adieu, let’s get started.</p>
<p><strong></p>
<p>Background</strong></p>
<p><strong>VERY IMPORTANT: </strong>You will first need to register on weather.com for their xml weather service. They provide this all for FREE. This will get you a License Key, PartnerID, and LocationID which are all <strong>required</strong> to use this control. So….go to weather.com now and get ‘em.</p>
<p><a href="https://registration.weather.com/ursa/xmloap/step1?" target="_blank">https://registration.weather.com/ursa/xmloap/step1?</a>?</p>
<p>Got ‘em? You’re 90% there…Keep reading.</p>
<p><strong></p>
<p>Using the code</strong></p>
<p>OK…so you have your weather.com account information. Now, download the zip file at the top of this web page and unzip it. Next, do the following:</p>
<p><strong>Step1: </strong>copy the <em>WeatherControl.ascx</em> file into your web project</p>
<p><strong>Step2</strong>: copy and paste the entire <em>ccicons </em>folder into your web project</p>
<p><strong>Step3: </strong>copy the <em>css</em> folder into your web project (contains stylesheet.css)</p>
<p><strong>Step4: </strong>in any aspx file you want to use this weather control, add the following code (see the default.aspx file for example) :</p>
<pre>&lt;%@ Register TagPrefix="My" TagName="Weather" src="WeatherControl.ascx" mce_src="WeatherControl.ascx" %&gt;</pre>
<p>And add the following code where you want the generated weather table to show up on your web page. <strong>YOU NEED TO ENTER YOUR OWN LicenseKey, PartnerID, and LocationID values that you got from weather.com!!!:</strong></p>
<p>NOTE: For LocationID visit: <a href="http://aspnetresources.com/tools/locid.aspx" target="_blank">http://aspnetresources.com/tools/locid.aspx</a></p>
<pre>&lt;My:Weather</pre>
<pre>        ID="Weather" runat="server"</pre>
<pre>        LicenseKey = ""</pre>
<pre>        PartnerID = ""</pre>
<pre>        LocationID = ""</pre>
<pre>        EnableWeatherCaching = "False"</pre>
<pre>        TimeToRefreshCache = "15"</pre>
<pre>        NumForecastDays = "3"</pre>
<pre>        showDateInForecast = "True"</pre>
<pre>        showWind = "True"</pre>
<pre>        forecastIconSize = "sm"</pre>
<pre>        showLastUpdateLabel = "True"</pre>
<pre>        showCelsius = "False"</pre>
<pre>        showKPH = "False"</pre>
<pre>        locationClass = "ccLoc"</pre>
<pre>        curTempClass = "temp"</pre>
<pre>        curDescClass = "cc"</pre>
<pre>        curWindClass = "curWind"</pre>
<pre>        fcastDateClass = "fcastDate"</pre>
<pre>        fCastTableClass = "fcastTable"</pre>
<pre>        fcastWeekdayClass = "fcastWeekDay"</pre>
<pre>        lastUpdateClass = "cc"</pre>
<pre>/&gt;</pre>
<p> The definable properties listed above are all set to the control’s default values. I listed all of them so you can see which properties you can set in the control. They are pretty self-explanatory but if you want to see the definition of each property, just open the ascx file. You’ll see a comment next to each public property that describes it. If the default values for the control are OK for your application, then simply use the following code and just set your license variables and location id:</p>
<pre>&lt;My:Weather</pre>
<pre>        ID="Weather" runat="server"</pre>
<pre>        LicenseKey = ""</pre>
<pre>        PartnerID = ""</pre>
<pre>        LocationID = ""</pre>
<pre>/&gt;</pre>
<p><strong> </strong></p>
<p><strong>That’s it!</strong></p>
<p>You can go into the ascx file and, at the bottom, change the format of the table to whatever layout you want.</p>
<p>If you want to customize it further…go nuts. You can pull even more data out of the weather.com xml file as well. Just use the two “Node Reading” functions at the top. See the code for examples on how to navigate through the xml tags…pretty self explanatory.Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=431</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best Practices for Speeding Up Your Web Site</title>
		<link>http://al-atari.net/?p=428</link>
		<comments>http://al-atari.net/?p=428#comments</comments>
		<pubDate>Sat, 28 Aug 2010 21:12:57 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=428</guid>
		<description><![CDATA[The Exceptional Performance team has identified a number of best practices for making web pages fast. The list includes 35 best practices divided into 7 categories Minimize HTTP Requests 80% of the end-user response time is spent on the front-end. Most of this time is tied up in downloading all the components in the page: [...]]]></description>
			<content:encoded><![CDATA[<p>The Exceptional Performance team has identified a number of best practices for making web pages fast. The list includes 35 best practices divided into 7 categories</p>
<p><strong>Minimize HTTP Requests</strong></p>
<p>80% of the end-user response time is spent on the front-end. Most of this time is tied up in downloading all the components in the page: images, stylesheets, scripts, Flash, etc. Reducing the number of components in turn reduces the number of HTTP requests required to render the page. This is the key to faster pages.</p>
<p>One way to reduce the number of components in the page is to simplify the page&amp;apos;s design. But is there a way to build pages with richer content while also achieving fast response times? Here are some techniques for reducing the number of HTTP requests, while still supporting rich page designs.</p>
<p><strong>Combined files</strong> are a way to reduce the number of HTTP requests by combining all scripts into a single script, and similarly combining all CSS into a single stylesheet. Combining files is more challenging when the scripts and stylesheets vary from page to page, but making this part of your release process improves response times.</p>
<p> <a href="http://alistapart.com/articles/sprites"><strong>CSS Sprites</strong></a> are the preferred method for reducing the number of image requests. Combine your background images into a single image and use the CSS <code>background-image</code> and <code>background-position</code> properties to display the desired image segment.</p>
<p><a href="http://www.w3.org/TR/html401/struct/objects.html#h-13.6"><strong>Image maps</strong></a> combine multiple images into a single image. The overall size is about the same, but reducing the number of HTTP requests speeds up the page. Image maps only work if the images are contiguous in the page, such as a navigation bar. Defining the coordinates of image maps can be tedious and error prone. Using image maps for navigation is not accessible too, so it&amp;apos;s not recommended.</p>
<p><strong>Inline images</strong> use the <a href="http://tools.ietf.org/html/rfc2397"><code>data:</code> URL scheme</a> to embed the image data in the actual page. This can increase the size of your HTML document. Combining inline images into your (cached) stylesheets is a way to reduce HTTP requests and avoid increasing the size of your pages. Inline images are not yet supported across all major browsers.</p>
<p>Reducing the number of HTTP requests in your page is the place to start. This is the most important guideline for improving performance for first time visitors. As described in Tenni Theurer&amp;apos;s blog post <a href="http://yuiblog.com/blog/2007/01/04/performance-research-part-2/">Browser Cache Usage &#8211; Exposed!</a>, 40-60% of daily visitors to your site come in with an empty cache. Making your page fast for these first time visitors is key to a better user experience.</p>
<p><strong>Use a Content Delivery Network</strong></p>
<p>The user&amp;apos;s proximity to your web server has an impact on response times. Deploying your content across multiple, geographically dispersed servers will make your pages load faster from the user&amp;apos;s perspective. But where should you start?</p>
<p>As a first step to implementing geographically dispersed content, don&amp;apos;t attempt to redesign your web application to work in a distributed architecture. Depending on the application, changing the architecture could include daunting tasks such as synchronizing session state and replicating database transactions across server locations. Attempts to reduce the distance between users and your content could be delayed by, or never pass, this application architecture step.</p>
<p>Remember that 80-90% of the end-user response time is spent downloading all the components in the page: images, stylesheets, scripts, Flash, etc. This is the <em>Performance Golden Rule</em>. Rather than starting with the difficult task of redesigning your application architecture, it&amp;apos;s better to first disperse your static content. This not only achieves a bigger reduction in response times, but it&amp;apos;s easier thanks to content delivery networks.</p>
<p>A content delivery network (CDN) is a collection of web servers distributed across multiple locations to deliver content more efficiently to users. The server selected for delivering content to a specific user is typically based on a measure of network proximity. For example, the server with the fewest network hops or the server with the quickest response time is chosen.</p>
<p>Some large Internet companies own their own CDN, but it&amp;apos;s cost-effective to use a CDN service provider, such as <a href="http://www.akamai.com/">Akamai Technologies</a>, <a href="http://www.edgecast.com/">EdgeCast</a>, or <a href="http://www.level3.com/index.cfm?pageID=36">level3</a>. For start-up companies and private web sites, the cost of a CDN service can be prohibitive, but as your target audience grows larger and becomes more global, a CDN is necessary to achieve fast response times. At Yahoo!, properties that moved static content off their application web servers to a CDN (both 3rd party as mentioned above as well as Yahoo’s own <a href="https://cwiki.apache.org/TS/traffic-server.html">CDN</a>) improved end-user response times by 20% or more. Switching to a CDN is a relatively easy code change that will dramatically improve the speed of your web site.</p>
<p><strong>Add an Expires or a Cache-Control Header</strong></p>
<p>There are two aspects to this rule: </p>
<ul>
<li>For static components: implement &#8220;Never expire&#8221; policy by setting far future <code>Expires</code> header</li>
<li>For dynamic components: use an appropriate <code>Cache-Control</code> header to help the browser with conditional requests</li>
</ul>
<p> Web page designs are getting richer and richer, which means more scripts, stylesheets, images, and Flash in the page. A first-time visitor to your page may have to make several HTTP requests, but by using the Expires header you make those components cacheable. This avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often used with images, but they should be used on <em>all</em> components including scripts, stylesheets, and Flash components.</p>
<p>Browsers (and proxies) use a cache to reduce the number and size of HTTP requests, making web pages load faster. A web server uses the Expires header in the HTTP response to tell the client how long a component can be cached. This is a far future Expires header, telling the browser that this response won&amp;apos;t be stale until April 15, 2010.</p>
<p>Expires: Thu, 15 Apr 2010 20:00:00 GMT</p>
<p>If your server is Apache, use the ExpiresDefault directive to set an expiration date relative to the current date. This example of the ExpiresDefault directive sets the Expires date 10 years out from the time of the request.</p>
<p>ExpiresDefault &#8220;access plus 10 years&#8221;</p>
<p>Keep in mind, if you use a far future Expires header you have to change the component&amp;apos;s filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component&amp;apos;s filename, for example, yahoo_2.0.6.js.</p>
<p>Using a far future Expires header affects page views only after a user has already visited your site. It has no effect on the number of HTTP requests when a user visits your site for the first time and the browser&amp;apos;s cache is empty. Therefore the impact of this performance improvement depends on how often users hit your pages with a primed cache. (A &#8220;primed cache&#8221; already contains all of the components in the page.) We <a href="http://yuiblog.com/blog/2007/01/04/performance-research-part-2/">measured this at Yahoo!</a> and found the number of page views with a primed cache is 75-85%. By using a far future Expires header, you increase the number of components that are cached by the browser and re-used on subsequent page views without sending a single byte over the user&amp;apos;s Internet connection.</p>
<p><strong>Gzip Components</strong></p>
<p>The time it takes to transfer an HTTP request and response across the network can be significantly reduced by decisions made by front-end engineers. It&amp;apos;s true that the end-user&amp;apos;s bandwidth speed, Internet service provider, proximity to peering exchange points, etc. are beyond the control of the development team. But there are other variables that affect response times. Compression reduces response times by reducing the size of the HTTP response.</p>
<p>Starting with HTTP/1.1, web clients indicate support for compression with the Accept-Encoding header in the HTTP request.</p>
<p>Accept-Encoding: gzip, deflate</p>
<p>If the web server sees this header in the request, it may compress the response using one of the methods listed by the client. The web server notifies the web client of this via the Content-Encoding header in the response.</p>
<p>Content-Encoding: gzip</p>
<p>Gzip is the most popular and effective compression method at this time. It was developed by the GNU project and standardized by <a href="http://www.ietf.org/rfc/rfc1952.txt">RFC 1952</a>. The only other compression format you&amp;apos;re likely to see is deflate, but it&amp;apos;s less effective and less popular.</p>
<p>Gzipping generally reduces the response size by about 70%. Approximately 90% of today&amp;apos;s Internet traffic travels through browsers that claim to support gzip. If you use Apache, the module configuring gzip depends on your version: Apache 1.3 uses <a href="http://sourceforge.net/projects/mod-gzip/">mod_gzip</a> while Apache 2.x uses <a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html">mod_deflate</a>.</p>
<p>There are known issues with browsers and proxies that may cause a mismatch in what the browser expects and what it receives with regard to compressed content. Fortunately, these edge cases are dwindling as the use of older browsers drops off. The Apache modules help out by adding appropriate Vary response headers automatically.</p>
<p>Servers choose what to gzip based on file type, but are typically too limited in what they decide to compress. Most web sites gzip their HTML documents. It&amp;apos;s also worthwhile to gzip your scripts and stylesheets, but many web sites miss this opportunity. In fact, it&amp;apos;s worthwhile to compress any text response including XML and JSON. Image and PDF files should not be gzipped because they are already compressed. Trying to gzip them not only wastes CPU but can potentially increase file sizes.</p>
<p>Gzipping as many file types as possible is an easy way to reduce page weight and accelerate the user experience.</p>
<p><strong>Put Stylesheets at the Top</strong></p>
<p>While researching performance at Yahoo!, we discovered that moving stylesheets to the document HEAD makes pages <em>appear</em> to be loading faster. This is because putting stylesheets in the HEAD allows the page to render progressively.</p>
<p>Front-end engineers that care about performance want a page to load progressively; that is, we want the browser to display whatever content it has as soon as possible. This is especially important for pages with a lot of content and for users on slower Internet connections. The importance of giving users visual feedback, such as progress indicators, has been well researched and <a href="http://www.useit.com/papers/responsetime.html">documented</a>. In our case the HTML page is the progress indicator! When the browser loads the page progressively the header, the navigation bar, the logo at the top, etc. all serve as visual feedback for the user who is waiting for the page. This improves the overall user experience.</p>
<p>The problem with putting stylesheets near the bottom of the document is that it prohibits progressive rendering in many browsers, including Internet Explorer. These browsers block rendering to avoid having to redraw elements of the page if their styles change. The user is stuck viewing a blank white page.</p>
<p>The <a href="http://www.w3.org/TR/html4/struct/links.html#h-12.3">HTML specification</a> clearly states that stylesheets are to be included in the HEAD of the page: &#8220;Unlike A, [LINK] may only appear in the HEAD section of a document, although it may appear any number of times.&#8221; Neither of the alternatives, the blank white screen or flash of unstyled content, are worth the risk. The optimal solution is to follow the HTML specification and load your stylesheets in the document HEAD.</p>
<p><strong>Put Scripts at the Bottom</strong></p>
<p>The problem caused by scripts is that they block parallel downloads. The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4">HTTP/1.1 specification</a> suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won&amp;apos;t start any other downloads, even on different hostnames.</p>
<p>In some situations it&amp;apos;s not easy to move scripts to the bottom. If, for example, the script uses <code>document.write</code> to insert part of the page&amp;apos;s content, it can&amp;apos;t be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.</p>
<p>An alternative suggestion that often comes up is to use deferred scripts. The <code>DEFER</code> attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn&amp;apos;t support the <code>DEFER</code> attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.</p>
<p><strong>Avoid CSS Expressions</strong></p>
<p>CSS expressions are a powerful (and dangerous) way to set CSS properties dynamically. They were supported in Internet Explorer starting with version 5, but were <a href="http://msdn.microsoft.com/en-us/library/ms537634%28VS.85%29.aspx">deprecated starting with IE8</a>. As an example, the background color could be set to alternate every hour using CSS expressions:</p>
<p>background-color: expression( (new Date()).getHours()%2 ? &#8220;#B8D4FF&#8221; : &#8220;#F08A00&#8243; );</p>
<p>As shown here, the <code>expression</code> method accepts a JavaScript expression. The CSS property is set to the result of evaluating the JavaScript expression. The <code>expression</code> method is ignored by other browsers, so it is useful for setting properties in Internet Explorer needed to create a consistent experience across browsers.</p>
<p>The problem with expressions is that they are evaluated more frequently than most people expect. Not only are they evaluated when the page is rendered and resized, but also when the page is scrolled and even when the user moves the mouse over the page. Adding a counter to the CSS expression allows us to keep track of when and how often a CSS expression is evaluated. Moving the mouse around the page can easily generate more than 10,000 evaluations.</p>
<p>One way to reduce the number of times your CSS expression is evaluated is to use one-time expressions, where the first time the expression is evaluated it sets the style property to an explicit value, which replaces the CSS expression. If the style property must be set dynamically throughout the life of the page, using event handlers instead of CSS expressions is an alternative approach. If you must use CSS expressions, remember that they may be evaluated thousands of times and could affect the performance of your page.</p>
<p><strong>Make JavaScript and CSS External</strong></p>
<p>Many of these performance rules deal with how external components are managed. However, before these considerations arise you should ask a more basic question: Should JavaScript and CSS be contained in external files, or inlined in the page itself?</p>
<p>Using external files in the real world generally produces faster pages because the JavaScript and CSS files are cached by the browser. JavaScript and CSS that are inlined in HTML documents get downloaded every time the HTML document is requested. This reduces the number of HTTP requests that are needed, but increases the size of the HTML document. On the other hand, if the JavaScript and CSS are in external files cached by the browser, the size of the HTML document is reduced without increasing the number of HTTP requests.</p>
<p>The key factor, then, is the frequency with which external JavaScript and CSS components are cached relative to the number of HTML documents requested. This factor, although difficult to quantify, can be gauged using various metrics. If users on your site have multiple page views per session and many of your pages re-use the same scripts and stylesheets, there is a greater potential benefit from cached external files.</p>
<p>Many web sites fall in the middle of these metrics. For these sites, the best solution generally is to deploy the JavaScript and CSS as external files. The only exception where inlining is preferable is with home pages, such as <a href="http://www.yahoo.com/">Yahoo!&amp;apos;s front page</a> and <a href="http://my.yahoo.com/">My Yahoo!</a>. Home pages that have few (perhaps only one) page view per session may find that inlining JavaScript and CSS results in faster end-user response times.</p>
<p>For front pages that are typically the first of many page views, there are techniques that leverage the reduction of HTTP requests that inlining provides, as well as the caching benefits achieved through using external files. One such technique is to inline JavaScript and CSS in the front page, but dynamically download the external files after the page has finished loading. Subsequent pages would reference the external files that should already be in the browser&amp;apos;s cache.</p>
<p><strong></strong> </p>
<p><strong>Reduce DNS Lookups</strong></p>
<p>The Domain Name System (DNS) maps hostnames to IP addresses, just as phonebooks map people&amp;apos;s names to their phone numbers. When you type www.yahoo.com into your browser, a DNS resolver contacted by the browser returns that server&amp;apos;s IP address. DNS has a cost. It typically takes 20-120 milliseconds for DNS to lookup the IP address for a given hostname. The browser can&amp;apos;t download anything from this hostname until the DNS lookup is completed.</p>
<p>DNS lookups are cached for better performance. This caching can occur on a special caching server, maintained by the user&amp;apos;s ISP or local area network, but there is also caching that occurs on the individual user&amp;apos;s computer. The DNS information remains in the operating system&amp;apos;s DNS cache (the &#8220;DNS Client service&#8221; on Microsoft Windows). Most browsers have their own caches, separate from the operating system&amp;apos;s cache. As long as the browser keeps a DNS record in its own cache, it doesn&amp;apos;t bother the operating system with a request for the record.</p>
<p>Internet Explorer caches DNS lookups for 30 minutes by default, as specified by the <code>DnsCacheTimeout</code> registry setting. Firefox caches DNS lookups for 1 minute, controlled by the <code>network.dnsCacheExpiration</code> configuration setting. (Fasterfox changes this to 1 hour.)</p>
<p>When the client&amp;apos;s DNS cache is empty (for both the browser and the operating system), the number of DNS lookups is equal to the number of unique hostnames in the web page. This includes the hostnames used in the page&amp;apos;s URL, images, script files, stylesheets, Flash objects, etc. Reducing the number of unique hostnames reduces the number of DNS lookups.</p>
<p>Reducing the number of unique hostnames has the potential to reduce the amount of parallel downloading that takes place in the page. Avoiding DNS lookups cuts response times, but reducing parallel downloads may increase response times. My guideline is to split these components across at least two but no more than four hostnames. This results in a good compromise between reducing DNS lookups and allowing a high degree of parallel downloads.</p>
<p><strong></strong> </p>
<p><strong>Minify JavaScript and CSS</strong></p>
<p>Minification is the practice of removing unnecessary characters from code to reduce its size thereby improving load times. When code is minified all comments are removed, as well as unneeded white space characters (space, newline, and tab). In the case of JavaScript, this improves response time performance because the size of the downloaded file is reduced. Two popular tools for minifying JavaScript code are <a href="http://crockford.com/javascript/jsmin">JSMin</a> and <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>. The YUI compressor can also minify CSS.</p>
<p>Obfuscation is an alternative optimization that can be applied to source code. It&amp;apos;s more complex than minification and thus more likely to generate bugs as a result of the obfuscation step itself. In a survey of ten top U.S. web sites, minification achieved a 21% size reduction versus 25% for obfuscation. Although obfuscation has a higher size reduction, minifying JavaScript is less risky.</p>
<p>In addition to minifying external scripts and styles, inlined <code>&lt;script&gt;</code> and <code>&lt;style&gt;</code> blocks can and should also be minified. Even if you gzip your scripts and styles, minifying them will still reduce the size by 5% or more. As the use and size of JavaScript and CSS increases, so will the savings gained by minifying your code.</p>
<p><strong></strong> </p>
<p><strong>Avoid Redirects</strong></p>
<p>Redirects are accomplished using the 301 and 302 status codes. Here&amp;apos;s an example of the HTTP headers in a 301 response:</p>
<p>HTTP/1.1 301 Moved Permanently Location: http://example.com/newuri Content-Type: text/html</p>
<p>The browser automatically takes the user to the URL specified in the <code>Location</code> field. All the information necessary for a redirect is in the headers. The body of the response is typically empty. Despite their names, neither a 301 nor a 302 response is cached in practice unless additional headers, such as <code>Expires</code> or <code>Cache-Control</code>, indicate it should be. The meta refresh tag and JavaScript are other ways to direct users to a different URL, but if you must do a redirect, the preferred technique is to use the standard 3xx HTTP status codes, primarily to ensure the back button works correctly.</p>
<p>The main thing to remember is that redirects slow down the user experience. Inserting a redirect between the user and the HTML document delays everything in the page since nothing in the page can be rendered and no components can start being downloaded until the HTML document has arrived.</p>
<p>One of the most wasteful redirects happens frequently and web developers are generally not aware of it. It occurs when a trailing slash (/) is missing from a URL that should otherwise have one. For example, going to <a href="http://astrology.yahoo.com/astrology">http://astrology.yahoo.com/astrology</a> results in a 301 response containing a redirect to <a href="http://astrology.yahoo.com/astrology/">http://astrology.yahoo.com/astrology/</a> (notice the added trailing slash). This is fixed in Apache by using <code>Alias</code> or <code>mod_rewrite</code>, or the <code>DirectorySlash</code> directive if you&amp;apos;re using Apache handlers.</p>
<p>Connecting an old web site to a new one is another common use for redirects. Others include connecting different parts of a website and directing the user based on certain conditions (type of browser, type of user account, etc.). Using a redirect to connect two web sites is simple and requires little additional coding. Although using redirects in these situations reduces the complexity for developers, it degrades the user experience. Alternatives for this use of redirects include using <code>Alias</code> and <code>mod_rewrite</code> if the two code paths are hosted on the same server. If a domain name change is the cause of using redirects, an alternative is to create a CNAME (a DNS record that creates an alias pointing from one domain name to another) in combination with <code>Alias</code> or <code>mod_rewrite</code>.</p>
<p><strong></strong> </p>
<p><strong>Remove Duplicate Scripts</strong></p>
<p>It hurts performance to include the same JavaScript file twice in one page. This isn&amp;apos;t as unusual as you might think. A review of the ten top U.S. web sites shows that two of them contain a duplicated script. Two main factors increase the odds of a script being duplicated in a single web page: team size and number of scripts. When it does happen, duplicate scripts hurt performance by creating unnecessary HTTP requests and wasted JavaScript execution.</p>
<p>Unnecessary HTTP requests happen in Internet Explorer, but not in Firefox. In Internet Explorer, if an external script is included twice and is not cacheable, it generates two HTTP requests during page loading. Even if the script is cacheable, extra HTTP requests occur when the user reloads the page.</p>
<p>In addition to generating wasteful HTTP requests, time is wasted evaluating the script multiple times. This redundant JavaScript execution happens in both Firefox and Internet Explorer, regardless of whether the script is cacheable.</p>
<p>One way to avoid accidentally including the same script twice is to implement a script management module in your templating system. The typical way to include a script is to use the SCRIPT tag in your HTML page.</p>
<p>&lt;script src=&#8221;menu_1.0.17.js&#8221;&gt;&lt;/script&gt;</p>
<p>An alternative in PHP would be to create a function called <code>insertScript</code>.</p>
<p>&lt;?php insertScript(&#8220;menu.js&#8221;) ?&gt;</p>
<p>In addition to preventing the same script from being inserted multiple times, this function could handle other issues with scripts, such as dependency checking and adding version numbers to script filenames to support far future Expires headers.</p>
<p><strong>Configure ETags</strong></p>
<p>Entity tags (ETags) are a mechanism that web servers and browsers use to determine whether the component in the browser&amp;apos;s cache matches the one on the origin server. (An &#8220;entity&#8221; is another word a &#8220;component&#8221;: images, scripts, stylesheets, etc.) ETags were added to provide a mechanism for validating entities that is more flexible than the last-modified date. An ETag is a string that uniquely identifies a specific version of a component. The only format constraints are that the string be quoted. The origin server specifies the component&amp;apos;s ETag using the <code>ETag</code> response header.</p>
<p>HTTP/1.1 200 OK Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: &#8220;10c24bc-4ab-457e1c1f&#8221; Content-Length: 12195</p>
<p>Later, if the browser has to validate a component, it uses the <code>If-None-Match</code> header to pass the ETag back to the origin server. If the ETags match, a 304 status code is returned reducing the response by 12195 bytes for this example.</p>
<p>GET /i/yahoo.gif HTTP/1.1 Host: us.yimg.com If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT If-None-Match: &#8220;10c24bc-4ab-457e1c1f&#8221; HTTP/1.1 304 Not Modified</p>
<p>The problem with ETags is that they typically are constructed using attributes that make them unique to a specific server hosting a site. ETags won&amp;apos;t match when a browser gets the original component from one server and later tries to validate that component on a different server, a situation that is all too common on Web sites that use a cluster of servers to handle requests. By default, both Apache and IIS embed data in the ETag that dramatically reduces the odds of the validity test succeeding on web sites with multiple servers.</p>
<p>The ETag format for Apache 1.3 and 2.x is <code>inode-size-timestamp</code>. Although a given file may reside in the same directory across multiple servers, and have the same file size, permissions, timestamp, etc., its inode is different from one server to the next.</p>
<p>IIS 5.0 and 6.0 have a similar issue with ETags. The format for ETags on IIS is <code>Filetimestamp:ChangeNumber</code>. A <code>ChangeNumber</code> is a counter used to track configuration changes to IIS. It&amp;apos;s unlikely that the <code>ChangeNumber</code> is the same across all IIS servers behind a web site.</p>
<p>The end result is ETags generated by Apache and IIS for the exact same component won&amp;apos;t match from one server to another. If the ETags don&amp;apos;t match, the user doesn&amp;apos;t receive the small, fast 304 response that ETags were designed for; instead, they&amp;apos;ll get a normal 200 response along with all the data for the component. If you host your web site on just one server, this isn&amp;apos;t a problem. But if you have multiple servers hosting your web site, and you&amp;apos;re using Apache or IIS with the default ETag configuration, your users are getting slower pages, your servers have a higher load, you&amp;apos;re consuming greater bandwidth, and proxies aren&amp;apos;t caching your content efficiently. Even if your components have a far future <code>Expires</code> header, a conditional GET request is still made whenever the user hits Reload or Refresh.</p>
<p>If you&amp;apos;re not taking advantage of the flexible validation model that ETags provide, it&amp;apos;s better to just remove the ETag altogether. The <code>Last-Modified</code> header validates based on the component&amp;apos;s timestamp. And removing the ETag reduces the size of the HTTP headers in both the response and subsequent requests. This <a href="http://support.microsoft.com/?id=922733">Microsoft Support article</a> describes how to remove ETags. In Apache, this is done by simply adding the following line to your Apache configuration file:</p>
<p>FileETag none</p>
<p><strong></strong> </p>
<p><strong>Make Ajax Cacheable</strong></p>
<p>One of the cited benefits of Ajax is that it provides instantaneous feedback to the user because it requests information asynchronously from the backend web server. However, using Ajax is no guarantee that the user won&amp;apos;t be twiddling his thumbs waiting for those asynchronous JavaScript and XML responses to return. In many applications, whether or not the user is kept waiting depends on how Ajax is used. For example, in a web-based email client the user will be kept waiting for the results of an Ajax request to find all the email messages that match their search criteria. It&amp;apos;s important to remember that &#8220;asynchronous&#8221; does not imply &#8220;instantaneous&#8221;.</p>
<p>To improve performance, it&amp;apos;s important to optimize these Ajax responses. The most important way to improve the performance of Ajax is to make the responses cacheable, as discussed in <a href="http://developer.yahoo.com/performance/rules.html#expires">Add an Expires or a Cache-Control Header</a>. Some of the other rules also apply to Ajax:</p>
<ul>
<li><a href="http://developer.yahoo.com/performance/rules.html#gzip">Gzip Components</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#dns_lookups">Reduce DNS Lookups</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#minify">Minify JavaScript</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#redirects">Avoid Redirects</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#etags">Configure ETags</a></li>
</ul>
<p>Let&amp;apos;s look at an example. A Web 2.0 email client might use Ajax to download the user&amp;apos;s address book for autocompletion. If the user hasn&amp;apos;t modified her address book since the last time she used the email web app, the previous address book response could be read from cache if that Ajax response was made cacheable with a future Expires or Cache-Control header. The browser must be informed when to use a previously cached address book response versus requesting a new one. This could be done by adding a timestamp to the address book Ajax URL indicating the last time the user modified her address book, for example, <code>&amp;t=1190241612</code>. If the address book hasn&amp;apos;t been modified since the last download, the timestamp will be the same and the address book will be read from the browser&amp;apos;s cache eliminating an extra HTTP roundtrip. If the user has modified her address book, the timestamp ensures the new URL doesn&amp;apos;t match the cached response, and the browser will request the updated address book entries.</p>
<p>Even though your Ajax responses are created dynamically, and might only be applicable to a single user, they can still be cached. Doing so will make your Web 2.0 apps faster.</p>
<p><strong>Flush the Buffer Early</strong></p>
<p>When users request a page, it can take anywhere from 200 to 500ms for the backend server to stitch together the HTML page. During this time, the browser is idle as it waits for the data to arrive. In PHP you have the function <a href="http://php.net/flush">flush()</a>. It allows you to send your partially ready HTML response to the browser so that the browser can start fetching components while your backend is busy with the rest of the HTML page. The benefit is mainly seen on busy backends or light frontends.</p>
<p>A good place to consider flushing is right after the HEAD because the HTML for the head is usually easier to produce and it allows you to include any CSS and JavaScript files for the browser to start fetching in parallel while the backend is still processing.</p>
<p>Example:</p>
<p>&#8230; &lt;!&#8211; css, js &#8211;&gt; &lt;/head&gt; <strong>&lt;?php flush(); ?&gt;</strong> &lt;body&gt; &#8230; &lt;!&#8211; content &#8211;&gt;</p>
<p><a href="http://search.yahoo.com/">Yahoo! search</a> pioneered research and real user testing to prove the benefits of using this technique.</p>
<p><strong></strong> </p>
<p><strong>Use GET for AJAX Requests</strong></p>
<p>The <a href="http://mail.yahoo.com/">Yahoo! Mail</a> team found that when using <code>XMLHttpRequest</code>, POST is implemented in the browsers as a two-step process: sending the headers first, then sending data. So it&amp;apos;s best to use GET, which only takes one TCP packet to send (unless you have a lot of cookies). The maximum URL length in IE is 2K, so if you send more than 2K data you might not be able to use GET.</p>
<p>An interesting side affect is that POST without actually posting any data behaves like GET. Based on the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">HTTP specs</a>, GET is meant for retrieving information, so it makes sense (semantically) to use GET when you&amp;apos;re only requesting data, as opposed to sending data to be stored server-side.</p>
<p><strong></strong> </p>
<p><strong>Post-load Components</strong></p>
<p>You can take a closer look at your page and ask yourself: &#8220;What&amp;apos;s absolutely required in order to render the page initially?&#8221;. The rest of the content and components can wait.</p>
<p>JavaScript is an ideal candidate for splitting before and after the onload event. For example if you have JavaScript code and libraries that do drag and drop and animations, those can wait, because dragging elements on the page comes after the initial rendering. Other places to look for candidates for post-loading include hidden content (content that appears after a user action) and images below the fold.</p>
<p>Tools to help you out in your effort: <a href="http://developer.yahoo.com/yui/imageloader/">YUI Image Loader</a> allows you to delay images below the fold and the <a href="http://developer.yahoo.com/yui/get/">YUI Get utility</a> is an easy way to include JS and CSS on the fly. For an example in the wild take a look at <a href="http://www.yahoo.com/">Yahoo! Home Page</a> with Firebug&amp;apos;s Net Panel turned on.</p>
<p>It&amp;apos;s good when the performance goals are inline with other web development best practices. In this case, the idea of progressive enhancement tells us that JavaScript, when supported, can improve the user experience but you have to make sure the page works even without JavaScript. So after you&amp;apos;ve made sure the page works fine, you can enhance it with some post-loaded scripts that give you more bells and whistles such as drag and drop and animations.</p>
<p><strong>Preload Components</strong></p>
<p>Preload may look like the opposite of post-load, but it actually has a different goal. By preloading components you can take advantage of the time the browser is idle and request components (like images, styles and scripts) you&amp;apos;ll need in the future. This way when the user visits the next page, you could have most of the components already in the cache and your page will load much faster for the user.</p>
<p>There are actually several types of preloading:</p>
<ul>
<li><em>Unconditional</em> preload &#8211; as soon as onload fires, you go ahead and fetch some extra components. Check google.com for an example of how a sprite image is requested onload. This sprite image is not needed on the google.com homepage, but it is needed on the consecutive search result page.</li>
<li><em>Conditional</em> preload &#8211; based on a user action you make an educated guess where the user is headed next and preload accordingly. On <a href="http://search.yahoo.com/">search.yahoo.com</a> you can see how some extra components are requested after you start typing in the input box.</li>
<li><em>Anticipated</em> preload &#8211; preload in advance before launching a redesign. It often happens after a redesign that you hear: &#8220;The new site is cool, but it&amp;apos;s slower than before&#8221;. Part of the problem could be that the users were visiting your old site with a full cache, but the new one is always an empty cache experience. You can mitigate this side effect by preloading some components before you even launched the redesign. Your old site can use the time the browser is idle and request images and scripts that will be used by the new site</li>
</ul>
<p> </p>
<p><strong>Reduce the Number of DOM Elements</strong></p>
<p>A complex page means more bytes to download and it also means slower DOM access in JavaScript. It makes a difference if you loop through 500 or 5000 DOM elements on the page when you want to add an event handler for example.</p>
<p>A high number of DOM elements can be a symptom that there&amp;apos;s something that should be improved with the markup of the page without necessarily removing content. Are you using nested tables for layout purposes? Are you throwing in more <code>&lt;div&gt;</code>s only to fix layout issues? Maybe there&amp;apos;s a better and more semantically correct way to do your markup.</p>
<p>A great help with layouts are the <a href="http://developer.yahoo.com/yui/">YUI CSS utilities</a>: grids.css can help you with the overall layout, fonts.css and reset.css can help you strip away the browser&amp;apos;s defaults formatting. This is a chance to start fresh and think about your markup, for example use <code>&lt;div&gt;</code>s only when it makes sense semantically, and not because it renders a new line.</p>
<p>The number of DOM elements is easy to test, just type in Firebug&amp;apos;s console:<br />
<code>document.getElementsByTagName('*').length</code></p>
<p>And how many DOM elements are too many? Check other similar pages that have good markup. For example the <a href="http://www.yahoo.com/">Yahoo! Home Page</a> is a pretty busy page and still under 700 elements (HTML tags).</p>
<p><strong>Split Components Across Domains</strong></p>
<p>Splitting components allows you to maximize parallel downloads. Make sure you&amp;apos;re using not more than 2-4 domains because of the DNS lookup penalty. For example, you can host your HTML and dynamic content on <code>www.example.org</code> and split static components between <code>static1.example.org</code> and <code>static2.example.org</code></p>
<p>For more information check &#8220;<a href="http://yuiblog.com/blog/2007/04/11/performance-research-part-4/">Maximizing Parallel Downloads in the Carpool Lane</a>&#8221; by Tenni Theurer and Patty Chi.</p>
<p><strong></strong> </p>
<p><strong>Minimize the Number of iframes</strong></p>
<p>Iframes allow an HTML document to be inserted in the parent document. It&amp;apos;s important to understand how iframes work so they can be used effectively.</p>
<p><code>&lt;iframe&gt;</code> pros:</p>
<ul>
<li>Helps with slow third-party content like badges and ads</li>
<li>Security sandbox</li>
<li>Download scripts in parallel</li>
</ul>
<p><code>&lt;iframe&gt;</code> cons:</p>
<ul>
<li>Costly even if blank</li>
<li>Blocks page onload</li>
<li>Non-semantic</li>
</ul>
<p><strong></strong> </p>
<p><strong>No 404s</strong></p>
<p>HTTP requests are expensive so making an HTTP request and getting a useless response (i.e. 404 Not Found) is totally unnecessary and will slow down the user experience without any benefit.</p>
<p>Some sites have helpful 404s &#8220;Did you mean X?&#8221;, which is great for the user experience but also wastes server resources (like database, etc). Particularly bad is when the link to an external JavaScript is wrong and the result is a 404. First, this download will block parallel downloads. Next the browser may try to parse the 404 response body as if it were JavaScript code, trying to find something usable in it.</p>
<p><strong></strong> </p>
<p><strong>Reduce Cookie Size</strong></p>
<p>HTTP cookies are used for a variety of reasons such as authentication and personalization. Information about cookies is exchanged in the HTTP headers between web servers and browsers. It&amp;apos;s important to keep the size of cookies as low as possible to minimize the impact on the user&amp;apos;s response time.</p>
<p>For more information check <a href="http://yuiblog.com/blog/2007/03/01/performance-research-part-3/">&#8220;When the Cookie Crumbles&#8221;</a> by Tenni Theurer and Patty Chi. The take-home of this research:</p>
<ul>
<li>Eliminate unnecessary cookies</li>
<li>Keep cookie sizes as low as possible to minimize the impact on the user response time</li>
<li>Be mindful of setting cookies at the appropriate domain level so other sub-domains are not affected</li>
<li>Set an Expires date appropriately. An earlier Expires date or none removes the cookie sooner, improving the user response time</li>
</ul>
<p> </p>
<p> <strong>Use Cookie-free Domains for Components</strong></p>
<p>When the browser makes a request for a static image and sends cookies together with the request, the server doesn&amp;apos;t have any use for those cookies. So they only create network traffic for no good reason. You should make sure static components are requested with cookie-free requests. Create a subdomain and host all your static components there.</p>
<p>If your domain is <code>www.example.org</code>, you can host your static components on <code>static.example.org</code>. However, if you&amp;apos;ve already set cookies on the top-level domain <code>example.org</code> as opposed to <code>www.example.org</code>, then all the requests to <code>static.example.org</code> will include those cookies. In this case, you can buy a whole new domain, host your static components there, and keep this domain cookie-free. Yahoo! uses <code>yimg.com</code>, YouTube uses <code>ytimg.com</code>, Amazon uses <code>images-amazon.com</code> and so on.</p>
<p>Another benefit of hosting static components on a cookie-free domain is that some proxies might refuse to cache the components that are requested with cookies. On a related note, if you wonder if you should use example.org or www.example.org for your home page, consider the cookie impact. Omitting www leaves you no choice but to write cookies to <code>*.example.org</code>, so for performance reasons it&amp;apos;s best to use the www subdomain and write the cookies to that subdomain.</p>
<p><strong></strong> </p>
<p><strong>Minimize DOM Access</strong></p>
<p>Accessing DOM elements with JavaScript is slow so in order to have a more responsive page, you should: </p>
<ul>
<li>Cache references to accessed elements</li>
<li>Update nodes &#8220;offline&#8221; and then add them to the tree</li>
<li>Avoid fixing layout with JavaScript</li>
</ul>
<p>For more information check the YUI theatre&amp;apos;s <a href="http://yuiblog.com/blog/2007/12/20/video-lecomte/">&#8220;High Performance Ajax Applications&#8221;</a> by Julien Lecomte.</p>
<p><strong>Develop Smart Event Handlers</strong></p>
<p>Sometimes pages feel less responsive because of too many event handlers attached to different elements of the DOM tree which are then executed too often. That&amp;apos;s why using <em>event delegation</em> is a good approach. If you have 10 buttons inside a <code>div</code>, attach only one event handler to the div wrapper, instead of one handler for each button. Events bubble up so you&amp;apos;ll be able to catch the event and figure out which button it originated from. </p>
<p>You also don&amp;apos;t need to wait for the onload event in order to start doing something with the DOM tree. Often all you need is the element you want to access to be available in the tree. You don&amp;apos;t have to wait for all images to be downloaded. <code>DOMContentLoaded</code> is the event you might consider using instead of onload, but until it&amp;apos;s available in all browsers, you can use the <a href="http://developer.yahoo.com/yui/event/">YUI Event</a> utility, which has an <code><a href="http://developer.yahoo.com/yui/event/#onavailable">onAvailable</a></code> method.</p>
<p>For more information check the YUI theatre&amp;apos;s <a href="http://yuiblog.com/blog/2007/12/20/video-lecomte/">&#8220;High Performance Ajax Applications&#8221;</a> by Julien Lecomte.</p>
<p><strong>Choose &lt;link&gt; over @import</strong></p>
<p>One of the previous best practices states that CSS should be at the top in order to allow for progressive rendering.</p>
<p>In IE <code>@import</code> behaves the same as using <code>&lt;link&gt;</code> at the bottom of the page, so it&amp;apos;s best not to use it.</p>
<p><strong>Avoid Filters</strong></p>
<p>The IE-proprietary <code>AlphaImageLoader</code> filter aims to fix a problem with semi-transparent true color PNGs in IE versions &lt; 7. The problem with this filter is that it blocks rendering and freezes the browser while the image is being downloaded. It also increases memory consumption and is applied per element, not per image, so the problem is multiplied.</p>
<p>The best approach is to avoid <code>AlphaImageLoader</code> completely and use gracefully degrading PNG8 instead, which are fine in IE. If you absolutely need <code>AlphaImageLoader</code>, use the underscore hack <code>_filter</code> as to not penalize your IE7+ users.</p>
<p><strong></strong> </p>
<p><strong>Optimize Images</strong></p>
<p>After a designer is done with creating the images for your web page, there are still some things you can try before you FTP those images to your web server. </p>
<ul>
<li>You can check the GIFs and see if they are using a palette size corresponding to the number of colors in the image. Using <a href="http://www.imagemagick.org/">imagemagick</a> it&amp;apos;s easy to check using<br />
<code>identify -verbose image.gif</code><br />
When you see an image useing 4 colors and a 256 color &#8220;slots&#8221; in the palette, there is room for improvement.</li>
<li>Try converting GIFs to PNGs and see if there is a saving. More often than not, there is. Developers often hesitate to use PNGs due to the limited support in browsers, but this is now a thing of the past. The only real problem is alpha-transparency in true color PNGs, but then again, GIFs are not true color and don&amp;apos;t support variable transparency either. So anything a GIF can do, a palette PNG (PNG8) can do too (except for animations). This simple imagemagick command results in totally safe-to-use PNGs:<br />
<code>convert image.gif image.png</code><br />
&#8220;All we are saying is: Give PiNG a Chance!&#8221;</li>
<li>Run <a href="http://pmt.sourceforge.net/pngcrush/">pngcrush</a> (or any other PNG optimizer tool) on all your PNGs. Example:<br />
<code>pngcrush image.png -rem alla -reduce -brute result.png</code></li>
<li>Run jpegtran on all your JPEGs. This tool does lossless JPEG operations such as rotation and can also be used to optimize and remove comments and other useless information (such as EXIF information) from your images.<br />
<code>jpegtran -copy none -optimize -perfect src.jpg dest.jpg</code></li>
</ul>
<p> </p>
<p><strong>Optimize CSS Sprites</strong></p>
<ul>
<li>Arranging the images in the sprite horizontally as opposed to vertically usually results in a smaller file size.</li>
<li>Combining similar colors in a sprite helps you keep the color count low, ideally under 256 colors so to fit in a PNG8.</li>
<li>&#8220;Be mobile-friendly&#8221; and don&amp;apos;t leave big gaps between the images in a sprite. This doesn&amp;apos;t affect the file size as much but requires less memory for the user agent to decompress the image into a pixel map. 100&#215;100 image is 10 thousand pixels, where 1000&#215;1000 is 1 million pixels</li>
</ul>
<p> </p>
<p><strong>Don’t Scale Images in HTML</strong></p>
<p>Don&amp;apos;t use a bigger image than you need just because you can set the width and height in HTML. If you need<br />
<code>&lt;img width="100" height="100" src="mycat.jpg" alt="My Cat" /&gt;</code><br />
then your image (mycat.jpg) should be 100x100px rather than a scaled down 500x500px image.</p>
<p><strong></strong> </p>
<p><strong>Make favicon.ico Small and Cacheable</strong></p>
<p>The favicon.ico is an image that stays in the root of your server. It&amp;apos;s a necessary evil because even if you don&amp;apos;t care about it the browser will still request it, so it&amp;apos;s better not to respond with a <code>404 Not Found</code>. Also since it&amp;apos;s on the same server, cookies are sent every time it&amp;apos;s requested. This image also interferes with the download sequence, for example in IE when you request extra components in the onload, the favicon will be downloaded before these extra components.</p>
<p>So to mitigate the drawbacks of having a favicon.ico make sure:</p>
<ul>
<li>It&amp;apos;s small, preferably under 1K.</li>
<li>Set Expires header with what you feel comfortable (since you cannot rename it if you decide to change it). You can probably safely set the Expires header a few months in the future. You can check the last modified date of your current favicon.ico to make an informed decision.</li>
</ul>
<p><a href="http://www.imagemagick.org/">Imagemagick</a> can help you create small favicons</p>
<p><strong>Keep Components under 25K</strong></p>
<p>This restriction is related to the fact that iPhone won&amp;apos;t cache components bigger than 25K. Note that this is the <em>uncompressed</em> size. This is where minification is important because gzip alone may not be sufficient. </p>
<p>For more information check &#8220;<a href="http://yuiblog.com/blog/2008/02/06/iphone-cacheability/">Performance Research, Part 5: iPhone Cacheability &#8211; Making it Stick</a>&#8221; by Wayne Shea and Tenni Theurer.</p>
<p><strong>Pack Components into a Multipart Document</strong></p>
<p>Packing components into a multipart document is like an email with attachments, it helps you fetch several components with one HTTP request (remember: HTTP requests are expensive). When you use this technique, first check if the user agent supports it (iPhone does not).</p>
<p><strong>Avoid Empty Image src</strong></p>
<p>Image with empty string <strong>src</strong> attribute occurs more than one will expect. It appears in two form:</p>
<ol>
<li>straight HTML</li>
</ol>
<p>&lt;img src=&#8221;"&gt;</p>
<ol>
<li>JavaScript</li>
</ol>
<p>var img = new Image();<br />
img.src = &#8220;&#8221;;</p>
<p>Both forms cause the same effect: browser makes another request to your server.</p>
<ul>
<li><strong>Internet Explorer</strong> makes a request to the directory in which the page is located.</li>
<li><strong>Safari and Chrome</strong> make a request to the actual page itself.</li>
<li><strong>Firefox</strong> 3 and earlier versions behave the same as Safari and Chrome, but version 3.5 addressed this issue<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=444931">[bug 444931]</a> and no longer sends a request.</li>
<li><strong>Opera</strong> does not do anything when an empty image src is encountered.</li>
</ul>
<p> </p>
<p><strong>Why is this behavior bad? </strong></p>
<ol>
<li>Cripple your servers by sending a large amount of unexpected traffic, especially for pages that get millions of page views per day.</li>
<li>Waste server computing cycles generating a page that will never be viewed.</li>
<li>Possibly corrupt user data. If you are tracking state in the request, either by cookies or in another way, you have the possibility of destroying data. Even though the image request does not return an image, all of the headers are read and accepted by the browser, including all cookies. While the rest of the response is thrown away, the damage may already be done.</li>
</ol>
<p>The root cause of this behavior is the way that URI resolution is performed in browsers. This behavior is defined in RFC 3986 &#8211; Uniform Resource Identifiers. When an empty string is encountered as a URI, it is considered a relative URI and is resolved according to the algorithm defined in section 5.2. This specific example, an empty string, is listed in section 5.4. Firefox, Safari, and Chrome are all resolving an empty string correctly per the specification, while Internet Explorer is resolving it incorrectly, apparently in line with an earlier version of the specification, RFC 2396 &#8211; Uniform Resource Identifiers (this was obsoleted by RFC 3986). So technically, the browsers are doing what they are supposed to do to resolve relative URIs. The problem is that in this context, the empty string is clearly unintentional.</p>
<p>HTML5 adds to the description of the tag&amp;apos;s src attribute to instruct browsers not to make an additional request in section 4.8.2:</p>
<p>The src attribute must be present, and must contain a valid URL referencing a non-interactive, optionally animated, image resource that is neither paged nor scripted. If the base URI of the element is the same as the document&amp;apos;s address, then the src attribute&amp;apos;s value must not be the empty string.</p>
<p>Hopefully, browsers will not have this problem in the future. Unfortunately, there is no such clause for &lt;script src=&#8221;"&gt; and &lt;link href=&#8221;"&gt;. Maybe there is still time to make that adjustment to ensure browsers don&amp;apos;t accidentally implement this behavior.</p>
<p>This rule was inspired by Yahoo!&amp;apos;s JavaScript guru Nicolas C. Zakas. For more information check out his article &#8220;<a href="http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/">Empty image src can destroy your site</a>&#8220;.</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=428</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring Web Applications</title>
		<link>http://al-atari.net/?p=425</link>
		<comments>http://al-atari.net/?p=425#comments</comments>
		<pubDate>Sat, 28 Aug 2010 02:23:45 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=425</guid>
		<description><![CDATA[A web application is designed to look and behave in a way similar to a native application—for example, it is scaled to fit the entire screen on iPhone OS. You can tailor your web application for Safari on iPhone OS even further, by making it appear like a native application when the user adds it [...]]]></description>
			<content:encoded><![CDATA[<p>A web application is designed to look and behave in a way similar to a native application—for example, it is scaled to fit the entire screen on iPhone OS. You can tailor your web application for Safari on iPhone OS even further, by making it appear like a native application when the user adds it to the Home screen. You do this by using settings for iPhone OS that are ignored by other platforms.</p>
<p>For example, you can specify an icon for your web application used to represent it when added to the Home screen on iPhone OS, as described in <a href="http://al-atari.net/wp-includes/js/tinymce/plugins/paste/pasteword.htm?ver=327-1235#//apple_ref/doc/uid/TP40002051-CH3-SW4">“Specifying a Webpage Icon for Web Clip.”</a> You can also minimize the Safari on iPhone OS user interface, as described in <a href="http://al-atari.net/wp-includes/js/tinymce/plugins/paste/pasteword.htm?ver=327-1235#//apple_ref/doc/uid/TP40002051-CH3-SW1">“Changing the Status Bar Appearance”</a> and <a href="http://al-atari.net/wp-includes/js/tinymce/plugins/paste/pasteword.htm?ver=327-1235#//apple_ref/doc/uid/TP40002051-CH3-SW2">“Hiding Safari User Interface Components,”</a> when your web application is launched from the Home screen. These are all optional settings that when added to your web content are ignored by other platforms.</p>
<p>Read <a href="http://al-atari.net/wp-includes/js/tinymce/plugins/UsingtheViewport/UsingtheViewport.html#//apple_ref/doc/uid/TP40006509-SW19">“Viewport Settings for Web Applications”</a> for how to set the viewport for web applications on iPhone OS.</p>
<p><strong>Specifying a Webpage Icon for Web Clip</strong></p>
<p><strong>iPhone OS Note:</strong> The Web Clip feature is available in iPhone OS 1.1.3 and later. The <code>apple-touch-icon-precomposed.png</code> filename is available in iPhone OS 2.0 and later.</p>
<p>You may want users to be able to add your web application or webpage link to the Home screen. These links, represented by an icon, are called Web Clips. Follow these simple steps to specify an icon to represent your web application or webpage on iPhone OS.</p>
<ul>
<li>To specify an icon for the entire website (every page on the website), place an icon file in PNG format in the root document folder called <code>apple-touch-icon.png</code>or <code>apple-touch-icon-precomposed.png</code>. If you use <code>apple-touch-icon-precomposed.png</code> as the filename, Safari on iPhone OS won’t add any effects to the icon.</li>
<li>To specify an icon for a single webpage or replace the website icon with a webpage-specific icon, add a link element to the webpage, as in:<br />
<table>
<tbody>
<tr>
<td scope="row">&lt;link rel=&#8221;apple-touch-icon&#8221; href=&#8221;/custom_icon.png&#8221;/&gt;</td>
</tr>
</tbody>
</table>
<p>In the above example, replace <code>custom_icon.png</code> with your icon filename. If you don’t want Safari on iPhone OS to add any effects to the icon, replace <code>apple-touch-icon</code> with <code>apple-touch-icon-precomposed</code>.</li>
</ul>
<p>See <a href="http://al-atari.net/wp-includes/InternetWeb/Conceptual/iPhoneWebAppHIG/MetricsLayout/MetricsLayout.html#//apple_ref/doc/uid/TP40007900-CH6-SW31" target="_top">“Create an Icon for Your Web Application or Webpage”</a> in <em><a href="http://al-atari.net/wp-includes/InternetWeb/Conceptual/iPhoneWebAppHIG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007900" target="_top">iPhone Human Interface Guidelines for Web Applications</a></em> for webpage icon metrics.</p>
<p><strong>Specifying a Startup Image</strong></p>
<p><strong>iPhone OS Note:</strong> Specifying a startup image is available in iPhone OS 3.0 and later.</p>
<p>On iPhone OS, similar to native applications, you can specify a startup image that is displayed while your web application launches. This is especially useful when your web application is offline. By default, a screenshot of the web application the last time it was launched is used. To set another startup image, add a link element to the webpage, as in:</p>
<table>
<tbody>
<tr>
<td scope="row">&lt;link rel=&#8221;apple-touch-startup-image&#8221; href=&#8221;/startup.png&#8221;&gt;</td>
</tr>
</tbody>
</table>
<p>In the above example, replace <code>startup.png</code> with your startup screen filename. On iPhone and iPod touch, the image must be 320 x 460 pixels and in portrait orientation.</p>
<p><strong>Hiding Safari User Interface Components</strong></p>
<p>As part of optimizing your web application for Safari on iPhone OS, have it launch in full-screen mode to look like a native application. When using full-screen mode, Safari is not used to display the web content—specifically, there is no browser URL text field at the top of the screen or button bar at the bottom of the screen. Only a status bar appears at the top of the screen. Read <a href="http://al-atari.net/wp-includes/js/tinymce/plugins/paste/pasteword.htm?ver=327-1235#//apple_ref/doc/uid/TP40002051-CH3-SW1">“Changing the Status Bar Appearance”</a> for how to minimize the status bar.</p>
<p>Set the <code><a href="http://al-atari.net/wp-includes/js/tinymce/SafariHTMLRef/Articles/MetaTags.html#//apple_ref/html/const/apple-mobile-web-app-capable" target="_top">apple-mobile-web-app-capable</a></code> meta tag to <code>yes</code> to turn on this feature. For example, the following HTML displays web content in full-screen mode.</p>
<table>
<tbody>
<tr>
<td scope="row">&lt;meta content=&#8221;yes&#8221; /&gt;</td>
</tr>
</tbody>
</table>
<p>You can determine whether a webpage is displayed in full-screen mode using the <code>window.navigator.standalone</code> read-only Boolean JavaScript property.</p>
<p><strong>Changing the Status Bar Appearance</strong></p>
<p>If your web application displays in full-screen mode like that of a native application, you can minimize the status bar that is displayed at the top of the screen on iPhone OS. Do so using the status-bar-style meta tag.</p>
<p>This meta tag has no effect unless you first specify full-screen mode as described in <a href="http://al-atari.net/wp-includes/js/tinymce/plugins/paste/pasteword.htm?ver=327-1235#//apple_ref/doc/uid/TP40002051-CH3-SW2">“Hiding Safari User Interface Components.”</a> Then use the status bar style meta tag,<code><a href="http://al-atari.net/wp-includes/js/tinymce/SafariHTMLRef/Articles/MetaTags.html#//apple_ref/html/const/apple-mobile-web-app-status-bar-style" target="_top">apple-mobile-web-app-status-bar-style</a></code>, to change the appearance of the status bar depending on your application needs. For example, if you want to use the entire screen, set the status bar style to translucent black.</p>
<p>For example, the following HTML sets the background color of the status bar to black:</p>
<table>
<tbody>
<tr>
<td scope="row">&lt;meta content=&#8221;black&#8221; /&gt;</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=425</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>7 AJAX Loading Icon Generators</title>
		<link>http://al-atari.net/?p=422</link>
		<comments>http://al-atari.net/?p=422#comments</comments>
		<pubDate>Sat, 28 Aug 2010 02:13:16 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=422</guid>
		<description><![CDATA[If you want to inform your websites’ visitor that there are more information to be displayed or still to be loaded on your page, you may need a “loading” or “wait” icon, or I simply called it a preloader image. An Ajax loading icon is also most commonly used on AJAX-base sites and applications. However, [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to inform your websites’ visitor that there are more information to be displayed or still to be loaded on your page, you may need a “loading” or “wait” icon, or I simply called it a preloader image. An Ajax loading icon is also most commonly used on AJAX-base sites and applications. However, not all of us have the skills to design and create such icons. Here, we present to you online tools that will generate an AJAX loading icons and some sites which have a collection of it that are ready for download.</p>
<p>1- <a href="http://preloaders.net/" target="_blank">Preloaders.net</a> : Preloaders.net has a nice categorized collection of GIF preloaders. You can set your preloaders’ background (<em>transparent is also available</em>) and foreground color, size with contrains proportion option and it’s animation speed.</p>
<p>2- <a href="http://ajaxload.info/" target="_blank">Ajaxload</a> : Ajaxload.info is still in Beta and the only option for it’s loading icon that you can set is it’s background and foreground color.</p>
<p>3- <a href="http://www.loadinfo.net/" target="_blank">Load Info</a> : LoadInfo.net options for it’s loading icon are background and foreground color and three predefined sizes which are 16×16, 24×24 and 48×48.</p>
<p>4- <a href="http://www.webscriptlab.com/" target="_blank">Web Script Lab</a> : Web Script Lab’s Ajax Loading GIF Generator options for it’s loading icon are background and foreground color and three predefined speed which are normal, fast and slow.</p>
<p>5- <a href="http://www.chimply.com/" target="_blank">Chimply</a> : Chimply is in Beta stage but it has also a nice collection of categorized Ajax loading icons. Common settings include background and foreground colors and it’s width. Many advanced options will appear depending on what type of preloader you are going to select.</p>
<p>6- <a href="http://mentalized.net/activity-indicators/" target="_blank">mentalized Activity Indicators</a> </p>
<p>7- <a href="http://www.sanbaldo.com/wordpress/1/ajax_gif/" target="_blank">SanBaldo Ajax Loading Animated GIF</a></p>
<p><a href="http://www.sanbaldo.com/wordpress/1/ajax_gif/" target="_blank"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=422</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make your website an iPhone web application</title>
		<link>http://al-atari.net/?p=418</link>
		<comments>http://al-atari.net/?p=418#comments</comments>
		<pubDate>Fri, 06 Aug 2010 23:28:20 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=418</guid>
		<description><![CDATA[These are a lot of tips to make your website an iPhone app so users can save it on their Home screens and access to your site faster. Specifying a Webpage Icon for iPhone Home We have two ways to design a custom icon that users can display on their Home screens using the Web [...]]]></description>
			<content:encoded><![CDATA[<p dir="ltr">These are a lot of tips to make your website an iPhone app so users can save it on their Home screens and access to your site faster.</p>
<p dir="ltr"><strong>Specifying a Webpage Icon for iPhone Home</strong></p>
<p dir="ltr">We have two ways to design a custom icon that users can display on their Home screens using the Web Clip feature:</p>
<ul>
<li dir="ltr">a simple image where iPhone 1.1.3 and later automatically adds some visual effects so that it coordinates with the built-in icons. Specifically, iPhone 1.1.3 adds:
<ul>
<li dir="ltr">rounded corners</li>
<li dir="ltr">drop shadow</li>
<li dir="ltr">reflective shine</li>
</ul>
</li>
</ul>
<p dir="ltr">This is the image for Luscarpa.com:</p>
<p>and this is how it is on iphone home screen:</p>
<ul>
<li dir="ltr">an image precomposed, to this image iPhone doesn’t add effects.<br />
This is the image precomposed for Luscarpa.com:</p>
<p>and this is how it is on iphone home screen:</li>
</ul>
<p dir="ltr">How we can provide this image? There are two ways:</p>
<ul>
<li dir="ltr">place an icon file in PNG format in the root document folder called apple-touch-icon.png or apple-touch-icon-precomposed.png. With this method you specify an icon for the entire website (every page on the website),</li>
<li dir="ltr">add a link element to the webpage, as in:</li>
</ul>
<p dir="ltr">&lt;link rel=&#8221;apple-touch-icon&#8221; href=&#8221;/custom_icon.png&#8221;/&gt;</p>
<p dir="ltr"><strong>&lt;link rel=&#8221;apple-touch-icon&#8221; href=&#8221;/custom_icon.png&#8221;/&gt;</strong></p>
<p dir="ltr">or</p>
<p dir="ltr"><strong>&lt;link rel=&#8221;apple-touch-icon-precomposed&#8221; href=&#8221;/custom_icon_precomposed.png&#8221;/&gt;</strong></p>
<p dir="ltr"><strong>&lt;link rel=&#8221;apple-touch-icon-precomposed&#8221; href=&#8221;/custom_icon_precomposed.png&#8221;/&gt;</strong></p>
<p dir="ltr">With this code you specify an icon for a single webpage or replace the website icon with a webpage-specific icon.</p>
<p dir="ltr"><strong>Hide Safari Components</strong></p>
<p dir="ltr">Add this line if you want that your web app/website don’t show the safari user interface components:</p>
<p dir="ltr">&lt;meta content=&#8221;yes&#8221; /&gt;</p>
<p dir="ltr"><strong>&lt;meta content=&#8221;yes&#8221; /&gt;</strong></p>
<p dir="ltr"><strong>Status Bar Appearance</strong></p>
<p dir="ltr">You can change the Status Bar of web app/website using the following line of code:</p>
<p dir="ltr"><strong>&lt;meta content=&#8221;black&#8221; /&gt;</strong></p>
<p dir="ltr"><strong>&lt;meta content=&#8221;black&#8221; /&gt;</strong></p>
<p dir="ltr">There are three different colors:</p>
<p dir="ltr">1-default</p>
<p dir="ltr">2-black</p>
<p dir="ltr">3-black-translucent</p>
<p dir="ltr"><em>NOTE: If set to default or black, the web content is displayed below the status bar. If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar.</em></p>
<p dir="ltr"><strong>Specifying a Startup Image</strong></p>
<p dir="ltr">On iPhone OS, similar to native applications, you can specify a startup image that is displayed while your web application/website launches. By default, this image is a screenshot of the web application with the page that the user has visited the last time. If you want customize it, add a link element to the webpage, like this:</p>
<p dir="ltr">&lt;link rel=&#8221;apple-touch-startup-image&#8221; href=&#8221;/startup.png&#8221;&gt;</p>
<p dir="ltr"><strong>&lt;link rel=&#8221;apple-touch-startup-image&#8221; href=&#8221;/startup.png&#8221;&gt;</strong></p>
<p dir="ltr">Here an example of my custom startup:</p>
<p>The image must be a png file and his dimensions 320 x 460 pixels in portrait orientation.<br />
<em>NOTE: this option works only if </em><em>apple-mobile-web-app-capable is set to yes</em></p>
<p dir="ltr"><strong>Standalone Detection</strong></p>
<p dir="ltr">You can develope custom features or effects for your standalone version of site, you can detect it using the boolean var window.navigator.standalone from javascript.</p>
<p dir="ltr"><strong>Note &amp; Conclusion</strong></p>
<p dir="ltr">All these tips only works for web pages that have been saved to the home screens and opened from there, if you access to your website using safari you don’t have this customizations. Remember also that any new link will be open in new browser tab so you lost these settings.</p>
<p dir="ltr">Is my opinion that if you develop a strongly ajax-oriented web application, so to avoid the users from stressing clicking and page refresh, allowing them to use just the “first page” , all these settings can be make your app amazing.</p>
<p dir="ltr">This website uses these options, you can test them adding it to your home screen of iPhone/iPod Touch, actually I’m using wordpress so there isn’t a customization to load all site with ajax so you can see the home page like web application, but if you click on a post link you will be redirect to safari.</p>
<p dir="ltr"><strong>Resources</strong></p>
<ul>
<li dir="ltr"><a title="Safari Dev Center - Safari Web Content Guide" href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/Introduction/Introduction.html#//apple_ref/doc/uid/TP40002079-SW1" target="_blank">Safari Dev Center – Safari Web Content Guide</a></li>
</ul>
<p dir="rtl"> </p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=418</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>XIIR Calculation</title>
		<link>http://al-atari.net/?p=412</link>
		<comments>http://al-atari.net/?p=412#comments</comments>
		<pubDate>Fri, 16 Jul 2010 21:45:25 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=412</guid>
		<description><![CDATA[Using VBA – EXCEL If you are using VB itself, then you will need to either include the reference to MS Excel or Create it as an object and then run the above code with the declaration to excel.. e.g Dim Result Dim obEx As New Excel.Application &#8216;Early Binding Result=obEx.WorksheetFunction.XIRR(Conditions) obEx.Quit Set obEx = Nothing [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Using VBA – EXCEL</strong></p>
<p>If you are using VB itself, then you will need to either include the reference to MS Excel or Create it as an object and then run the above code with the declaration to excel.. e.g</p>
<p>Dim Result<br />
Dim obEx As New Excel.Application &#8216;Early Binding<br />
Result=obEx.WorksheetFunction.XIRR(Conditions)<br />
obEx.Quit<br />
Set obEx = Nothing</p>
<p>OR</p>
<p>Dim obEx2 as Object<br />
Set obEx2 = CreateObject(&#8220;Excel.Application&#8221;)<br />
Result=obEx2.WorksheetFunction.XIRR(Conditions)<br />
obEx2.Quit<br />
Set obEx2 = Nothing<br />
<strong>Using VB.NET</strong><br />
URL : <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.irr.aspx">http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.financial.irr.aspx</a><br />
           <a href="http://msdn.microsoft.com/en-us/library/daksysx3.aspx">http://msdn.microsoft.com/en-us/library/daksysx3.aspx</a><br />
&#8216; Define money format.<br />
Dim MoneyFmt As String = &#8220;###,##0.00&#8243;<br />
&#8216; Define percentage format.<br />
Dim PercentFmt As String = &#8220;#0.00&#8243;<br />
Dim values(4) As Double<br />
&#8216; Business start-up costs.<br />
values(0) = -70000<br />
&#8216; Positive cash flows reflecting income for four successive years.<br />
values(1) = 22000<br />
values(2) = 25000<br />
values(3) = 28000<br />
values(4) = 31000</p>
<p>&#8216; Use the IRR function to calculate the rate of return.<br />
&#8216; Guess starts at 10 percent.<br />
Dim Guess As Double = 0.1<br />
&#8216; Calculate internal rate.<br />
Dim CalcRetRate As Double = IRR(values, Guess) * 100<br />
&#8216; Display internal return rate.<br />
MsgBox(&#8220;The internal rate of return for these cash flows is &#8221; &amp;<br />
    Format(CalcRetRate, CStr(PercentFmt)) &amp; &#8221; percent.&#8221;)</p>
<p>Private Sub XIRRSample()<br />
    &#8216;Print some samples of the XIRR function.</p>
<p>    Dim Flow() As Variant<br />
    ReDim Flow(1 To 2, 1 To 2)</p>
<p>    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #4/1/1984#<br />
    Flow(1, 2) = 50674#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample<br />
   </p>
<p>    ReDim Flow(1 To 2, 1 To 2)</p>
<p>    Flow(1, 1) = 10000#<br />
    Flow(2, 1) = #4/1/1984#<br />
    Flow(1, 2) = -50674#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample<br />
�<br />
    ReDim Flow(1 To 2, 1 To 2)</p>
<p>    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #4/1/1989#<br />
    Flow(1, 2) = 20660#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample</p>
<p>    ReDim Flow(1 To 2, 1 To 2)</p>
<p>    Flow(1, 1) = 10000#<br />
    Flow(2, 1) = #4/1/1989#<br />
    Flow(1, 2) = -20660#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample<br />
    ReDim Flow(1 To 2, 1 To 2)<br />
    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #4/1/1993#<br />
    Flow(1, 2) = 10482#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample<br />
   </p>
<p>    ReDim Flow(1 To 2, 1 To 5)<br />
    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #1/1/1992#<br />
    Flow(1, 2) = 2750#<br />
    Flow(2, 2) = #3/1/1992#<br />
    Flow(1, 3) = 4250#<br />
    Flow(2, 3) = #10/30/1992#<br />
    Flow(1, 4) = 3250#<br />
    Flow(2, 4) = #2/15/1993#<br />
    Flow(1, 5) = 2750#<br />
    Flow(2, 5) = #4/1/1993#</p>
<p>    GoSub One_XIRRSample<br />
   </p>
<p>    ReDim Flow(1 To 2, 1 To 4)</p>
<p>    Flow(1, 1) = -70000#<br />
    Flow(2, 1) = #1/1/1990#<br />
    Flow(1, 2) = 10000#<br />
    Flow(2, 2) = #1/1/1991#<br />
    Flow(1, 3) = 20000#<br />
    Flow(2, 3) = #1/1/1992#<br />
    Flow(1, 4) = 30000#<br />
    Flow(2, 4) = #1/1/1993#</p>
<p>    GoSub One_XIRRSample<br />
    ReDim Flow(1 To 2, 1 To 2)<br />
    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #4/1/1984#<br />
    Flow(1, 2) = 10000#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample<br />
    ReDim Flow(1 To 2, 1 To 2)<br />
    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #4/1/1984#<br />
    Flow(1, 2) = 0#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample<br />
    ReDim Flow(1 To 2, 1 To 2)</p>
<p>    Flow(1, 1) = -10000#<br />
    Flow(2, 1) = #4/1/1984#<br />
    Flow(1, 2) = -100#<br />
    Flow(2, 2) = #4/1/1994#</p>
<p>    GoSub One_XIRRSample</p>
<p>    ReDim Flow(1 To 2, 1 To 512)</p>
<p>    Flow(1, 1) = -694369.54<br />
    Flow(2, 1) = #10/22/1997#</p>
<p>    Dim intCur As Integer<br />
    intCur = 2<br />
    Dim lngMon As Long<br />
    lngMon = 12 + 12 * 1997<br />
    Do While lngMon &lt;= 7 + 12 * 2009<br />
        Dim bytMon As Byte<br />
        Dim intYr As Integer<br />
        bytMon = lngMon Mod 12<br />
        intYr = lngMon \ 12<br />
        If bytMon = 0 Then<br />
            bytMon = 12<br />
            intYr = intYr &#8211; 1<br />
        End If</p>
<p>        Flow(1, intCur) = 8421.79<br />
        Flow(2, intCur) = DateSerial(intYr, bytMon, 25)</p>
<p>        intCur = intCur + 1<br />
        lngMon = lngMon + 1&amp;<br />
    Loop</p>
<p>    ReDim Preserve Flow(1 To 2, 1 To intCur &#8211; 1)</p>
<p>    GoSub One_XIRRSample</p>
<p>    Exit Sub</p>
<p>One_XIRRSample:</p>
<p>    Dim intCurFlow As Integer<br />
    For intCurFlow = LBound(Flow, 2) To UBound(Flow, 2)<br />
        Debug.Print Right$(Space$(3) &amp; Format$(intCurFlow, &#8220;#,##0&#8243;), 3);<br />
        Debug.Print &#8221; &#8221; &amp; Right$(Space$(20) &amp; Format$(Flow(1, intCurFlow), &#8220;$#,##0.00&#8243;), 20);<br />
        Debug.Print &#8221; &#8221; &amp; Format$(Flow(2, intCurFlow), &#8220;Short Date&#8221;);<br />
        Debug.Print<br />
    Next intCurFlow</p>
<p>    Debug.Print &#8220;XIRR = &#8221; &amp; Format$(XIRR(Flow()) * 100#, &#8220;#,##0.000 000&#8243;) &amp; &#8220;%&#8221;<br />
    Debug.Print</p>
<p>    Return<br />
End Sub</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=412</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Windows Service in VB.NET</title>
		<link>http://al-atari.net/?p=402</link>
		<comments>http://al-atari.net/?p=402#comments</comments>
		<pubDate>Sun, 11 Jul 2010 22:11:32 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Windows Service]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=402</guid>
		<description><![CDATA[What is Windows Service Previously called an NT service, the core function of a Windows aervice is to run an application in the background. There are few things that make them different from a Windows application. A Windows service starts much before any user logs in to the system (if it has been setup to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>What is Windows Service</strong></p>
<p>Previously called an NT service, the core function of a Windows aervice is to run an application in the background. There are few things that make them different from a Windows application. A Windows service starts much before any user logs in to the system (if it has been setup to start at boot up process). A Windows service can also be setup in such a way that it requires a user to start it manually – the ultimate customization!</p>
<p>Windows services have their own processes, and hence run very efficiently. Normally a Windows service will not have a user interface for the simple reason that it can be run even if no one is logged into the system, but this is not a rule &#8212; you can still have a Windows service with a user interface.</p>
<p>In windows 2000 you can view a list of services currently running on your computer by opening Control Panel -&gt; Administrative Tools -&gt; Services</p>
<h3>Creating A Windows Service in VB.NET</h3>
<p>Prior to VB.NET, creating a Windows service was a lot of work, and was left to the C++ guru&#8217;s, as you had to use some system level procedures, which were extremely difficult. Thanks to VB.NET, however, this is becoming very easy and we shall now learn how to create a Windows Service in VB.NET.</p>
<p>There are a few things that you should know before we dive in, however. Windows services are not available under Windows 95, 98 or ME &#8212; you need to have Windows NT or Windows 2000 to run services.</p>
<p>The advantage to use .NET is that the framework incorporates all of the classes, which shall help us to create, install and control a Windows Service. Open Visual Studio .NET and create a new Windows service project, which we shall call &#8220;MyService&#8221;. Click OK.</p>
<p><a href="http://al-atari.net/wp-content/uploads/2010/07/Image2.gif"><img class="alignnone size-medium wp-image-405" title="Image2" src="http://al-atari.net/wp-content/uploads/2010/07/Image2-300x205.gif" alt="" width="300" height="205" /></a></p>
<p>Add a timer control from the toolbar in the Components tab (<strong>not</strong> the Windows Forms tab!). In the properties window of Timer1, change the interval property to 10000, which is 10 seconds.</p>
<h3>Examining The Source Code</h3>
<p>Double click the timer1 control to open up the code window for <code>Timer1_Elapsed</code>. Type in the following code:</p>
<p><code>Dim MyLog As New EventLog() ' create a new event log<br />
' Check if the the Event Log Exists<br />
If Not MyLog.SourceExists("MyService") Then<br />
    MyLog.CreateEventSource("MyService", "Myservice Log") ' Create Log<br />
End If<br />
MyLog.Source = "MyService"<br />
' Write to the Log<br />
MyLog.WriteEntry("MyService Log", "This is log on " &amp; _<br />
CStr(TimeOfDay), EventLogEntryType.Information) </code></p>
<p>Type in the following code for the <code>OnStart</code> procedure:</p>
<p><code>Timer1.Enabled = True </code></p>
<p>Type in the following code in the <code>OnStop</code> procedure:</p>
<p><code>Timer1.Enabled = False </code></p>
<p>Our application is now ready, but there are a few things that we need to do before we move ahead when we build this application. The executable created is not a Windows application, and hence you can&#8217;t just click and run it &#8212; it needs to be installed as a service, but don&#8217;t worry, we don&#8217;t have to do it manually &#8212; VB.Net has a facility where we can add an installer to our program and then use a utility to install the service.</p>
<p>Adding an Installer to the Project</p>
<p>Open the <code>service1.vb</code> design window, right click on it and select Add Installer option, which will add an installer project (called <code>ProjectInstaller.vb</code>) with two controls &#8212; ServiceProcessInstaller1 and ServiceInstaller1 &#8212; to our existing project.</p>
<p>Select the ServiceInstaller1 control and open the property window. Change the <code>ServiceName</code> property and <code>DisplayName</code> property to MyService (this is the name you want to appear in the list of services in the services window). Select the ServiceProcessInstaller1 control and open the property window. Change the <code>Account</code> property to LocalSystem (this needs to be specified as we need to run the service on our local machine).</p>
<p>Now it&#8217;s time for us to build the application and create an executable. Select Build Solution from the Build menu to create an executable with installation instructions for the service.</p>
<h3>Installing the Service</h3>
<p>To install our service we need to use the InstallUtil program, which is a .NET utility to install Windows services. You can find it in <code>C:\WINNT\Microsoft.NET\Framework\v1.0.3705 </code></p>
<p><strong>Note: </strong>This directory might be different on your computer, depending upon the version of the .NET framework you are working with Alternatively, you could run a .NET Command Window by selecting <code>Start –&gt; Programs -&gt; Microsoft Visual Studio .NET -&gt; Visual Studio .NET Tools &gt;- Visual Studio .NET Command Prompt</code>, which sets all of the required paths for you.</p>
<p>Type the following command in the command window:</p>
<p><code>InstallUtil "d:\My documents\development\applications\MyService\bin\Myservice.exe" </code></p>
<p>This is the path for the executable of the service we just created. Remember that VB.NET created the executable in the Bin folder under the project folder, so make sure you change this to your executable path.</p>
<h3>Starting the service</h3>
<p>Running a service and starting a service are two different things &#8212; when you install the service with InstallUtil you are running the service, but have yet have to start it.</p>
<p>To view and start the service, open Control Panel -&gt; Administrative Tools. Now click Services, locate MyService, right click on it and select Start to start it:</p>
<p><a href="http://al-atari.net/wp-content/uploads/2010/07/Image3.gif"><img class="alignnone size-medium wp-image-403" title="Image3" src="http://al-atari.net/wp-content/uploads/2010/07/Image3-300x180.gif" alt="" width="300" height="180" /></a></p>
<p>Our service is now started. Open the Event Viewer from Administrative Tools and click Application Log to see the logs created by the Service (MyService) every 10 seconds. If you don&#8217;t see any logs click refresh (F5). You will have to keep refreshing to see the latest event logs:<br />
<a href="http://al-atari.net/wp-content/uploads/2010/07/Image5.gif"><img class="alignnone size-medium wp-image-404" title="Image5" src="http://al-atari.net/wp-content/uploads/2010/07/Image5-300x182.gif" alt="" width="300" height="182" /></a></p>
<h3>Stopping the Service</h3>
<p>This procedure is similar to installing the service but now we shall run the InstallUtil with the /U parameter, which will uninstall the service:</p>
<p><code>InstallUtil /U "d:\My documents\development\applications\MyService\bin\Myservice.exe"</code></p>
<p>(or the executable path on your computer).</p>
<p>Take note of the message to confirm that the service was uninstalled properly.</p>
<p><strong>Tips</strong></p>
<ul>
<li>Stop the service and close the service window before you install/uninstall the service.</li>
<li>Always uninstall/install if you make any changes to the service application.</li>
<li>Try avoiding a user interface, inputs and message boxes in the service application.</li>
<li>Open ProjectInstaller.vb, select the ServiceInstaller1 control, and open the property window. Change the StartType property to automatic if you want to start the service automatically.</li>
<li>If you want to debug your windows service, it isn&#8217;t quite as straight forward as usual. Start your service, then go to Debug|Processes in the Visual Studio IDE. Find MyService.exe (you may need to check a box to display system processes), and attach the debugger. Then you&#8217;ll be able to set breakpoints as usual &#8211; but not in the Start procedure</li>
</ul>
<p><strong>Conclusion</strong></p>
<p>Windows services are often overlooked. You should use a Windows service instead of a standard application when you need to monitor or administer something in the background. The only disadvantage of using a service is the installation procedure, but I bet that there are more positive aspects then negative when selecting a Windows service over an application running with Windows Scheduler!</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=402</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Software Development Life Cycles: Waterfall Model, V-Model (YouTube)</title>
		<link>http://al-atari.net/?p=399</link>
		<comments>http://al-atari.net/?p=399#comments</comments>
		<pubDate>Sun, 11 Jul 2010 22:00:36 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=399</guid>
		<description><![CDATA[  YouTube &#8211; Software Development Life Cycles: Waterfall Model, V-Model   ]]></description>
			<content:encoded><![CDATA[<p> </p>
<blockquote><p><a href="http://www.youtube.com/watch?v=KaPC0gsEQ68">YouTube &#8211; Software Development Life Cycles: Waterfall Model, V-Model</a><br />
<span style="display: none;"> </span><span style="display: none;"> </span><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.youtube.com/v/KaPC0gsEQ68&amp;hl=en&amp;rel=0" /><param name="wmode" value="opaque" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://www.youtube.com/v/KaPC0gsEQ68&amp;hl=en&amp;rel=0" wmode="opaque"></embed></object></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=399</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running a .net application on a server (Shared Folder)</title>
		<link>http://al-atari.net/?p=397</link>
		<comments>http://al-atari.net/?p=397#comments</comments>
		<pubDate>Sun, 11 Jul 2010 21:59:11 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[VB]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=397</guid>
		<description><![CDATA[  The question comes up all the time across hundreds of .net forums.  Here it goes: &#8220;I just created a vb.net application that works perfectly fine on my local machine, however I need to run this one application on a server so other users can use it.  When I try to run it on the [...]]]></description>
			<content:encoded><![CDATA[<div><span style="font-family: Arial; font-size: 12pt;"> </span></div>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">The question comes up all the time across hundreds of .net forums.  Here it goes: </span><em><span style="font-family: Arial; font-size: 10pt;">&#8220;I just created a vb.net application that works perfectly fine on my local machine, however I need to run this one application on a server so other users can use it.  When I try to run it on the server I get a TON of errors.&#8221; </span></em><span style="font-family: Arial; font-size: 10pt;">The error generally looks like this (warning: It&#8217;s pretty long and ugly):</span> </span></span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV3268RsV7tkGmKosXZUs3tj6BUpZ2Gleu0VU8XLSYB5T7tpuzKCpndJANntMPbBRNI"></a></span><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV0gt60zXx-mBPEfaCiVBIi5jb6r4yQISUVpekR_EGPLdbXcPHZl3U8GukmERci56w4"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV0gt60zXx-mBPEfaCiVBIi5jb6r4yQISUVpekR_EGPLdbXcPHZl3U8GukmERci56w4" alt="41163180ad8" width="395" height="319" /></span></a><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Arial; font-size: 10pt;">So the question is why does this happen now in .net, how can I get around it, and how do I stop it from happening in the future.  Before I get right down to the answers I would like to explain this (so you fully understand why this happens).</span></span> </span></span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Arial; font-size: 10pt;"> </span></span><span style="font-family: Verdana; font-size: xx-small;"> </span></p>
<div style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Arial; font-size: 10pt;"> </span></span></div>
<div><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Arial; font-size: 10pt;"></span></span></div>
<p><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Arial; font-size: 10pt;"></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">VB6 Gone Are The Days</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Gone are the days where you could write a VB6 application, compile it, throw it on a UNC shared path and apply some security rights to your end users.  That was too simple&#8230;but in reality it was a pretty poor method of doing things.  You would have to constantly be modifying the rights on network folders, your admins hated you with a passion.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">CLR and CAS</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">With the .net framework programs that run on the CLR use CAS (code access security).  What this means is you no longer assign rights to users / groups on a network.  Instead you assign trust to actual code that the programmer has developed.  Basically your applications assembly file is compared with the security policy of the machine.  When you run your application on your local machine and it works just brilliantly fine it&#8217;s due to the fact that you are running your code in the MyComputer zone.  By default the MyComputer zone has FullTrust (unrestricted permissions) to do virtually anything.  This is why the application works on your local pc just fine&#8230;now why is it not working on the server.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">It Just Wont Work On That Server</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Your application bails on the server because the server is more restrictive given its zone is the LocalIntranet zone which does not have full trust to run an executable by just anyone from any machine.  In addition, it is a lot more secure (and that&#8217;s the whole idea behind microsoft security from now on, make it more secure).  It also makes a lot more sense since now not anyone can just throw executables in a server shared and run them.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">Lets Discuss a Complete Example</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Pictures are worth 1000s of words..ya&#8230;so it&#8217;s best to stop yapping and to start showing.  Let&#8217;s go through a full blown example of an application that works fine on my local pc and bails on the server.  First and foremost it&#8217;s worthwhile to note that on most occassions applications bail on things that access other network structures, <strong>SQL data retrieval (working with the database)</strong>, etc.  The reason why I have placed a <strong>bold</strong> item on the second item is because that is what we will work on as well as in most cases this is what most people run into problems tapping into a database.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">So first and foremost the application.  We are going to write a useless application that simply pulls EmployeeID numbers from the Northwind database (The sample database given to us by MS on SQL Server).  The application has no use nor will we be writing pure beautiful code that takes advantage of stored procedures, triggers, yada yada yada.  The point of this post is not how to write clean code that taps into a database, it is simply to demonstrate how to avoid the security policy error in .net.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">So lets start by creating a VB winform application.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">I&#8217;m using VS 2005 so you may have to work around if you are using 2003..the code and the methodology is the same in both.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Click file-&gt;project</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Select Visual Basic and highlight Windows</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Select Windows Application</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">For the name you can call it AvoidSecurityException and store it anywhere (I usually use C:\Temp for temporary projects, and you can call it whatever you want.</span> </span></span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV3EQplrlBYA_ubihr6Cy8EG0EhTIyxSb1K4WcPcuflx7HhNC5jx6VJToRNcr-UuFbU"></a><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV0zi-NDhn54Lt1COKTBYXSFu7loiJ4hzLhYNoi8364MigVjy385Mh2OevnTzuizeww"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV0zi-NDhn54Lt1COKTBYXSFu7loiJ4hzLhYNoi8364MigVjy385Mh2OevnTzuizeww" alt="57048411nv1" width="386" height="267" /></span></a><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Now we are going to work on our project.  Drag and drop a Button onto your form, it doesnt matter where.</span> </span></span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Double Click the button so that it takes you to the code behind page.  Since we will be dealing with databases you need to import the System.Data.SQLClient namespace.  So above the <em>public class Form1 </em>add the text <em>Imports System.Data.SQLClient</em>.</span> </span></span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV08-uVwuuQdc-WqwLmUUXoz6Fah_DIw6LOF-Jbc3-PgBS77ytSVrsh_3kimvXjzoKc"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV08-uVwuuQdc-WqwLmUUXoz6Fah_DIw6LOF-Jbc3-PgBS77ytSVrsh_3kimvXjzoKc" alt="25460115vb1" width="414" height="128" /></span></a><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV0jVCRDNiQV3RgOmBUzpOLXOenIeXb-grpMlYifH9_AlZCQ0utwVdnSiXBhyWTqbKo"></a><span style="font-family: Verdana; font-size: xx-small;"> </span></p>
<p style="text-align: left; margin: 0pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Now we have the SQLClient namespace we can start writing our code in the Button1_Click event.  </span><span style="font-family: Arial; font-size: 10pt;"> </span></span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV3zm0stsWKzTVJyJhL05MfTj78FpYHVqvmA0n8tz2Cu3qlHnUodMSXSCiZSLMEzH1Q"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV3zm0stsWKzTVJyJhL05MfTj78FpYHVqvmA0n8tz2Cu3qlHnUodMSXSCiZSLMEzH1Q" alt="52681258dg2" width="412" height="379" /></span></a></span></p>
<div style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span></div>
<div><span style="font-family: Arial; font-size: 10pt;"></span></div>
<p><span style="font-family: Arial; font-size: 10pt;"></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">We are pretty much done, told you it was a worthless application, just to show you what happens when placing this app on a server as opposed to your local machine.  Now go ahead and build your application:</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">From the menu at the top select Build-&gt;Build AvoidSecurityException (the name might be different here).</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Once you build this application you can run it on your local machine.  Either run it within Visual Studio, or double click the executable found in your projects bin/debug directory.  You will notice a simple loop that message boxes the employee id numbers, hopefully there isn&#8217;t alot, if there is you will need to end the program (ctrl alt delete).</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Great your program works, now you need to deploy it to a server so that all your other users on your network can use this program.  So you copy and paste your .exe file (the one that was in your bin/debug directory) to a network server share folder </span><a><span style="color: #223355;"><span style="text-decoration: underline;"><span style="font-family: Verdana; font-size: xx-small;">\\servername\folder</span></span></span></a><span style="font-family: Verdana; font-size: xx-small;">.  Now you double click the exe from that shared network folder and you get that same message about an unhandled exception all the way down to System.Data.SqlClient.SqlClientPermission.</span></span><span style="font-family: Verdana; font-size: xx-small;"> </span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">How To Avoid This</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">There&#8217;s a couple of ways to avoid this.  You can do it the right way which takes a bit longer and seems to be a bit more complex, or you can do it the <em>other</em> way which is much quicker but is poor practice and a security vulnerability.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">The 2 ways are:</span> </span></span></p>
<ul>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Create a strong name key and use it in your applications AssemblyInfo.vb file </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Modify the security policy to fully trust the LocalIntranet zone </span></span></li>
</ul>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">The 2nd method (bad way of doing things)</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">(From the .net security blog: </span><a href="http://blogs.msdn.com/shawnfa/default.aspx"><span style="color: #223355;"><span style="text-decoration: underline;"><span style="font-family: Verdana; font-size: xx-small;">http://blogs.msdn.com/shawnfa/default.aspx</span></span></span></a><span style="font-family: Verdana; font-size: xx-small;">)</span></span><span style="font-family: Verdana; font-size: xx-small;"> </span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">The easiest way to modify your security policy is by using the Microsoft .NET Framework Configuration utility from the control panel.  You can also run this tool from the command line by running mscorcfg.msc. </span></span></p>
<ol>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Expand the Runtime Security Policy folder </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Expand the Machine policy level </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Expand the Code Groups folder </span></span></li>
</ol>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">To modify the polcy to trust a specific strong name:</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span></span></span></p>
<ol>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Right click on All_Code, and select New </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Create a new code group for your strong name, and hit next </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Select a strong name membership condition from the drop down box </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Hit the import button, and select your assembly.  The configuration tool will import your public key.  If you want to trust everything you sign with this key, leave the name and version boxes unchecked </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Select the FullTrust permission set </span></span></li>
</ol>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">To modify the policy to allow full trust for all Intranet assemblies:</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span></span></span></p>
<ol>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Expand the All_Code code group </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Right click the LocalIntranet_Zone code group, and select properties </span></span></li>
<li style="text-align: left; margin: 0pt 0pt 0pt 36pt; unicode-bidi: embed; direction: ltr; tab-stops: list 36.0pt;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Switch to the Permission Set tab, and select FullTrust </span></span></li>
</ol>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><em><span style="font-family: Arial; font-size: 10pt;">Reference: .net security blog</span></em><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">The Right Way of doing it</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">The correct and more preferred method is to create a strong name using the sn.exe tool and using that key in your application&#8217;s AssemblyInfo file to get around these horrendous errors.  So point to your visual studio 2005 program group from the start menu.  Select <em>Visual Studio Tools</em> then select <em>Visual Studio Command Line</em></span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">The command line will open.  Type in:</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><em><span style="font-family: Arial; font-size: 10pt;">sn -k mykey.snk</span></em><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">You can change mykey to any value you want such as myappskey.snk the main thing you want to make sure is you run it with the -k option.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><em><span style="font-family: Arial; font-size: 10pt;">sn -k myappskey.snk</span></em><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">In my apps example I will stick with mykey.snk.  Result should look much like this</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"> </p>
<p><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV0d5sy8wxaj_S9m6WI9vi0Dev_XewyRamuvjC2Opg4PI0TgidxWXOuNCZSy_4OPivQ"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV0d5sy8wxaj_S9m6WI9vi0Dev_XewyRamuvjC2Opg4PI0TgidxWXOuNCZSy_4OPivQ" alt="48112545li8" width="426" height="166" /></span></a><span style="font-family: Verdana; font-size: xx-small;"> </span></p>
<p></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Notice how the key has generated and written as mykey.snk within the active directory.  Simply take and move this key to where you would like to store it.  Make sure you place it somewhere visible to the application, in addition do not store it in a local protected folder while the application is sitting on some shared server.  It needs to be able to see it (does not mean it has to physically see it within the same directory, just means it should be able to call it or have visibility to it).  Let us say you stored the key on some shared network drive.  Fine and dandy, now we need to modify our applications AssemblyInfo file to accept this key.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">So go back to your project and look in the <em>Solution Explorer </em>for the AssemblyInfo.vb file.  If you do not see it click the &#8220;Show All Files&#8221; icon (second small icon on the solution explorer).  Then drill down into &#8220;My Project&#8221; and you will see it:</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV0mga16YYLjwSguErla8MxPlEHD66H-Fn3dDu_jw_ZhVlwe72di5suagippfRvmUQc"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV0mga16YYLjwSguErla8MxPlEHD66H-Fn3dDu_jw_ZhVlwe72di5suagippfRvmUQc" alt="25608602se8" width="134" height="200" /></span></a></span></p>
<div style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span></div>
<div><span style="font-family: Arial; font-size: 10pt;"></span></div>
<p><span style="font-family: Arial; font-size: 10pt;"></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Double click this file, and you will be presented with something like so:</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV1ygYfvSyt9yuOjXVheDEIcg2Pi8ou1W2Hkpi9a2WvPU5XPU94MYbN0_Z0iBZVDlhc"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV1ygYfvSyt9yuOjXVheDEIcg2Pi8ou1W2Hkpi9a2WvPU5XPU94MYbN0_Z0iBZVDlhc" alt="50915245je3" width="424" height="330" /></span></a></span><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV1ygYfvSyt9yuOjXVheDEIcg2Pi8ou1W2Hkpi9a2WvPU5XPU94MYbN0_Z0iBZVDlhc"></a><span style="font-family: Verdana; font-size: xx-small;">  </span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span><span style="font-family: Verdana; font-size: xx-small;"> </span></p>
<div style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span></div>
<div><span style="font-family: Arial; font-size: 10pt;"></span></div>
<p><span style="font-family: Arial; font-size: 10pt;"></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">You will need to add the AssemblyKeyFile attribute to this so that your assembly is aware of your key.  So you can add it anywhere in this file.  I have added it under the AssemblyTrademark:</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><a href="http://blufiles.storage.live.com/y1pYTKTOoGriV29OBVbjWk8HXSKRBvOlT3_DY3eYe97AP18I0oz7UMPcMwqGhFDxnGgLIV0w1XJHhQ"><span style="font-family: Verdana; font-size: xx-small;"><img src="http://blufiles.storage.live.com/y1pYTKTOoGriV29OBVbjWk8HXSKRBvOlT3_DY3eYe97AP18I0oz7UMPcMwqGhFDxnGgLIV0w1XJHhQ" alt="10gw5" width="403" height="464" /></span></a></span></p>
<div style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"> </span></div>
<div><span style="font-family: Arial; font-size: 10pt;"></span></div>
<p><span style="font-family: Arial; font-size: 10pt;"></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Notice it as:</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><em><span style="font-family: Arial; font-size: 10pt;">&lt;Assembly: AssemblyKeyFile(&#8220;\\networkserver\sharedfolder\mykey.snk&#8221;)&gt;</span></em><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">You will need to modify the path to point to where you have stored your .snk file.  Now rebuild your project.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Copy over your newly generated exe file to the shared network path so that all the other users can now run your application.  Run your application from that shared folder on that server and <em>Voila</em> you no longer get the security exception error.  The application message boxes the records from the database.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><strong><span style="font-family: Arial; font-size: 10pt;">If You Still Get The Error</span></strong><span style="font-family: Arial; font-size: 10pt;"> </span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Verdana;"><span style="font-size: xx-small;"><span style="font-family: Arial; font-size: 10pt;">Strange, you shouldn&#8217;t.  But if you did make sure your key (.snk) file is visible on some shared network folder.  Make sure your AssemblyInfo.vb file has an AssemblyVersion attribute (the line right before the last line in the image posted of the AssemblyInfo file).  Make certain you got the latest .exe compiled and that you&#8217;ve copied that file over to the server.</span> </span></span></p>
<p style="text-align: left; margin: 0pt 0pt 10.5pt; unicode-bidi: embed; direction: ltr;"><span style="font-family: Arial; font-size: 10pt;"><span style="font-family: Verdana; font-size: xx-small;">Finally last thing you can do is to select Build-&gt;Publish Project from VS 2005 and tell it to publish the .exe file to a shared (UNC) server.  Go through the wizard and get it to copy it automatically.  Sometimes you will need to install the latest .net framework on the server that hosts the exe file.</span></span> </p>
<p> </p>
<p></span> </p>
<p></span> </p>
<p></span> </p>
<p></span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=397</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Call a .NET Web Service in a BlackBerry Widget</title>
		<link>http://al-atari.net/?p=382</link>
		<comments>http://al-atari.net/?p=382#comments</comments>
		<pubDate>Thu, 24 Jun 2010 12:34:05 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=382</guid>
		<description><![CDATA[URL: http://www.geekreflex.com/blog/blogarticle.aspx?ArticleID=13 One of my responsibilities where I work is to provide custom software for our BlackBerry smart phones. As of June 30, 2010, BlackBerry MDS Runtime will no longer be supported by RIM (Research in Motion). This posed a problem since we upgraded our users to new BlackBerry Bold 9700s this year. The new [...]]]></description>
			<content:encoded><![CDATA[<p>URL: <a href="http://www.geekreflex.com/blog/blogarticle.aspx?ArticleID=13">http://www.geekreflex.com/blog/blogarticle.aspx?ArticleID=13</a></p>
<p>One of my responsibilities where I work is to provide custom software for our BlackBerry smart phones. As of June 30, 2010, <a href="http://na.blackberry.com/eng/developers/rapidappdev/eolnotice.jsp">BlackBerry MDS Runtime will no longer be supported by RIM (Research in Motion)</a>. This posed a problem since we upgraded our users to new BlackBerry Bold 9700s this year. The new BlackBerry application platform focuses on two approaches; BlackBerry Widgets and Java. BlackBerry Widgets utilize web development languages such as HTML, CSS, Javascript and AJAX. Since I am not very familiar with Java development, I chose to migrate our existing MDS applications to BlackBerry Widgets.</p>
<p>RIM offers a plug-in for Microsoft Visual Studio that allows .NET developers to use a .NET programming environment to develop BlackBerry applications. The MDS plug-in worked great and provided the ability to reference a .NET Web Service with ease. The good news is, this plug-in has been updated to support new BlackBerry Widgets, however it&#8217;s still in Beta form. If you need to reference a web service in a BlackBerry Widget app you&#8217;ll notice immediately that it&#8217;s not as easy in the new web plug-in as was in the MDS plug-in. Not to worry though. With a little bit of AJAX, you can consume a web service without any problem and I&#8217;m going to explain and demonstrate how to do this from start to finish.</p>
<p>For this example, we&#8217;ll do the following:</p>
<ul>
<li>Create a BlackBerry Widget project in Microsoft Visual Studio 2008.</li>
<li>Create a .NET Web Service with a simple &#8220;Hello World&#8221; method.</li>
<li>Invoke the web service method in the BlackBerry Widget app using XMLHttpRequest.</li>
</ul>
<p>First, you&#8217;ll need a couple of things before you can create a BlackBerry Widget; the BlackBerry Web Plug-in for Visual Studio and the Sun Java Development Kit 1.6 or Higher. <a href="http://na.blackberry.com/eng/developers/browserdev/devtoolsdownloads.jsp">Follow this link</a> to get the Plug-in and JDK. The Web Plug-in for Eclipse is also provided, but for this example we&#8217;ll be using the Visual Studio Plug-in.</p>
<p>Once you have the Plug-in and JDK installed, open Visual Studio 2008 and Create a new <strong>Project</strong>. Here you <em>should</em> simply be able to select the BlackBerry Project type, then BlackBerry Widget and hit OK. However, since the Plug-in is still in Beta it&#8217;s a bit buggy. Before you can actually save a BlackBerry Widget project you have to create a separate project type first, and then add a BlackBerry Widget project as a new Project. If not, you&#8217;ll be presented with the following error when trying to save the project.</p>
<p>I didn&#8217;t research this issue so there could be other work-a-rounds and it’s possible you may not experience this error at all. I did encounter this error and I&#8217;m using Visual Studio Team System 2008 Development Edition and the MDS plug-in had also previously been installed.</p>
<p>So&#8230;instead of selecting the BlackBerry project type, expand <strong>Other Project Types</strong> and select <strong>Visual Studio Solutions</strong>. Select the <strong>Blank Solution</strong> Template, name it &#8220;HelloWorldWidget&#8221; or whatever you desire and click OK. Now, right-click on the Solution in the Solution Explorer and Add a New Project. This time, select the <strong>BlackBerry</strong> Project type, then the <strong>BlackBerry Widget</strong> Template. Again, name it &#8220;HelloWorldWidget&#8221; and click OK.</p>
<p>Two files will be created and added to your Widget project; config.xml and index.htm.</p>
<p>Before we go any further, let’s go ahead and create the Web Service. Add another <strong>New Project</strong> to your Solution. Under Visual Basic (used in this example) or Visual C# Project type, select Web and create an <strong>ASP.NET Web Service Application</strong>. Call it &#8220;HelloWorldService&#8221;. By default, a HelloWorld Web Method is already added to Service1.asmx.vb. If for whatever reason it&#8217;s not, add it.</p>
<p>Right click the Web Service in Solution Explorer, select <strong>Debug</strong> and <strong>Start new instance</strong> This will create a test ASP.NET Development Server we can use to call our service later.</p>
<p>Now let&#8217;s get back to the Widget. View the code of index.htm and add a simple input button to the body.</p>
<p>Eventually, clicking this button will display an alert box with the return string, &#8220;Hello World&#8221; from our web service. To do this, we just need a little AJAX script.</p>
<p>To keep our project neat and organized, create a <strong>New Folder</strong> in the Widget app and call it &#8220;scripts&#8221;. Right click the folder and select <strong>Add &gt; New Item&#8230;</strong>. Select <strong>JScript</strong> from the BlackBerry category and name it &#8220;actions.js&#8221;.</p>
<p>Here we&#8217;re going to use <strong>XMLHttpRequest</strong> make a request to our web service and invoke the HelloWorld method. We&#8217;ll retrieve the response in XML, then parse the XML to retrieve our return string.</p>
<p>First, create the XMLHttpRequest object.</p>
<p>Now, you&#8217;ll need an event handler which will be called from the button click on the htm page. This will send the request for data to the web service. We’ll make the request by sending a GET method to the web service.</p>
<p><em>Make sure and change the url above to your test ASP.NET Development Server url.</em><br />
The <strong>sayHello()</strong> function listens to the <strong>onreadystatechange</strong> property of the XMLHttpRequest object and calls another function that we’ll call <strong>callbackFunction()</strong>. This function determines when the server has completed our request and will handle the data returned.</p>
<p>The call back function checks for a <strong>readyState</strong> value of<strong> 4</strong>. This value indicates that the request has completed and we can use the data returned. There are other values that may be returned from this request but for this purpose we are interested in this value.<br />
We’ll receive the data as text through the <strong>responseText</strong> property of the XMLHttpRequest object and then display it in an alert box.</p>
<p>Just a few more steps and we’re done! Open your <strong>config.xml</strong> file in your BlackBerry Widget application. Here you have several different configuration options you can change, however there is only one we are required to change before our widget will work correctly. We’ll need to give our widget access to the domain where our web service resides. Click <strong>Add Domain</strong>, then enter the domain into the textbox provided. Our web service is on our local machine so we’ll use <strong>http://localhost:2064</strong>. For this example, the ASP.NET Development Server is using port 2064, but this may be different on your machine.</p>
<p>Now let’s test it out! Make sure the widget application is set as the <strong>StartUp Project</strong>, then hit F5 (or start the debug instance from the GUI). The BlackBerry simulator should start loading and you will eventually be presented with your application. The BlackBerry Simulator is a pretty cool tool, as it does very well in simulating a BlackBerry device. You can also download other BlackBerry models to simulate from BlackBerry’s website.</p>
<p>Test the widget out by clicking the button that you created. Nothing happen? Good. We still have one more step before we can get a response, sorry. I wasted a lot of time trying to figure this one out, so I intentionally left it out above so it would stand out. We have to enable our web service to be invoked using SOAP and GET, as ASP.NET does not allow this by default. To do this, simply add the following code under <strong>system.web</strong> in your web service’s <strong>Web.config</strong> file.</p>
<p>Alright, now let’s run our widget application again! This time you should receive an alert box similar to the following after pressing the button:</p>
<p>Don’t worry, we’re still not finished. Our code at this point is just returning the XML from our web service method as plain text. You have a few options here. You can parse this text to retrieve the actual value, or you can return the data as XML using the <strong>responseXML</strong> property of the XMLHTTPRequest object. Then we can parse the XML with ease to get our “Hello World&#8221; string. Change your javascript <strong>callbackFunction()</strong> to look like the following:</p>
<p>If you want to learn more about XML Parsing, check on <a href="http://www.w3schools.com/xml/xml_parser.asp">this link</a></p>
<p>Now the Widget application should display an alert box with a simple “Hello World&#8221; string.</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=382</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to call Server Side function from Client Side Code using PageMethods in ASP.NET AJAX</title>
		<link>http://al-atari.net/?p=380</link>
		<comments>http://al-atari.net/?p=380#comments</comments>
		<pubDate>Thu, 17 Jun 2010 14:34:00 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=380</guid>
		<description><![CDATA[ URL: http://www.dotnetcurry.com/ShowArticle.aspx?ID=109 You cannot call server-side code ‘directly’ from client-side code. That is because by design, the server side code executes at server side and client side code at the client. However there are some workarounds. To call serverside code from javascript, you will need to use AJAX, and the easiest way out, is to [...]]]></description>
			<content:encoded><![CDATA[<p> URL: <a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=109">http://www.dotnetcurry.com/ShowArticle.aspx?ID=109</a></p>
<p>You cannot call server-side code ‘directly’ from client-side code. That is because by design, the server side code executes at server side and client side code at the client. However there are some workarounds. To call serverside code from javascript, you will need to use AJAX, and the easiest way out, is to use the ASP.NET AJAX Extensions.</p>
<p>One option while using Microsoft ASP.NET AJAX is to call ASP.NET Web services (.asmx files) from the browser by using client script. The script can call a webservice containing server-based methods (Web methods) and invoke these methods without a postback and without refreshing the whole page. However this approach could be overkill sometimes, to perform the simplest of tasks. Moreover the logic needs to be kept in a separate .asmx file. We need something that is more ‘integrated’ with our solution.</p>
<p>The option we are going to use in this article involves PageMethods. A PageMethod is basically a public static method that is exposed in the code-behind of an aspx page and is callable from the client script. PageMethods are annotated with the [WebMethod] attribute. The page methods are rendered as inline JavaScript.</p>
<p>Let us explore PageMethods with an example. The example we will be discussing here may not be the best example to explain PageMethods, but it will give you an idea of how to call server side code from client side. In this example, we will be connecting to the Customers table in the Northwind database. We will have some textboxes which will accept the CustomerID and in turn return the Contact Name of that Customer. The method returning ContactName will be called whenever the textbox loses focus. We will be using the onblur event where a javascript code will take in the value(CustomerID) from the textbox. This javascript function will then call a PageMethod (server side code) which returns the ContactName without any page refresh.</p>
<p>I assume that you have downloaded and installed ASP.NET AJAX extensions for ASP.NET 2.0. If not, I would advise you to download the extensions from <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&amp;displaylang=en">here</a> and install it before moving ahead. At any point of time, if you find a difficulty in understanding the code, download the sample project attached with this article at the end.</p>
<p><strong>Step 1:</strong> Create an ASP.NET AJAX enabled website. Go to File &gt; New &gt; Website &gt; ASP.NET AJAX-Enabled Web Site. Give the solution a name and location and click Ok.</p>
<p><strong>Step 2:</strong> Drag and drop 2 labels and 4 textbox controls. We will be accepting the CustomerID from the user in the 2 textboxes and displaying the ‘ContactName’ in the other two textboxes. The textboxes that will display ‘ContactName’ has some properties set that will make it appear as a label without a border. Just set the BorderStyle=None, BorderColor=Transparent and ReadOnly=True. The markup will look similar to the following:</p>
<p>&lt;form id=&#8221;form1&#8243; runat=&#8221;server&#8221;&gt;    </p>
<p>        &lt;asp:ScriptManager ID=&#8221;ScriptManager1&#8243; runat=&#8221;server&#8221;/&gt;</p>
<p>        &lt;div&gt;</p>
<p>        &lt;asp:Label ID=&#8221;lblCustId1&#8243; runat=&#8221;server&#8221; Text=&#8221;Customer ID 1&#8243;&gt;&lt;/asp:Label&gt;</p>
<p>        &lt;asp:TextBox ID=&#8221;txtId1&#8243; runat=&#8221;server&#8221;&gt;&lt;/asp:TextBox&gt;&lt;br /&gt;</p>
<p>            &lt;asp:TextBox ID=&#8221;txtContact1&#8243; runat=&#8221;server&#8221; BorderColor=&#8221;Transparent&#8221; BorderStyle=&#8221;None&#8221;</p>
<p>                ReadOnly=&#8221;True&#8221;&gt;&lt;/asp:TextBox&gt;&lt;br /&gt;</p>
<p>        &lt;br /&gt;</p>
<p>        &lt;asp:Label ID=&#8221;lblCustId2&#8243; runat=&#8221;server&#8221; Text=&#8221;Customer ID 2&#8243;&gt;&lt;/asp:Label&gt;</p>
<p>        &amp;nbsp;</p>
<p>        &lt;asp:TextBox ID=&#8221;txtId2&#8243; runat=&#8221;server&#8221;&gt;&lt;/asp:TextBox&gt;&lt;br /&gt;</p>
<p>            &lt;asp:TextBox ID=&#8221;txtContact2&#8243; runat=&#8221;server&#8221; BorderColor=&#8221;Transparent&#8221; BorderStyle=&#8221;None&#8221;</p>
<p>                ReadOnly=&#8221;True&#8221;&gt;&lt;/asp:TextBox&gt;&amp;nbsp;&lt;br /&gt;</p>
<p>            &lt;/div&gt;</p>
<p>    &lt;/form&gt;</p>
<p>Before moving ahead, we will store our connection string information in the Web.config. Add the following tag below your &lt;/configSections&gt; tag. Remember we have created an ‘ASP.NET AJAX enabled website’. The tag &lt;/configSections&gt; along with some other tags automatically get added to the web.config.</p>
<p>&lt;connectionStrings&gt;</p>
<p>            &lt;removename=&#8221;all&#8221;/&gt;</p>
<p>            &lt;addname=&#8221;NorthwindConnectionString&#8221;connectionString=&#8221;Data Source=(local); Initial Catalog=Northwind; Integrated Security = SSPI;&#8221;/&gt;</p>
<p>      &lt;/connectionStrings&gt;</p>
<p><strong>Step 3:</strong> Currently we will add a method, ‘GetContactName()’ which will accept a CustomerID and return the Contact Name information from the Northwind database, Customer table. We will then transform this method as a PageMethod.</p>
<p>C#</p>
<p>public static string GetContactName(string custid)</p>
<p>    {</p>
<p>        if (custid == null || custid.Length == 0)</p>
<p>            return String.Empty;</p>
<p>        SqlConnection conn = null;</p>
<p>        try</p>
<p>        {</p>
<p>            string connection = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;</p>
<p>            conn = new SqlConnection(connection);</p>
<p>            string sql = &#8220;Select ContactName from Customers where CustomerId = @CustID&#8221;;</p>
<p>            SqlCommand cmd = new SqlCommand(sql, conn);</p>
<p>            cmd.Parameters.AddWithValue(&#8220;CustID&#8221;, custid);</p>
<p>            conn.Open();</p>
<p>            string contNm = Convert.ToString(cmd.ExecuteScalar());</p>
<p>            return contNm;</p>
<p>        }</p>
<p>        catch (SqlException ex)</p>
<p>        {</p>
<p>            return &#8220;error&#8221;;</p>
<p>        }</p>
<p>        finally</p>
<p>        {</p>
<p>            conn.Close();</p>
<p>        }</p>
<p>    }</p>
<p>VB.NET</p>
<p> Public Shared Function GetContactName(ByVal custid As String) As String</p>
<p>        If custid Is Nothing OrElse custid.Length = 0 Then</p>
<p>            Return String.Empty</p>
<p>        End If</p>
<p>        Dim conn As SqlConnection = Nothing</p>
<p>        Try</p>
<p>            Dim connection As String = ConfigurationManager.ConnectionStrings(&#8220;NorthwindConnectionString&#8221;).ConnectionString</p>
<p>            conn = New SqlConnection(connection)</p>
<p>            Dim sql As String = &#8220;Select ContactName from Customers where CustomerId = @CustID&#8221;</p>
<p>            Dim cmd As SqlCommand = New SqlCommand(sql, conn)</p>
<p>            cmd.Parameters.AddWithValue(&#8220;CustID&#8221;, custid)</p>
<p>            conn.Open()</p>
<p>            Dim contNm As String = Convert.ToString(cmd.ExecuteScalar())</p>
<p>            Return contNm</p>
<p>        Catch ex As SqlException</p>
<p>            Return &#8220;error&#8221;</p>
<p>        Finally</p>
<p>            conn.Close()</p>
<p>        End Try</p>
<p>    End Function</p>
<p><strong>Step 4:</strong> We will now transform this method as a PageMethod and then call this method GetContactName() from client side code; i.e. using JavaScript. To enable the method as a PageMethod, add the attribute [WebMethod] on top of the method:</p>
<p>C#</p>
<p>[System.Web.Services.WebMethod]</p>
<p>public static string GetContactName(string custid)</p>
<p>{</p>
<p>}</p>
<p>VB.NET</p>
<p>&lt;System.Web.Services.WebMethod()&gt; _</p>
<p>    Public Shared Function GetContactName(ByVal custid As String) As String</p>
<p>   End Function</p>
<p>At the sametime, add the attribute EnablePageMethods=&#8221;true&#8221; to the ScriptManager as shown below:</p>
<p>&lt;asp:ScriptManager ID=&#8221;ScriptManager1&#8243; runat=&#8221;server&#8221; EnablePageMethods=&#8221;true&#8221;/&gt;</p>
<p><strong>Step 5:</strong> Let us now create the JavaScript that will call this server side code. Add a javascript file called script.js to your solution (Right Click Project &gt; Add New Item &gt; Jscript File &gt; Rename file to script.js). Add the following code to the javascript file.</p>
<p>function CallMe(src,dest)</p>
<p> {    </p>
<p>     var ctrl = document.getElementById(src);</p>
<p>     // call server side method</p>
<p>     PageMethods.GetContactName(ctrl.value, CallSuccess, CallFailed, dest);</p>
<p> }</p>
<p> // set the destination textbox value with the ContactName</p>
<p> function CallSuccess(res, destCtrl)</p>
<p> {    </p>
<p>     var dest = document.getElementById(destCtrl);</p>
<p>     dest.value = res;</p>
<p> }</p>
<p> // alert message on some failure</p>
<p> function CallFailed(res, destCtrl)</p>
<p> {</p>
<p>     alert(res.get_message());</p>
<p> }</p>
<p><strong>Step 6:</strong> We now need to reference this JavaScript file from our aspx page and invoke the ‘CallMe()’ method whenever the textbox loses focus. To do so:</p>
<p>Add a reference to the javascript file in the body tag as shown below:</p>
<p>&lt;body&gt;</p>
<p>&lt;script type=&#8221;text/javascript&#8221; language=&#8221;javascript&#8221; src=&#8221;script.js&#8221;&gt; &lt;/script&gt;</p>
<p>    &lt;form id=&#8221;form1&#8243; runat=&#8221;server&#8221;&gt;    </p>
<p>………</p>
<p><strong>Step 7:</strong> To invoke the methods whenever the textbox looses focus, add these lines of code in the Page_Load() event</p>
<p>C#</p>
<p>if (!Page.IsPostBack)</p>
<p>        {</p>
<p>            txtId1.Attributes.Add(&#8220;onblur&#8221;, &#8220;javascript:CallMe(&#8216;&#8221; + txtId1.ClientID + &#8220;&#8216;, &#8216;&#8221; + txtContact1.ClientID + &#8220;&#8216;)&#8221;);</p>
<p>            txtId2.Attributes.Add(&#8220;onblur&#8221;, &#8220;javascript:CallMe(&#8216;&#8221; + txtId2.ClientID + &#8220;&#8216;, &#8216;&#8221; + txtContact2.ClientID + &#8220;&#8216;)&#8221;);</p>
<p>        }</p>
<p>VB.NET</p>
<p>If (Not Page.IsPostBack) Then</p>
<p>                  txtId1.Attributes.Add(&#8220;onblur&#8221;, &#8220;javascript:CallMe(&#8216;&#8221; &amp; txtId1.ClientID &amp; &#8220;&#8216;, &#8216;&#8221; &amp; txtContact1.ClientID &amp; &#8220;&#8216;)&#8221;)</p>
<p>                  txtId2.Attributes.Add(&#8220;onblur&#8221;, &#8220;javascript:CallMe(&#8216;&#8221; &amp; txtId2.ClientID &amp; &#8220;&#8216;, &#8216;&#8221; &amp; txtContact2.ClientID &amp; &#8220;&#8216;)&#8221;)</p>
<p>End If</p>
<p>As shown above, we are using the Attributes.Add that lets us add an attribute to the server control’s System.Web.UI.AttributeCollection object. The function ‘CallMe’ kept in the ‘script.js’ file will be invoked. We are passing the source and destination textboxes as parameters. The source textbox will contain the CustomerID. The CustomerID will be looked up in the Customers table and the corresponding ‘ContactName’ will be retrieved in the destination textbox.</p>
<p>Well that is all that is needed to invoke server side code from client side. Run the code. Type ‘ALFKI’ in the first textbox and hit the tab key. You will see that the javascript function goes ahead and calls the PageMethod GetContactName() using PageMethods.GetContactName. It passes the value of the source textbox which contains the CustomerID. The ‘ContactName’ returned is displayed in the second textbox below the first one, in our case the value displayed is ‘Maria Anders’.</p>
<p><strong>Troubleshooting: ‘PageMethods Is &#8216;Undefined&#8217;’ error</strong></p>
<p>1.    Try setting EnablePageMethods=&#8221;true&#8221; in the script manager tag</p>
<p>&lt;asp:ScriptManager ID=&#8221;ScriptManager1&#8243; runat=&#8221;server&#8221; EnablePageMethods=&#8221;true&#8221;/&gt;</p>
<p>2.    Don&#8217;t add the javascript references or code in the &lt;head /&gt; section. Add it to the &lt;body&gt; tag.</p>
<p>&lt;body&gt;</p>
<p>&lt;script type=&#8221;text/javascript&#8221; language=&#8221;javascript&#8221; src=&#8221;script.js&#8221;&gt; &lt;/script&gt;</p>
<p>    &lt;form id=&#8221;form1&#8243; runat=&#8221;server&#8221;&gt; </p>
<p>    &lt;/form&gt;</p>
<p>&lt;/body&gt;</p>
<p>3.    Page methods needs to be static in code behind.</p>
<p>I hope you have got an idea of how to call server side code using JavaScript. I have used this technique successfully in a few projects and just love and admire PageMethods. I hope you found this article useful and I thank you for viewing it. The <strong>source code</strong> for this article can be downloaded from <a href="http://cid-2c5f5b0560e374cb.skydrive.live.com/self.aspx/.Public/Uploads/ServerCodeFromClientSide.zip"><strong>here</strong></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=380</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>iPhone Webclip Icons (apple-touch-icon)</title>
		<link>http://al-atari.net/?p=376</link>
		<comments>http://al-atari.net/?p=376#comments</comments>
		<pubDate>Wed, 16 Jun 2010 17:51:18 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=376</guid>
		<description><![CDATA[I remember, years ago, I was baffled by the little 16&#215;16 icons that were showing up in my URL toolbar, and it took a surprising amount of searching to find out how to create one. I refuse to let this happen again. So: if you want to make a custom icon for your website that [...]]]></description>
			<content:encoded><![CDATA[<p>I remember, years ago, I was baffled by the little 16&#215;16 icons that were showing up in my URL toolbar, and it took a surprising amount of searching to find out how to create one. I refuse to let this happen again.</p>
<p>So: if you want to make a custom icon for your website that will show up in the Springboard when a user makes a &#8220;webclip&#8221;, using their iPhone or iPod Touch, the dirt simple way is:</p>
<ul>
<li>Create a 57&#215;57 PNG.</li>
<li>Name it &#8220;apple-touch-icon.png&#8221;</li>
<li>Throw it in the root folder of your website. (Not the root of your server, the root of your web documents.)</li>
</ul>
<p>Boom. If you add a webclip for vjarmy.com, you&#8217;ll see my smiling mug.</p>
<p>If you want more flexibility &#8211; perhaps you don&#8217;t have access to the site root, perhaps you want to use a different file name or format &#8211; you can use a link tag in the head of the document, such as:</p>
<pre>&lt;head&gt;</pre>
<pre>    &lt;title&gt;iHelloWorld&lt;/title&gt;</pre>
<pre>    &lt;link rel="apple-touch-icon" href="/whatever.jpg"/&gt;
    OR
    &lt;link rel="apple-touch-icon-precomposed" href="/whatever.jpg"/ /&gt;</pre>
<pre>&lt;/head&gt;</pre>
<p>I&#8217;ve tested this with a slightly larger (75&#215;75) JPEG, and it works without trouble &#8211; it just scales things down.</p>
<p>If you&#8217;re testing this on your iPhone, you may notice a pause of a few seconds before the icon appears when you press &#8220;Add To Home Menu&#8221;. I&#8217;d imagine the icon only downloads when you request to make a webclip, instead of the &#8220;request it every time&#8221; method used for fetching favicon.ico. (As for why it&#8217;s a few seconds &#8211; well, that&#8217;s EDGE for you. The lag goes away when you use WiFi.)</p>
<p>Apple has more info on their <a href="http://developer.apple.com/iphone/devcenter/designingcontent.html">iPhone Dev Center</a>; look at &#8220;Create a WebClip Bookmark Icon&#8221;.</p>
<p>And don&#8217;t worry if your icon design skills aren&#8217;t up to snuff, but do worry if you care about the sanctity of your image:</p>
<p>Safari will automatically composite the icon with the standard &#8220;glassy&#8221; overlay so it looks like a built-in iPhone or iPod application.</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=376</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Custom JavaScript Alert</title>
		<link>http://al-atari.net/?p=374</link>
		<comments>http://al-atari.net/?p=374#comments</comments>
		<pubDate>Tue, 15 Jun 2010 21:23:04 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=374</guid>
		<description><![CDATA[URL:http://slayeroffice.com/code/custom_alert/ This is a demonstration of how to over-ride the default window.alert method of a browser. This was born from the design requirements of a recent project to have non-standard alerts to notify the user of a problem with data they had entered. The trick here was that all products use the same validation scripts, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">URL:<a href="http://slayeroffice.com/code/custom_alert/">http://slayeroffice.com/code/custom_alert/</a><br />
This is a demonstration of how to over-ride the default <code>window.alert</code> method of a browser.</p>
<p style="text-align: left;">This was born from the design requirements of a recent project to have non-standard alerts to notify the user of a problem with data they had entered. The trick here was that all products use the same validation scripts, and not all of them fell under this requirement.</p>
<p style="text-align: left;">To modify the validation scripts to expect another argument that would have told it to use a DIV overlay or a standard alert would have proven difficult to implement and maintain. A co-worker (<a href="http://blog.slayeroffice.com/index.php?content=1">Dean</a>) wondered out loud if it was possible to overload the alert method, and turns out &#8211; you can.</p>
<p style="text-align: left;">You can test the alert functionality with the following button. You can also type <code>javascript:alert("Hello World");</code> from your browsers URL bar to see it work.</p>
<p style="text-align: left;">The markup for the above button is:<br />
<code>&lt;input value = "Test the alert" /&gt; </code></p>
<p style="text-align: left;">Psuedo-modality is achieved by using a 100% wide and 100% tall absolutely positioned DIV element that acts as the parent element of the custom alert. This DIV overlays everything on the page and prevents user interaction with elements other than the custom alert. Note that a 1&#215;1 transparent png image is set as the background-image &#8212; this prevents MSIE from allowing the parent DIV to be &#8220;hollow&#8221;, which would defeat its purpose.</p>
<p style="text-align: left;">Only one alert can exist at a time &#8212; the function will return if it detects the existence of a previous instance of the &#8220;modalContainer&#8221; parent element. Hitting the &#8220;Ok&#8221; button will remove the &#8220;modalContainer&#8221; element from the DOM along with its child elements and hand control of the page back to the user.</p>
<p style="text-align: left;">In browsers that support <code>position:fixed</code>, meaning all of them except MSIE6 and lower, the alert will stay with the user as they scroll. Thanks to <a href="http://centricle.com/">Kevin</a> for the education on that property value.</p>
<p style="text-align: left;">This has been tested and verified to work in MSIE6, Firefox 1.0, Safari and Opera 7.1+.</p>
<p style="text-align: left;"><strong>Note:</strong> This is a demonstration <em>only</em>. I am not saying that this is a production worthy alternative to the default behavior of the window.alert method as it does not allow for true modality. I am only showing what is possible &#8211; implement at your own risk. Feel free to contact me with any suggestions.</p>
<p style="text-align: left;">Source:</p>
<p>// constants to define the title of the alert and button text.<br />
var ALERT_TITLE = &#8220;Oops!&#8221;;<br />
var ALERT_BUTTON_TEXT = &#8220;Ok&#8221;;</p>
<p>// over-ride the alert method only if this a newer browser.<br />
// Older browser will see standard alerts<br />
if(document.getElementById) {<br />
 window.alert = function(txt) {<br />
  createCustomAlert(txt);<br />
 }<br />
}</p>
<p>function createCustomAlert(txt) {<br />
 // shortcut reference to the document object<br />
 d = document;</p>
<p> // if the modalContainer object already exists in the DOM, bail out.<br />
 if(d.getElementById(&#8220;modalContainer&#8221;)) return;</p>
<p> // create the modalContainer div as a child of the BODY element<br />
 mObj = d.getElementsByTagName(&#8220;body&#8221;)[0].appendChild(d.createElement(&#8220;div&#8221;));<br />
 mObj.id = &#8220;modalContainer&#8221;;<br />
  // make sure its as tall as it needs to be to overlay all the content on the page<br />
 mObj.style.height = document.documentElement.scrollHeight + &#8220;px&#8221;;</p>
<p> // create the DIV that will be the alert<br />
 alertObj = mObj.appendChild(d.createElement(&#8220;div&#8221;));<br />
 alertObj.id = &#8220;alertBox&#8221;;<br />
 // MSIE doesnt treat position:fixed correctly, so this compensates for positioning the alert<br />
 if(d.all &amp;&amp; !window.opera) alertObj.style.top = document.documentElement.scrollTop + &#8220;px&#8221;;<br />
 // center the alert box<br />
 alertObj.style.left = (d.documentElement.scrollWidth &#8211; alertObj.offsetWidth)/2 + &#8220;px&#8221;;</p>
<p> // create an H1 element as the title bar<br />
 h1 = alertObj.appendChild(d.createElement(&#8220;h1&#8243;));<br />
 h1.appendChild(d.createTextNode(ALERT_TITLE));</p>
<p> // create a paragraph element to contain the txt argument<br />
 msg = alertObj.appendChild(d.createElement(&#8220;p&#8221;));<br />
 msg.innerHTML = txt;<br />
<br />
 // create an anchor element to use as the confirmation button.<br />
 btn = alertObj.appendChild(d.createElement(&#8220;a&#8221;));<br />
 btn.id = &#8220;closeBtn&#8221;;<br />
 btn.appendChild(d.createTextNode(ALERT_BUTTON_TEXT));<br />
 btn.href = &#8220;#&#8221;;<br />
 // set up the onclick event to remove the alert when the anchor is clicked<br />
 btn.onclick = function() { removeCustomAlert();return false; }</p>
<p><br />
}</p>
<p>// removes the custom alert from the DOM<br />
function removeCustomAlert() {<br />
 document.getElementsByTagName(&#8220;body&#8221;)[0].removeChild(document.getElementById(&#8220;modalContainer&#8221;));<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=374</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Google Maps into an ASP.NET page</title>
		<link>http://al-atari.net/?p=371</link>
		<comments>http://al-atari.net/?p=371#comments</comments>
		<pubDate>Fri, 11 Jun 2010 21:58:35 +0000</pubDate>
		<dc:creator>Mohammed Al-Atari</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://al-atari.net/?p=371</guid>
		<description><![CDATA[URL:http://blog.evonet.com.au/post/Integrating-Google-Maps-into-an-ASPNET-page.aspx While Microsoft have released their new Virtual Earth ASP.NET Control, I still haven&#8217;t found a decent wrapper that converts addresses to langitude and longitude co-ordinates.  There is a Geo coder web service available here (this shows the co-ordinates for the White House) but it seems to only work for US addresses, which doesn&#8217;t help [...]]]></description>
			<content:encoded><![CDATA[<h6>URL:<a href="http://blog.evonet.com.au/post/Integrating-Google-Maps-into-an-ASPNET-page.aspx">http://blog.evonet.com.au/post/Integrating-Google-Maps-into-an-ASPNET-page.aspx</a></h6>
<h6>While Microsoft have released their <a title="http://dev.live.com/blogs/devlive/archive/2008/07/27/386.aspx" href="http://dev.live.com/blogs/devlive/archive/2008/07/27/386.aspx">new Virtual Earth ASP.NET Control</a>, I still haven&#8217;t found a decent wrapper that converts addresses to langitude and longitude co-ordinates.  There is a Geo coder web service available <a href="http://geocoder.us/service/rest/?address=1600%20Pennsylvania%20Avenue%20NW%20Washington,%20DC%2020500">here (this shows the co-ordinates for the White House)</a> but it seems to only work for US addresses, which doesn&#8217;t help me at all.</h6>
<h6>So for the moment, I&#8217;m still using Google Maps, and have prepared the following to show you how to integrate Google Maps into your ASP.NET pages</h6>
<h6>Step 1. Get a Google Maps API key</h6>
<h6>In order to use Google Maps on your site, you need to register for a free Google Maps API key from here: <a href="http://www.google.com/apis/maps/">http://www.google.com/apis/maps/</a></h6>
<h6>Step 2. Download the SubGurim Google Maps wrapper dll</h6>
<h6>This one is the best Google Maps wrapper I have found so far <a href="http://en.googlemaps.subgurim.net/descargar.aspx">http://en.googlemaps.subgurim.net/descargar.aspx</a>.  It is a commercial product (from $10), or you can put up with the overlayed text in the free versions.Download the gmaps.dll file and add it to your \bin directory. Step 3. Set up your aspx page</h6>
<h6>In your aspx page, add a few text boxes to gather the address details.  You can simply use one textbox, or split the address to enable validation for suburbs, countries, etc.  I haven&#8217;t included any form validation in my example.</h6>
<h6>&lt;p style=&#8221;text-align:right; margin-right:300px&#8221;&gt;     Street Address:     &lt;asp:textbox ID=&#8221;txtStreetAddress&#8221; runat=&#8221;server&#8221; Width=&#8221;150px&#8221; /&gt;&lt;br /&gt;     Suburb:     &lt;asp:textbox ID=&#8221;txtSuburb&#8221; runat=&#8221;server&#8221; Width=&#8221;150px&#8221; /&gt;&lt;br /&gt;     Country:     &lt;asp:textbox ID=&#8221;txtCountry&#8221; runat=&#8221;server&#8221; Width=&#8221;150px&#8221; /&gt;&lt;br /&gt;&lt;br /&gt;     &lt;asp:Button Text=&#8221;Show Map&#8221; ID=&#8221;lnkShowMap&#8221; runat=&#8221;server&#8221; /&gt; &lt;/p&gt;</h6>
<h6>You need to add your Google API key to your web.config file like so:</h6>
<h6>&lt;appSettings&gt;     &lt;add key=&#8221;googlemaps.subgurim.net&#8221; value=&#8221;YourGoogleMapsAPIKeyHere&#8221; /&gt; &lt;/appSettings&gt;</h6>
<h6>And finally, you need to register the SubGurim wrapper at the top of your page (or in your web.config if you have a number of pages that display maps):</h6>
<h6>&lt;%@ Register Assembly=&#8221;GMaps&#8221; Namespace=&#8221;Subgurim.Controles&#8221; TagPrefix=&#8221;cc1&#8243; %&gt;</h6>
<h6>Step 4: Add code to display the mapFinally, add code that collates your address fields and calls the Google Maps wrapper.</h6>
<h6>Protected Sub lnkShowMap_Click(ByVal sender As Object, ByVal e As System.EventArgs)         Handles lnkShowMap.Click     Dim strFullAddress As String     Dim sMapKey As String =     ConfigurationManager.AppSettings(&#8220;googlemaps.subgurim.net&#8221;)     Dim GeoCode As Subgurim.Controles.GeoCode      &#8216; Combine our address fields to create the full address.  The street,     &#8216; suburb and country should be seperated by  periods (.)     strFullAddress = txtStreetAddress.Text &amp; &#8220;. &#8221; &amp; txtSuburb.Text         &amp; &#8220;. &#8221; &amp; txtCountry.Text      &#8216; Work out the longitude and latitude     GeoCode = GMap1.geoCodeRequest(strFullAddress, sMapKey)     Dim gLatLng As New Subgurim.Controles.GLatLng(GeoCode.Placemark.coordinates.lat,         GeoCode.Placemark.coordinates.lng)     &#8216; Display the map     GMap1.setCenter(gLatLng, 16, Subgurim.Controles.GMapType.GTypes.Normal)     Dim oMarker As New Subgurim.Controles.GMarker(gLatLng)     GMap1.addGMarker(oMarker) End Sub</h6>
<h6>That&#8217;s it! Check out the <a href="http://demo.evonet.com.au/GoogleMaps.aspx">demo</a> or download the <a href="http://demo.evonet.com.au/GoogleMaps.rar">source code</a>, and let me know if you find a good wrapper for the Virtual Earth ASP.NET control!</h6>
]]></content:encoded>
			<wfw:commentRss>http://al-atari.net/?feed=rss2&amp;p=371</wfw:commentRss>
		<slash:comments>81</slash:comments>
		</item>
	</channel>
</rss>
