TURKISH BLOG   |  ABOUT ME  |  ARCHIVES  | DELETE LANGUAGE COOKIE

Enes TAYLAN

Mind Hegemony - Mood 1.0 - Total Control Edition

RIA, Silverlight, Microsoft, Oracle, The Future of The Web and Web Technologies

clock February 23, 2010 07:18
Internet and computers are where things change fastest. Look at web technologies (and companies. Google is 12 and Facebook is 6 years old. Their revenues are $23 billion and $300 million, respectively). About in last 15 years user experience on the browser has changed dramatically: from static HTML pages, to dynamic web sites with advanced JavaScript capabilities (look at your Facebook Profile) and to the ultimate Rich Internet Applications (RIA) along with new web technologies to offer best tools for developers and experience for end users. Companies and communities have developed many technologies, programming languages and frameworks on browser and server side: JavaScript, ASP, PHP, Python, Ruby, JSP, JSF, ASP.NET etc. On PHP side, new versions have come to the use of developers and it dominated small websites (like small news websites) and is used by some big companies like Yahoo because of these companies' desire not to be dependent on another companies so they selected open source. JSP on Java side, has been used by many enterprises in their large scale websites. JSF was released as the successor of JSP but couldn't gain market share. On Microsoft side, ASP and its successor ASP.NET were released for dynamic websites and have been used by enterprises generally. All technologies and frameworks have continuosly improved, their new versions have released. Above is the current picture of web technologies. However, the future of internet seems very different from this picture and it seems that without breakthroughs, releasing new versions will not be sufficient for upcoming trends. (How can you build a website like this with Html?)

The reason why future of web will be different is RIA (Rich Internet Applications) because
-Graphic cards improving ceaselessly. PC's are becoming more and more powerful to display advanced UI. Even now they are more powerful than enogh to render traditional web pages.
-Social web applications need much more interactivity that traditional technologies lack.

Therefore, I think in at most 10 years, Html will be dead. When we sit on the laptop and open the browser, we will not see html content but RIA content. Html pages will live in our souvenirs. Along with Html, css will be obsolete also but not JavaScript because it will be used to communicate with browsers by RIA's.

To be able to use PC's rending power, new technologies have already been developed and are going to be improved. Flex (2004), JavaFX (2007) and Silverlight (2007) are RIA technologies by Adobe, Sun and Microsoft. Now let's look at companies' side. I think, the battle will be between Microsoft with its Silverlight and Adobe with Flex, if Oracle doesn't do anything in RIA area (it should improve JavaFX or may support more Flex) . Oracle's JavaFX (Oracle bought Sun last year) is dead now. Adobe's flex is market's No1 for the moment and Silverlight is its 4th version in 22 months. What's important is being in the RIA means also being in web technologies. In the future, when almost all websites will be RIA enabled, a company without RIA technology will be wiped out from the market. Even their server side technology will not be used. Think about Microsoft Silverlight. I think, it is the biggest guarantor of ASP.NET. If you want to use Silverlight, then using ASP.NET on server side and communicate with it via RIA Services it the best and smooth way of doing so. Almost nobody wants to use Silverlight with PHP in the back and use manual web services instead of RIA Services. Therefore, again if Oracle doesn't do anything its JSP (or JSF) will be useless also.


Taking Snapshots in ASP.NET

clock January 5, 2010 23:45

Taking snapshots of web pages is used by many applications, for example Wordpress shows a small snapshot image of the page that a link directs to. In this post, I'll show how can we get snapshot image of a web page by using a small program, an .exe executable. Hence, it is the executable that creates the image actually and our asp.net page will make use of that .exe. First create a website, add a textbox and a button like below:



Define a class level string imageName code button's click event:
public partial class _Default : System.Web.UI.Page 
{
    string imageName = "shot.png";

