Friday, September 30, 2011

Silverlight TextBox Watermark

The Silverlight TextBox does have a Watermark property, but Microsoft says “Do not use in a Silverlight 4 application” HERE.    So I looked into making one myself and it didn’t take much to do it.
I just wanted the text box below to show the text “Search” in a grayed out way.
image
To do this it is just setting the forground color.
"tbxSearch" Width="120" Text="Search" Foreground="#5A000000" 
VerticalAlignment="Center" GotFocus="tbxSearch_GotFocus" />

I also wanted to reset the text to the normal color and to clear the text box when the user gave it focus.  Simple enough. If you notice above, the GotFocus event is wired up to the following method:
private void tbxSearch_GotFocus(object sender, RoutedEventArgs e)
{
if (((SolidColorBrush)tbxSearch.Foreground).Color != Colors.Black)
{
tbxSearch.Text = "";
((SolidColorBrush)tbxSearch.Foreground).Color = Colors.Black;
}
}
So that is it except that this should be made into a user control.

Moving AppSettings to a Database Table

In one of our ASP.Net application we wanted to change where the AppSettings were stored from a config file to a database table.   Since this is a very large application (over 670 .cs files), the first requirement was that the majority of the changes needed to be done with a search and replace.   In the end the change looked like this:
    System.Configuration.ConfigurationSettings.AppSettings["AppVersion"]
Would be replaced by:
    cApp.AppSettings["AppVersion"];

BACKGROUND  
We had app settings in web.config and the environment specific settings were in an WebEnvironment.config file that was referenced by the web.config file.  So our appSettings section in our web.config looked like:
    <appSettings file="WebEnvironment.config">
        <add key="AppVersion" value="13.9"/>

    </appSettings>

The problem with this is that we have to do a release to change one of the settings.  Whenever we were changing a setting in the WebEnvironment.config  we had to give the deployment team a different file for each environment and have them rename the correct file depending on where they were deploying to.   So they had a WebEnvironment.configTEST, WebEnvironment.configQA, WebEnvironment.configPROD and WebEnvironment.configDR, this is a little awkward and prone to errors.

We also liked the fact that if the app settings lived in a table then we could give ourselves a maintenance page where we could change the values without doing a deployment.

TABLE
First I needed the table to hold the app setting.  This was simple enough:
    create table dbo.Config
    (Environment varchar(4),
    [Key] varchar(255),
    Value varchar(8000),
    Comment varchar(255),
    LastUpdated datetime default getdate())
    go

STORED PROC
Second a stored proc to retrieve the values depending on the environment. So this is:

    create proc dbo.GetConfig(@Environment varchar(4))
    as
    begin
select [key], value
from AppConfig with(nolock)
where environment = @Environment
union all
select [key], value
from AppConfig with(nolock)
where environment = 'All'
and [key] not in
            (select env.[key]
            from AppConfig env with(nolock)
            where env.environment = @Environment
            )
order by [key]
    end
    go

SAMPLE DATA
Now insert some sample data:
insert into Config
(Environment, [Key], Value, Comment)
values ('Dev','AppVersion','13.9', 'Version of the application')

insert into Config
(Environment, [Key], Value, Comment)
values ('Dev','key1','value1', 'Test data')

insert into Config
(Environment, [Key], Value, Comment)
values ('Prod','key1','value1prod', 'Test data')

CONFIG CLASS
Now I need my new class that will hold the data, this will only load once.

using System.Data;
using System.Collections.Generic;

public class cConfig
{
    public Dictionary<string, string> AppSettings = new Dictionary<string,string>();

    public cConfig(string environment)
    {
        // the cApp.DAL is our data access layer and this just calls the stored proc and returns a table.
        foreach (DataRow dr in cApp.DAL.CommonData.GetConfig(environment).Rows)
        {
            AppSettings.Add(dr["Key"].ToString(), dr["Value"].ToString());
        }

    }

}

CLASS VARIABLE
Now we make the data available globally within the application and define it in such a way that it only insantiates the cConfig object once in a tread safe way.
using System;
using System.Collections.Generic;
using System.Configuration;

  public sealed class cApp
    {
        // This is the only time System.Configuration.ConfigurationManager.AppSettings is called.
        // The appSetting ApplicationEnv is in machine.config and will be one of the values “Dev”, “Test”, “QA”, “Prod” or “DR”
        static readonly cConfig _config = new cConfig(System.Configuration.ConfigurationManager.AppSettings["ApplicationEnv"]));

        public static Dictionary<string, string> AppSettings
        {
            get {
                return _config.AppSettings;
            }
        }
....


Now I can use this anywhere in my code by using the following:
        cApp.AppSettings["MySetting"];

Remove whitespace from your pages



Ok, this is not new. The thing is that removing whitespace is a very tricky discipline that is different from site to site. At least that was what I thought until very recently.

For some unexplained reason I started working on a little simple method to remove whitespace in a way so it works on all websites without breaking any HTML. Maybe not unexplained since I’ve written about it so many times that it would seem I got a secret obsession.

Obsession or not, here is the code I ended up with after a few hours of hacking. Just copy the code onto your base page or master page and watch the magic.

private static readonly Regex REGEX_BETWEEN_TAGS = new Regex(@">\s+<", RegexOptions.Compiled);

private static readonly Regex REGEX_LINE_BREAKS = new Regex(@"\n\s+", RegexOptions.Compiled);



/// <summary>
/// Initializes the <see cref="T:System.Web.UI.HtmlTextWriter"></see> object and calls on the child
/// controls of the <see cref="T:System.Web.UI.Page"></see> to render.
/// </summary>
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"></see> that receives the page content.</param>
protected override void Render(HtmlTextWriter writer)

{

  using (HtmlTextWriter htmlwriter = new HtmlTextWriter(new System.IO.StringWriter()))

  {

    base.Render(htmlwriter);

    string html = htmlwriter.InnerWriter.ToString();



    html = REGEX_BETWEEN_TAGS.Replace(html, "> <");

    html = REGEX_LINE_BREAKS.Replace(html, string.Empty);



    writer.Write(html.Trim());

  }

}
Remember that whitespace removal speeds up rendering in especially IE and reduces the overall weight of your page.




Thursday, September 29, 2011

Efficient stylesheet minification in C#

I was encouraged to post the code that does the actual minification.
public static string RemoveWhiteSpaceFromStylesheets(string body)
{
  body = Regex.Replace(body, @"[a-zA-Z]+#", "#");
  body = Regex.Replace(body, @"[\n\r]+\s*", string.Empty);
  body = Regex.Replace(body, @"\s+", " ");
  body = Regex.Replace(body, @"\s?([:,;{}])\s?", "$1");
  body = body.Replace(";}", "}");
  body = Regex.Replace(body, @"([\s:]0)(px|pt|%|em)", "$1");

  // Remove comments from CSS
  body = Regex.Replace(body, @"/\*[\d\D]*?\*/", string.Empty);

  return body;
}

The method takes a string of CSS and returns a minified version of it. The method have been modified for demo purposes, so you might want to optimize the code yourself.

Performance tuning tricks for ASP.NET and IIS 7

By taking advantage of these few tricks we can increase the performance of any new or existing website without changing anything but the web.config file.
The following XML snippets must be placed in the section of the web.config.

HTTP compression

You’ve always been able to perform HTTP compression in ASP.NET by using third-party libraries or own custom built ones. With IIS 7 you can now throw that away and utilize the build-in compression available from the web.config. Add the following line to enable HTTP compression:

By default, only text based content types are compressed.

doDynamicCompression

Setting this attribute to true enables compression of dynamically generated content such as pages, views, handlers. There really aren’t any reasons not to enable this.

doStaticCompression

This attribute allows you to decide whether or not you want static files such as stylesheets and script files to be compressed. Images and other non-text content types will not be compressed by default. This is also something you want to enable.

dynamicCompressionBeforeCache

If you do output caching from within your ASP.NET website, you can tell IIS 7 to compress the output before putting it into cache. Only if you do some custom output caching you might run into issues with setting this to true. Try it and test it. If your website works with this enabled, then you definitely want to keep it enabled.

Tip

By default, only text based content types are compressed. That means if you send application/x-javascript as content type, you should change it to text/javascript. If you use some custom modules in your website, then you might experience conflicts with the IIS 7 compression feature.

Resources

Cache static files