    protected void Button1_Click(object sender, EventArgs e)
    {
        string path = this.GetImage(TextBox1.Text, imageName, Request.PhysicalApplicationPath , 200, 100);

        Response.Redirect("~/Default2.aspx?path=" + path);        
    }

Click event above uses GetImage() method, we will talk about soon, and assigns the path of the image to the QueryString of Default2.aspx, the page responsible for displaying snapshot image.

public string GetImage(string url, string name, string rootDir, int width, int height)
{
    string fName = rootDir + "\\" + imageName;
    Shot(url, rootDir);
    System.Drawing.Image snapshotImage = System.Drawing.Image.FromFile(fName);
    
    fName = rootDir + "\\" + "snapshots" + "\\" + name + ".png";
    if (File.Exists(fName))
        File.Delete(fName);
    snapshotImage .Save(fName, ImageFormat.Png);    
    return name;
}

The GetImage() method, uses Shot() by assigning relative path of the image and root directory. After invoking Shot() method, it gets the image file that Shot() got and saved.

private void Shot(string url, string rootDir)
{
    try
    {          
        Process p = new Process();
        p.StartInfo.FileName = rootDir + "IECapt.exe";
        p.StartInfo.Arguments = String.Format("\"{0}\" \"{1}\"", url, rootDir + "\\" + imageName);
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.CreateNoWindow = false;
        p.Start();
        p.WaitForExit();
        p.Dispose();

        Label1.Text = "Success :) !!!!!";
    }
    catch (Exception ex)
    {
        Label1.Text = ex.ToString();
    }
}

This method defines a Process to start and execute a file. Then it sets up arguments (the sequence of them are same with the ones if you would use this .exe in command line).

If you want to add the feature of Wordpress (showing snapshots when hovering on links) you can implement the code above as a Web Service. Then using that service via JavaScript, or with JQuery library to make it more easy, you can get that functionality.

Note: IECapt.exe can be downloaded from here

Note: Because IECapt.exe takes snapshot of the whole page with very big resolution you should scale it in many scenarios.


Our simple Default2.aspx just has a Image control and two lines of code in Page_Load event handler to show the image:

protected void Page_Load(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(Request.QueryString["path"]))
    {
        Image1.ImageUrl = "~//" + Request.QueryString["path"].ToString();
        Response.Write(Image1.ImageUrl);
    }
}


Dragging with Silverlight Thumb Control

clock December 3, 2009 07:59

Dragging can be a useful feature in various scenarios especially in visually compelling ones. In Silverlight we can add drag capabilities to almost every element by using their MouseMove event. However, this method doesn't provide us a smooth drag experience. For example, when we drag a rectangle control by using its MouseMove event, dragging it to LHS immediately after RHS direction just stops the control. Therefore, we'll use Thumb control that is designed to be dragged with its specialized events. Let's begin:

1. Add a Grid control to your .xaml (or just use default LayoutRoot Grid)

2. Add two Grid Row Definitions to define rows
<Grid.RowDefinitions>
 <RowDefinition/>
 <RowDefinition Height="46"/>
</Grid.RowDefinitions>

3. Add a Thumb control and define its DragStarted, DragDelta (core dragging logic) and DragCompleted events as below:
<Thumb x:Name="myThumb" Height="50" HorizontalAlignment="Left" VerticalAlignment="Top" Width="50" DragDelta="myThumb_DragDelta" DragStarted="myThumb_DragStarted"       DragCompleted="myThumb_DragCompleted" >
</Thumb>

4. Add a Textblock with with 4 Run control and 1 LineBreak to show which Thumb event is running and current coordinates of Thumb:
<TextBlock Grid.Row="1" TextWrapping="Wrap">
  <Run Text="Events: "></Run>
  <Run x:Name="EventRun" FontStyle="Italic"></Run>
  <LineBreak></LineBreak>
  <Run Text="Coordinates: "></Run>
  <Run x:Name="CoordinatesRun" FontStyle="Italic"></Run>
</TextBlock>

5. In DragStarted and DragCompleted events just add the code below to populate TextBlock EventRun for informational purposes:

private void myThumb_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
	EventRun.Text = "Drag Started";
}