To speed up the load time for the visitors, it is crucial that everything that can be cached by the browser IS cached by the browser. That includes static files such as images, stylesheets and script files. By letting the browser cache all these files means it doesn’t need to request them again for the duration of the cache period. That saves you and your visitors a lot of bandwidth and makes the page load faster. A well primed browser cache also triggers the load and DOMContentLoaded event sooner.
By adding this snippet to your web.config, all static files are cached in the browser for 1 year:

    

This setting sets the expiration date of the file one year in the future. It does that by setting an HTTP header that instruct the browser to add the file to its internal cache. If you hit F5 or ctrl-F5, the browser will request the files no matter what the expiration is set to.
A major problem with client-side caching is if your static files change before the cache expires. Then the visitor with the old version in the cache won’t see the new file until she clears the browser cache or hit F5. Therefore, this setting must be used with caution and probably with a shorter expiration time. In part 2 of this series I’ll address this problem and provide a simple solution to it.

Tip

Make sure that user sensitive information isn't cached on the browser. It will then be available by anyone else using the same browser.

Resources



==============================================================
In this part we will focus on handling browser caching issues and optimize the number of JavaScript and CSS files loaded from an ASP.NET website. NB! All the code (a single .cs file of 125 lines) is included in the zip file at the bottom of this post.

Browser caching

In part 1, we looked at how it was possible to set an expiration header to any static file such as JavaScript and CSS files, so the browser would cache them for a long time and thereby optimize both for bandwidth and the number of requested files going from server to browser.
The problem with setting a browser cache expiration date of i.e. a JavaScript file to a year in the future becomes clear when you change the file before it expires in your visitor’s browsers. They simply won’t see the changes until they either clear their cache or hits F5 manually.

Adding the version number

The only viable way to maintain a far-in-the-future expiration date is to change the URL of the file when the file changes. So instead of including script files like so:

…we really want to get a version number included in the src attribute, like so:

The problem with this is that ASP.NET doesn’t have any feature that will inject a version number, so we have to create that our selves. It is very simple to do so by looking at when the file was last changed and then retrieve the ticks from that date. In the zip file below you’ll find a method that does exactly that and it can be used like so:

The BundleHelper.InsertFile method is one you want to use for Stylesheets as well, like so:
" type="text/css" />
Ok, now all our JavaScript and stylesheet references have the version number in the path. Next thing to look at is getting it working with the updated non-existing path.

The HTTP handler

To be able to serve the correct file even with the version number in the path, we need to register an HTTP handler in the web.config’s section like so:


The handler we just registered is called FileBundleHandler and knows how to filter out the version number to find the right file. It supports both .css and .js files. The handler also makes sure to both output cache and browser cache correctly. Just add the FileBundleHandler.cs file from the zip file to your website and you are up and running.
Now the browser cache issue has been resolved by adding a version number to the path of the included file and by adding an HTTP handler that knows how to remove it again when serving the file.

Bundle multiple files

Another common website performance issue is that there are many JavaScript and CSS files included on a page. This scenario results in the browser have to download a lot of extra files and that all slows down the performance of a website. The solution to this is also very simple when you’ve first completed the above steps to register the HTTP handler in web.config and called the BundleHelper.InsertFile method when inserting JavaScript and CSS files.

The folder structure convention

There are many ways of bundling files into a single request, like Justin Etheredge’s Squisher. For this example I have chosen a convention based approach because that doesn’t require any code to implement.
Any given ASP.NET website might have a folder structure similar to this:

The folder convention supported in the FileBundleHandler lets you reference a folder instead of just a file. Both the HTTP handler and the BundleHelper.InsertFile understand when a folder is referenced and automatically bundles all the .js or .css files to a single response. So in order to bundle all the files in a given folder, simply reference the folder name and add the extension of the types of files you want bundled. Having the folder structure above, you can add a bundle like so:

Notice that the file /scripts/common.js doesn’t exist, but the folder /scripts/common does. By adding .js at the end, we tell the HTTP handler to look for all files with the same file extension – in this case .js files. It bundles all the files in alphabetical order and serve the as a single response. For security reasons, the HTTP handler will only serve .css and .js extensions.

Minification

Since we are now running all JavaScript and stylesheet files in bundles and through the HTTP handler, it makes sense to also look at the content of the files to optimize even further.
For this example I’m using the Microsoft Ajax Minifier (MAM), which is a single .dll file capable of minifying both JavaScript and stylesheets. The MAM is my favorite JavaScript minifier since it not only removes whitespace, it also rewrites variable and function names and a lot of other things as well. For me it has proven a better choice than the YUI Compressor and Google Closure Compiler. The stylesheet minifier feature of MAM also looks very nice, but I have honestly never used it before except for this example.
Basically what MAM does is that it optimizes and removes unwanted whitespace from both JavaScript and stylesheets. The HTTP handler makes use of MAM for both single files and bundled ones, so you get full benefit no matter your scenario.

Summary

No matter if you use the website model, the web application model or ASP.NET MVC you are now able to utilize the browser cache to the fullest. Furthermore, by bundling your files using the folder convention you can minimize the number of requests sent by the browser. Both JavaScript and stylesheet files are also minified and optimized for even smaller file sizes sent over the wire.
It's worth noticing that the output caching respects file changes and therefore refreshes evertime changes are made to the JavaScript and CSS files tunnelled through this code.
Following the techniques in part 1 combined with this example will improve any website’s server-to-browser performance substantially.

Implementation

  1. Download the zip file below and place the AjaxMin.dll in your bin folder.
  2. Then place the FileBundleHandler.cs in your App_Code folder if you use the website model – otherwise place it where ever it makes sense in your structure.
  3. Now register the HTTP handler in your web.config under the section like so:



  4. The last thing you need is to start using the BundleHelper.InsertFile method on your pages for both JavaScript and stylesheets like so:


    " type="text/css" />

Monday, September 12, 2011

http-equiv: Meta Attribute Values for http-equiv

The http-equiv attribute is used by servers to gather information about a page using the HTTP header. The meta tag’s http-equiv attribute set is similar to a http header. The attribute lets you to send additional information to the browser in the http header. I rarely use any http-equiv meta elements other than content-type, and had never really thought about them for any purpose other than caching, So, as I looked deeper into the possible values, I thought I would “share”. There isn’t as much depth to this post as my usual endeavors, but hopefully this will make a good resource to bookmark.

Structure of Meta Element

The structure of the meta element is:
http-equiv="value" content="value" />
Do not include the name attribute in the meta when the http-equiv attribute is included.
Do include the content attribute. Below are the various values for the http-equiv attribute:

Values for http-equiv