private void myThumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
	EventRun.Text = "Drag Completed";
}

6. DragDelta event is fired each time as soon as our Thumb Control is dragged. In this event's handler logic we first determine where Thumb control is (relative to Grid) just before it is moved on the screen. Then we calculate Thumb's new margin by adding current margin and how much it is dragged and assign this new margin to the Thumb's margin property (so it is moved).

private void myThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
	
	double marginLeft = myThumb.Margin.Left;
	double marginTop = myThumb.Margin.Top;
	
	double newMarginLeft = marginLeft + e.HorizontalChange;
	double newMarginTop = marginTop + e.VerticalChange;
	myThumb.Margin = new Thickness(newMarginLeft,newMarginTop,0,0);

        EventRun.Text = "Drag Delta (Thumb is being dragged)";
	CoordinatesRun.Text = newMarginLeft + "," + newMarginTop;
}

For informational purposes, populate EventRun and CoordinatesRun.

Hope, this helps.



Using Cache and Purging it with IDictionaryEnumerator

clock November 22, 2009 07:40

Using cache can provide enormous performance benefits. To get them, however, we, as developers, should manage cache in a good, determined way. General way of cache management is:

1. Determine keys (will be represented in string) to each information group (example: for category domain objects use category, for a specific category use category_{id}). Use this key everywhere in your code, don't change (don't use category somewhere and Category in another place), you can constant string variables for this purpose.

2. When you get data first check whether it is in cache already; if yes, take it else get from your datasource then immediately add that data to the cache with the key.

3. Write a global method that takes a prefix, to purge cache items has the prefix

As an example: Below the code method that takes data from datasource (never mind its domain, just focus on its purpose):

 public static int GetIhalelerCount()
{    
    int articleCount = 0;

    //construct your key
    string key = "tenders_approvedCount_" + categoryID.ToString();

    //check whether it is on cache or not, if yes, take it
    if (BaseDomain.Settings.EnableCaching && BizObject.Cache[key] != null)
    {
        articleCount = (int)BizObject.Cache[key];
    }

    //at this point, it is not in the cache, get it from datasource
    //and insert it to the cache with your predetermined key
    else
    {
        articleCount = SiteProvider.Provider.GetApprovedIhalelerCountByCategory(categoryID);
        BaseDomain.CacheData(key, articleCount);
    }
    return articleCount;
}

The CacheData method:

protected static void CacheData(string key, object data)
{
    //checks whether data is null or not, because in the case
    //null exception is thrown
    if (data != null)
    {	           
        HttpContext.Current.Cache.Insert(key, data, null,
            DateTime.Now.AddSeconds(10), TimeSpan.Zero);
    }
}
We need also a PurgeCacheItems method to clean unnecessary data. This method is generally used in Delete, Update, Insert methods because after this modifications data at hand become obsolete.

protected static void PurgeCacheItems(string prefix)
{
    prefix = prefix.ToLower();
    List itemsToRemove = new List();

    IDictionaryEnumerator enumerator = HttpContext.Current.Cache.GetEnumerator();
    while (enumerator.MoveNext())
    {
        if (enumerator.Key.ToString().ToLower().StartsWith(prefix))
            itemsToRemove.Add(enumerator.Key.ToString());
    }

    foreach (string item in itemsToRemove)
    {
        HttpContext.Current.Cache.Remove(item);
    }
}

In PurgeCacheItems, to get cache's content take enumeration of it by using GetEnumerator() method and iterate through it. You can also use itemsToRemove list above to list in an .aspx page, like:

protected void Page_Load(object sender, EventArgs e)
{
    IDictionaryEnumerator enumerator = HttpContext.Current.Cache.GetEnumerator();    

    while (enumerator.MoveNext())
    {
        Label1.Text += enumerator.Key.ToString() + "
"; Label2.Text += enumerator.Value.ToString() + "
"; } }

Hope, this helps.



Iterating through Page Control Collection using Linq

clock November 6, 2009 23:04

Linq is used generally to get and manipulate data by using Linq to Sql, Linq to Entities or Linq to Xml. However, it can work on many collections in .NET Framework. Now in this post, I'll show how to work on Page Control Collection with Linq. Think about the scenario you want to get every textboxes that has a text in it. To see which ones we select add them a text you want.

Create a new .aspx page and add several textboxes to it. They can be directly in page or another control (i.e. a panel control). Then add the code below to the click event of a button.

protected void Button1_Click(object sender, EventArgs e)
{
    GetControls(this.Page);
    //to instantiate the process
}


//this method is recursive.It starts with the control collection of
//the control given to it.

private void GetControls(Control parentControl)
{
    //iterates through control collection of the parent control
    //if there is textbox selects it
    var controls = from c in parentControl.Controls.Cast()
                   let txt = c as TextBox
                   where (txt != null && txt.Text.Length > 0)
                   select c;

    //add "--has text!" to each textbox
    foreach (var item in controls)
    {
        (item as TextBox).Text += "-- has text!";
    }


    //recursion step: chechks whether subcontrols has
    //their subcontrols and recurse on them
    foreach (Control control in parentControl.Controls)
    {
        if (control.Controls.Count > 0)
        {
            GetControls(control);
        }
    }         
}

By using the principle on the above example you can have much more control on your server (or user) controls than before with Linq.



JQuery SELECTORS

clock September 5, 2009 10:27

Today, I worked some on Jquery. Firstly, my interest was just to find some plugins to create nice pop-ups to show images. But, later I found myself in the docs  of JavaScript and Jquery.  As a programmer who works with major languages like Java, C#, ASP.NET, I understood how much I’ve ignored this important concept of web programming especially after seeing power of Jquery. To create shared functionality between several elements ( that shares some type of sign ), using Jquery is a very good solution in some problems (for example, highlighting codes in a document , like in this website, use name attribute in <pre> tags and give them some cool css features. This would require very strange and humble solutions when using just C#.) Now, in this entry, I am beginning a new series of articles: Jquery articles. First one: Getting Started with Jquery.

Downloading and Using Jquery
To be able to use Jquery requires no much work and as simple as writing one line of html. Just download it from here and write

<script type="text/javascript" src="jquery.js"></script>

in <head>…</head>  (make sure that “scr” is pointing the correct file !!!!!)

Now, Getting Started

Using JQuery or Javascript means using Document Object Model (DOM) and manipulating these objects. So  first of all we should have ready-to-use objects. With this code:

$(document).ready(function(){
   // Your code here
 });

,  jquery waits DOM objects to be loaded and executes your code in “//Your code here” section.

Note: Jquery has many shortcuts. The code above is same as:

var doc = new jQuery(document);
doc.ready(function() {
   // Your code here
});
This point is important because shortcuts are used so often.

Using Selectors and Events

We said writing Javascript means using DOM objects. So the point is “how to find and select them”. This is achieved in classic Javascript by using “getElementById(elementIDName)”. Jquery has a good shortcut: $. However when selecting these objects we should write some CSS or XPath selectors. Examples:

1.Selecting all “a” html elements and binding a function to their click events.
$("a").click(function(event){
     alert("www.enestaylan.com!");
   });
Note: Don’t forget to write this code in “$(document).ready…..” or in a custom function.

2.Select a specific element with its id:
$("#menu").click(function(event){
     alert("www.enestaylan.com!");
   });
Note: Look at “#” sign before “menu”

3.Select  elements with their css class:
$(".menu").click(function(event){
     alert("www.enestaylan.com!");
   });
4. Selecting all certain types of children elements from a specific html element
$(document).ready(function() {
   $("#myList > li").addClass("green");
 });
This code is same as:
$(document).ready(function() {
   $("#myList li").addClass("green");
 });
and
$(document).ready(function() {
   $("#myList").find("li").addClass("green");
 });
Codes above selects all “li” elements from html element whose id is “myList”

5. Using “first” and “last” keywords to select first and last elements from an element list:
$(document).ready(function() {
   $("# myList li:first").addClass("blue");
 });
6.Selecting html elements that have some specific sub element:
$(document).ready(function() {
   $("li").filter(":has(ul)").css("background-color", "1px red"); 
 });
This code selects all “li” elements that has “ul” sub-element and give them a css attribute. The logical not of this code is:
$(document).ready(function() {
   $("li").not(":has(ul)").css("background-color", "1px red"); 
 });
Note: Second code snippet has “not” instead of “filter”

7. Filtering elements according to their attributes:
$(document).ready(function() {
   $("a[name]").css("background", "red" );
 });
This code selects all “a” element that has name attribute.
$(document).ready(function() {
   $("a[href*=/jpg]").click(function() {
     // do something
   });
 });
The code above select all “a” elements whose href attributes containes “jpg” word. (Here *= means contains. For exact matching use just  = )


CACHING WITH SQL DEPENDENCY SUPPORT-1

clock July 17, 2009 02:40

Caching data that comes from an SQL database (in other words dependencies to database tables) in RAM has been supported since ASP.NET 2.0. In practice this means, we can cache the data for undetermined period until the source database table is updated. This cache mechanism works for SQL Server 7 and later including SQL 2005 and SQL 2008. SQL 2005 and SQL 2008 supports another type of cache invalidation based on events. I call first mechanism as Table Level SQL Dependencies and second as Command Level SQL Dependencies. In this article, "Table Level SQL Dependencies" will be spoken. For "Command Level SQL Dependencies" you can look at "Caching with SQL Dependency Support-2".

Table Level SQL Dependencies
This cache invalidation mechanism use polling technique and creates a table AspNet_CacheTablesForChangeNotification for the database in which you want to enable cache invalidation and creates a row for each table, you customly select these ones, in this database. ASP.NET runtime engine places a counter in these rows and checks every so often (the interval is configurable) and if it is updated than deletes the cached information from the cache. To create required database schema run aspnet_regsql.exe run below command:

aspnet-regsql.exe -E -S .\YourCustomSqlServerNameHere -d YourCustomDatabaseNameHere -ed
 -E option is for Windows Integrated Security
 -S for Sql Server Instance name
 -d for database name
 -ed for "enable database"

Above command creates required tables, triggers, stored procedures etc. The next step is adding a row to this table for the table to which you're adding support  (this also automatically adds a trigger to your table)

aspnet-regsql.exe -E -S .\YourCustomSqlServerNameHere -d YourCustomDatabaseNameHere -t Customers -et
 -t is for table name
 -et is for "enable table"

The last thing to enable Sql Cache dependency is to configure web.config:

<configuration>
 <connectionStrings>
  <add name="MyConString"............ //other details here    />
 </connectionStrings>
 
 <system.web>
  <caching>
   <sqlCacheDependency enabled="true" pollTime="20000">
    <databases>
     <add name="MyCustomCache " connectionStringName="MyConString" pollTime="5000" />
    </databases> 
   </sqlCacheDependency>
  </caching>
 </system.web>
</configuration>


pollTime above defines the polling interval of 20000 milliseconds (20 seconds) default and re-writes it for our specific database by 5000 milliseconds (5 seconds) Now everything is configured so let’s try code:

public List GetProducts()
{
     List productNames = null;
     if (Cache["ProductNames"] != null) 
     {
         productNames = (List)Cache["ProductNames"];
         //if cache already contains the info return it
     }
     else
     {
         using (SqlConnection conn = new SqlConnection(_connString))
         {
             SqlCommand cmd = new SqlCommand("SELECT ProductNames FROM Products", cn);
             productNames = cmd.ExecuteReader().FillListFromReader(cmd.ExecuteReader());

             //FillListFromReader is an umimplemented method that takes the
             //the result of "ExecuteReader" and converts it to List

             SqlCacheDependency dep = new SqlCacheDependency("MyCustomCache", "Products");
             //MyCustomCache is the name we defined in web.config
             //Products is the table name we want to cache on it

             Cache.Insert("ProductName", productNames, dep);
         }
     }
}


NEW FEATURES COME WITH ASP.NET 4.0

clock July 13, 2009 05:55
Like ASP.NET 3.5, ASP.NET 4.0 comes with many new features. In Mix09 there were several sessions, I haven't yet written about, about new features ASP.NET will make available in version 4.0  We'll see them but to show you the path ASP.NET has pursuit, first, which improvements ASP.NET 3.5 made:

  1. Microsoft Entity Framework
  2. ADO.NET Data Services
  3. Dynamic Data
  4. Microsoft Ajax Improvements
             --Browser History
             --Script Combining

Now new features of ASP.NET 4.0 in its all sub-framework:

Web Forms:.net hierachy
  • <asp:formView control now has "RenderTable"  property that when we set it to "false" doesn't render its content in <table>..</table> tags. This is important because almost all developers use <div>..</div> tags with .css files to control the layout of their pages.

  • <asp:ListView control now can be used without section <Layout>.....</Layout> Although clearly defining the layout sometimes can be very useful event crucial, in many situations developers use ListView for simple and easy situations and don't need it.

  • ViewState is disabled default. ViewState is a major improvement of ASP.NET in web technologies. However many developers use it in situations that actually don't require ViewState and this results in waste of bandwidth (in big web pages, ViewState can be very big in terms of amount) So we have now for each ASP.NET control and also for Page ( Page is also a control ), "ViewStateMode=enabled,disabled,inherit" so we have more control over it.

  • More control on Client IDs. ASP.NET has produce Client IDs for html output sent to the client considering layout and containers of the specific controls. This is useful because we can't control all the ids of all controls (especially for controls in data binding containers) However when we try to work on these controls, whose name is not known by us, with JavaScript problems start to arise. For example, when we refer to a control like "document.getElementByID(controlID)" we can't do anything. ASP.NET 4.0 solves this problem with (control.clientIdMode -->> legacy,static,predictable,inherit(default)).  ( Static means "use the id I gave. I am responsible all errors) (Predictable means "give an id considering containers but in a more clear way)

  • Description and Keyword attributes for @Page for better search engine optimization.

  • Enhancements in web standards (xhtml standarts,accessibility standarts section508,wcag,aria) and checking them in VS2010.

  • A new ASP.NET control, QueryExtender, makes easy to query on entities that implements IQueriable

  • In ASP.NET 4.0 developers will be able to write their own custom cache providers.

  • Session state compression (out-of-proc) with GZip.

ASP.NET Ajax 4.0
  • New data binding features on client side by using templates like ASP.NET databinding controls.

  • jquery comes as part of the visual studio 2010

  • More enhanced Ajax Control Toolkit  (there is also client side libraries)


ASP.NET MVC
  • Comes as a separate, stand-alone framework

ASP.NET Dynamic Data
  • New controls and more control for developer


HEALTH MONITORING AND EXCEPTION HANDLING IN ASP.NET

clock June 27, 2009 07:11
Runtime exceptions and errors happen sometimes (or I should say always :) ), but end users don't need to know the details of them. Also showing internal details of the application may harm the security (gives hackers sensitive information). So websites should show user friendly error pages to users and save-log detailed technical information in an error message. To do so, we can configure web.config:

<customErrors mode="RemoteOnly" defaultRedirect="~/FriendlyErrorMessagePage.aspx">
    <error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>


In this example, for error "404" there is a specific page, and all other cases are addressed in "defaultRedirect" attribute of "customErrors". "RemoteOnly" means, when working in localhost, show the error page. But this is not enough. We should also have a system that saves technical details and inform the administrator about them. To take some action in "OnError" event in our code-behind files is a good option. A better approach is, rather than copying this code in every page, we can write a base page that inherits System.Web.UI.Page.
public class MyBasePage : System.Web.UI.Page
{
	protected override void OnError(EventArgs e)
	{
		//log the error-exception
	}

	//................
}
Another option is doing this in "Application_Error" event in "Global.asax.cs" :
void Application_Error (Object sender, EventArgs e)
{
	//log the error-exception
}
This approaches work but there is a full-scale mechanism in ASP.NET to get same functionality: instrumentation and health monitoring system. This system takes care of :

  • unhandled exceptions
  • lifetime exceptions (start of application, finish of application etc.)
  • audit events (failed or successful logins etc.)
  • .....
Instrumentation and health monitoring system is a framework and based on provider model design pattern. So we can log the details to SQL Server Database, the Windows Event Log, the WMI log, to mails or to Oracle RDMS by writing a specific provider for Oracle (by inheriting System.Web.Management.WebEventProvider).

Configuration setting of health monitoring is under <healthMonitoring> element of web.config

<healthMonitoring>
    <eventMappings>........</eventMappings>
    <providers>.................</providers>
    <rules>.......................</rules>
    <profiles>....................</profiles>
    <bufferModes>.............</bufferModes>
</healthMonitoring>


<eventMappings>........</eventMappings> registers the event classes so their types like:

<eventMappings>
    <add name="HeartBits" type="System.Web.Management.WebHeartbeatEvent,System.Web"  />
</eventMappings>


<providers>.................</providers> section registers providers:

<providers>
    <add name="SqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider,System.Web" ConnectionStringName="localSqlServer" />
</providers>


<rules>.......................</rules> is the place we actually define which events to log, which registered provider and how often. Now an example that HeartBits events to be logged to Sql Server:

<rules>
    <add name="HeartBitEvents" eventName="HeartBits" provider="SqlWebEventProvider"
</rules>



HOW TO USE CACHE AND CACHE DEPENDENCY ?

clock June 21, 2009 04:28

Using cache is an easy way to increase efficiency in programs. By using cache techniques we can store the data in RAM that is normally in harddisk or another stuff whose access time is much bigger than RAM's. In this article, I will write a method that gets the subdirectory names in a directory and return them to caller. ( this method can be used, for example, to populate theme names in a dropdownlist so that user can select her preferred style. .NET cache classes are in System.Web.Cache hence don't forget import it. ( by using statement ) Another important thing about cache is: how much time the info should reside in cache? Because if it losses its validity after some time, it is just a garbage and may decrease the efficiency. If cache information is deleted earlier than it normally would be, we can't rely on the cache. Therefore, to solve this problem we have CacheDependency objects that enable us bind info to a file in system file hierarchy and say: "When this file is updated then delete this specific cache information. Now see the code:

 	public static string[] GetThemes()
        {
            if (HttpContext.Current.Cache["SiteThemes"] != null)
            {
		    //if there is already cache info then just use it
                return (string[])HttpContext.Current.Cache["SiteThemes"];
            }

            else //when cache is empty
            {
                string themesDirPath = HttpContext.Current.Server.MapPath("~/App_Themes");
		    //map virtual file location to full one

                string[] themes = Directory.GetDirectories(themesDirPath);
		    //using System.IO features get all directories in a specific one

                for (int i = 0; i < themes.Length; i++)
                {
                    themes[i] = Path.GetFileName(themes[i]);
                }

                CacheDependency dep = new CacheDependency(themesDirPath);
		    //define a dependency on the directory "themesDirPath"

                HttpContext.Current.Cache.Insert("SiteThemes", themes, dep);    
		    //Here we insert the "themes" string array with the cache key
		    //"SiteThemes" and say that if "dep" dependency object
		    //warns you delete this key - value pair from cache

		    
                return themes;
            }
        }

Here information is stored as key - value pairs. ( key is "SiteThemes" string and the value is "themes" array ) In this code snippet, when directory "App_Themes" is updated then "SiteThemes"-"themes" key - value pair also deleted. What we benefit from this code is: we don't read content of "App_Themes" every time (means many IO costs) instead read it only when the method is first invoked.



MICROSOFT IS PUTTING ITS POWER BEHIND SEARCH ENGINE BING

clock June 21, 2009 02:06

Steve BallmerThis week Thursday, Microsoft Corp. Ceo Steve Ballmer said, Microsoft is willing to invest in Internet search business up to 10% of its annual income. "Our shareholders, I told them we were willing to spend 5 to 10 percent of operating income for up to five years in this business, and we feel like we can get an economic return" said Ballmer in a business conference. Bing has grabbed 12.1% of US internet searches for the week June 8-1, up from June 1-5. However, Google has 65% share in the market. When this was reminded to Ballmer, he answered, "You don't go from 8 percent to 80. You have to be patient, we invested in Xbox for years and now it generates nice economic returns for us," he added, referring to the company's popular gaming console. Microsoft has operating $4.4 billion  in last quarter means that for a quarter $440 million and per year $1.8 billion to develop and advertise Bing. 

I always thought that why Microsoft hasn't done so much in internet area not just in search engine but in all internet related areas, because everything shifts to internet: software, advertise, information with cloud computing etc. And I see the answer now as Ballmer said "If we could have one do-over I would probably say I would start sooner on search," said Ballmer. "Sometimes the error you make is what you don't do and don't see. Our mistake wasn't that we didn't see the technology change coming, we didn't see the business change coming."  [Reuters]

And Google CEO Eric Schmidt' s ideas about Bing:



MULTI - TIER SOFTWARE DESIGN

clock June 20, 2009 23:35

Multi-tier or n-tier software design is a buzzword in recent years. To recap it in few words, it divides functionality, components, and code for a projects. There are generally 4 of them ( some people define 3 tiers not mentioning data store) multi-tier

1. Presentation Layer: This is the user interface. In this tier, the code defines what a user should see on the screen. To do so, it invokes the lower tier and get the data, shape and format it, maybe cast it considering its specific purpose and present data to user. 

2. Business Logic Layer (BLL): The code that takes the data from data access layer ( generally in the form of relational data ) and exposes it to the Presentation Layer in a more abstracted and intuitive way, hiding low level details. ( such as database schema, constraints) Also this tier grants input validation and ensures that the input is safe and consistent.

3. Data Access Layer: The code that takes of retrieving and manipulating raw data in the data store. It gives commands to data store ( to an RDMBS ) to create, read, update and delete information. The developer that prepares this layer should have knowledge about exactly all internal details of database: its constraints, columns - their names and data types and specific information about how RDMS works.In .NET environment this can be achieved by ADO.NET 

4. Data Store: This is where the data resides. This can be a RDMS, an XML file, a text file.

In small projects these tiers can be united, for example BLL and DAL can be implemented in a single class. However, in big projects that many developers work, multi - tier design with each tier is independent from the other ones is a very important and ease the work much.



WHICH ONE IS BETTER FOR SITE LAYOUT: "DIV" or "TABLE"

clock June 20, 2009 07:45
Sometimes developers use HTML tables to control the positioning of items to create a layout in webpage. This is a very common practice but not the best one. Also W3C discourages it by saying that <table> should be used to mark up tabular data such as sign up pages with many fields but not to create page layout. To create a layout <div> tags with "css" features should be used. These are why:
 
1. By using <div> and a separate stylesheet then we don't need to repeat this definition. This leads a site that is both faster to develop and easier to maintain.
 
2. Seperate .css files are cached by the browser but not html tables. So when we use <div> with .css files we get much faster loaded web sites. This is much more important in heavily loaded websites because sending less few bytes with thousands of users means much more efficient bandwidth usage.

3. By using <div> and separate stylesheet we can define multiple different themes and style sheets that users can select by considering preferences. These preferences can be colors, pictures and layout of <div> tags. (at top, at right etc.) Especially when changing position of some columns using <table> (i.e. exchanging positions of left and right column) is much more difficult than manipulating <div> tags.

4. For different screen resolutions, especially for PDA's to adapt the output for them is very easy by defining different stylesheets. Also hiding some content (i.e. some banner) by <div> is much easier than <table>