content-type” content=”type; charset=charset” />
http-equiv=”content-type” indicates the type of data sent to the browser, enabling the browsers to know what to do with data received. The element, in all its forms, are optional. Content-type is the one you really don’t want to omit. For English sites use . There are many other possible values for content, such as for Japanese sites.
expires” content=”date” />
The date indicates the date and time that the document is set to expire. When the date is reached, the document will be reloaded even if the document is stored in the cache. This element is used to disable caching of the document: simply put a date that has passed in the date, and this will cause the browser to fetch new files. Put a date far into the future if you want the page to be cached. Note that IE6 will fetch the content of a users home page when a new browser window is opened, even if you set it to cache.
set-cookie” content=”name=value; expires=date; path=url“” />
The name is the name of the cookie.The value is the value to be set for that named cookie. The date is the date and time when the cookie will be deleted from the the computer. The date is optional. If you don’t include an expiration date and time, the cookie will be deleted when you exit the browser. You can include more than one http-equiv=”set-cookie” if you need to set more than one cookie name/value pair.
content-encoding” content=”data encoding” />
Indicates the encoding of the returned data; usually the compression type. For g-zipped documents, use content-encoding” content=”gzip” />
allow” content=”methods” />
Supposedly you include methods supported by server, but I’ve never seen this in action.
date” content=”date” />
Include the date and time that the page was created.
last-modified” content=”date” />
The content is the date and time the page was last modified.
location” content=”n; url” />
refresh” content=”n;url=url” />
ex. ex. n is the interval at which time the page should be refreshed: in our example, the page will refresh every 12 seconds. If included, url is the location the page will redirect to. Our second example would cause the page to redirect to Community MX after 3 seconds. Please do NOT use this method to redirect to a new URL. It is not accessible.
window-target” content=”location” />
The http-equiv=”window-target” specifies the “named window” of the current page. The main use is to prevent a page from appearing inside another framed page: . Usually this means that the Web browser will force the page to go the top frameset.
www-authenticate” content=”" />
http-equiv=”www-authenticate” is one method of providing basic access authentication, but providing such authentication in such a visible manner is not recommended for security reasons.
pics-label” content=’labellist‘ />
The Platform for Internet Content Selection (PICS) is a standard for labeling online content: basically online content rating. To generate the labelist, visit safesurf or another labellist generator. Note that the content attribute uses single quotes, because the PICS label syntax uses double quotes.
pragma” content=”option” />
cache-control” content=”option” />
You can use the http-equiv=”expires” with a past date to ensure that the browser retrieves fresh files from the server (rather than caching). Since not all client browsers and caching devices (e.g. proxy servers) are known to successfully implement all no-caching options, include multiple no-caching options, including:
content-language” content=”language-Country” />
Enables language specification, enabling search engines to accurately categorize the document into language and country. The language is the main language code, and the country is the country where the dialect of the language is more specific, such as en-US versus en-GB, US English versus English spoken in Great Britain. content-language” content=”de-AU” /> would be German as is spoken in Austria.
content-script-type” content=”language“>
The default script language for the script element is javascript. If you aren’t using JavaScript as your default, declare informs the browser which type of scripting language you are using by default: is this case, Visual Basic.
page-enter” content=”revealtrans(duration=seconds,transition=num)” />
page-exit” content=”revealtrans(duration=seconds,transition=num)” />
Page-enter and page-exit are Microsoft proprietary transitions that only work in Internet Explorer. The seconds is how long the transition should take, and num is an integer between 0 and 23, correlated with a specific type of transition (23 is random).. There are 23 transitions, from 0 – 22. A transition with value of 23 is allows Internet Explorer to randomly select from the 23 available transitions. page-enter” content=”blendTrans(duration=sec)” /> is another value.
imagetoolbar” content=”no”>
Another IE specific (which means you shouldn’t use it) http-equiv value is “imagetoolbar”. In some versions of Internet Explorer, when an image is hovered, an image toolbar appears. enables the disabling of the image toolbar.
Notes:
The following characters appearing within the content must be escaped using SGML entities:
single quote
& & ampersand
> > greater than

Friday, September 9, 2011

Magento How to run SQL anywhere

Magento is a bit complex. Sometime it takes so much time to find the existing model on Magento to retrieve data with complex query. So you will think about how to run SQL anywhere you want. Please check the below code to find the solution
01
02
03
04
05
06
07
08
09
10
$db = Mage::getModel('core/resource')->getConnection('core_write');
$table_prefix = Mage::getConfig()->getTablePrefix();
$result = $db->query("SELECT `entity_id` FROM `{$table_prefix}catalog_product_entity`");
if(!$result) {
    return false;
}
 
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
    print_r($row); // process the row data here
}
Reference: at class Zend_Db
Controls how the next row will be returned to the caller. This value must be one of the PDO::FETCH_* constants, defaulting to value of PDO::ATTR_DEFAULT_FETCH_MODE (which defaults to PDO::FETCH_BOTH).
  • PDO::FETCH_ASSOC: returns an array indexed by column name as returned in your result set
  • PDO::FETCH_BOTH (default): returns an array indexed by both column name and 0-indexed column number as returned in your result set
  • PDO::FETCH_BOUND: returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound with the PDOStatement::bindColumn() method
  • PDO::FETCH_CLASS: returns a new instance of the requested class, mapping the columns of the result set to named properties in the class. If fetch_style includes PDO::FETCH_CLASSTYPE (e.g. PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) then the name of the class is determined from a value of the first column.
  • PDO::FETCH_INTO: updates an existing instance of the requested class, mapping the columns of the result set to named properties in the class
  • PDO::FETCH_LAZY: combines PDO::FETCH_BOTH and PDO::FETCH_OBJ, creating the object variable names as they are accessed
  • PDO::FETCH_NUM: returns an array indexed by column number as returned in your result set, starting at column 0
  • PDO::FETCH_OBJ: returns an anonymous object with property names that correspond to the column names returned in your result set
Checked at:
  • Magento 1.5.1