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);
    }
}


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.



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.



.NET IO - 2 ( Reading from and Writing to Files )

clock June 19, 2009 21:16
We are continuing from where we left in System.IO. (for the first article click) In .NET IO to write or read, we should use a stream or specific stream classes that extends abstract base class Stream. For example:

  • System.IO.FileStream
  • System.IO.MemoryStream
  • System.Net.Sockets.NetworkStream
  • System.IO.BufferedStream
In this article I'll use System.IO.FileStream to read from and write to a file. Let's look at this code:
 FileStream fs = new FileStream(Server.MapPath("example.txt"), FileMode.Open);
 //By using FileStream, we start to read the file. "FileMode.Open" means that this
 //file will be used just for reading not another operations. Other possible values are:
 //Append,Create,Truncate,CreateNew,OpenOrCreate 

byte[] data = new byte[fs.Length]; fs.Read(data, 0, (int)fs.Length);
//we read the whole file by "from 0 to fs.length" 

foreach (byte k in data) 
{ 
    Response.Write(k.ToString()); 
} 
//and we send the result to the user 
When we run this example, we can get some meaningless results. The reason is "FileStream" gives us the result as "byte". If we don't want to transform these bytes to human-readable form, we should use "System.IO.StreamWriter" and "System.IO.StreamReader".
StreamWriter writer = new StreamWriter(File.Open(Server.MapPath("enes.txt"), FileMode.Open)); 
//file.open() -->> creates a filestream for streamwriter 
writer.Write("write to the file");
writer.Close(); 

////////////////////////////////////////////////////////// 

StreamReader reader = new StreamReader(File.Open(Server.MapPath("enes.txt"), FileMode.Open));
Label1.Text = reader.ReadLine(); 
reader.Close(); 
"System.IO.StreamWriter" and "System.IO.StreamReader" creates "System.IO.FileStream" themselves (so we don't need to create them)  "Label1.Text = reader.ReadLine(); " enables us to read file line by line. If we wanted to read whole file as a single chunk, we would write  "Label1.Text = reader.ReadToEnd(); " Besides these methods there are other static methods in System.IO that allows us carry out these operations easier:
 string k = File.ReadAllText(Server.MapPath("enes.txt")); 
and
 File.WriteAllText(@"C:\temp.txt",data); 


COMPRESSING HTTP OUTPUT WITH AN HTTPMODULE

clock June 12, 2009 19:55
The communication between Server and Client is carried out via HTTP messages by sending necessary data. The workload of server and net speed is exactly how much time this messages requires to be sent. Therefore, to decrease message ( by using compressing algorithm and techniques ) size means higher speed and efficient bandwidth. Almost all new browsers can use "gzip" and "deflate" compression algorithms. ( they can decompress messages that comes from server) ASP.NET gives us compressing ability.

We will use "HttpModule" in this article. First create a Windows Class Library in C#.

Note: HttpModule' s are the controls that manipulates Request and Response messages. 



Name project as "CompressionModule" and with same name add a new class. Right-Click to the project, select "Add Reference" , browse "System.Web". Then write below code  :
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Web;  
  
namespace ZipModule  
{  
    //to get HttpModule capabilities implement "IHttpModule" interface
  
    public class CompressionModule : IHttpModule    
    {  
 
        #region IHttpModule Members  
  
        public void Dispose()  
        {  
            throw new NotImplementedException();  
        }  
  
        public void Init(HttpApplication context)  
        {  
            context.BeginRequest += new EventHandler(context_BeginRequest);  
        //besides default event handler we should write our custom one
        //context -->> current application that invokes our HttpModule
        }  
  
        void context_BeginRequest(object sender, EventArgs e)  
        {  
            HttpApplication app = (HttpApplication)sender;  
        //name this application as sender
  
            string encodings = app.Request.Headers.Get("Accept-Encoding");  
        //"Accept-Encoding" is the Http Header that informs us
        //whether the browser can use encoding algorithms
  
            if (encodings == null) //if it can't return
                return;  
  
            Stream s = app.Response.Filter;  
        //if can filter the response message
  
            encodings = encodings.ToLower();  
  
            if (encodings.Contains("gzip"))  
            {  
                app.Response.Filter = new GZipStream(s, CompressionMode.Compress);  
            //here is the core of the code
	//we zip the code here  
              
                app.Response.AppendHeader("Compression Tecnique", "gzip");  
            //we add a header to message so that we will be able
            //trace whether our module is working or not
          
                app.Context.Trace.Warn("GZIP Compression on");  
            }  
  
            else  
            {  
                app.Response.Filter = new DeflateStream(s, CompressionMode.Compress);  
            //if browser can't use "gzip" compress the message 
	//with "deflate"  
              
                app.Response.AppendHeader("Content-Encoding", "deflate");  
                app.Context.Trace.Warn("Deflate compression on");  
            }  
  
        }  
 
        #endregion  
    }  
}  
Build the project, copy the "ZipModule.dll" from "bin" directory. Add this .dll to your new website. Again like we did above right-click the website name and browse the "ZipModule.dll" and select it. To use this HttpModule we should configure "web.config" :
<httpModules>
    <add name="HttpCompressionModule" type="ZipModule.CompressionModule"/>
</httpModules>
<trace enabled="true"/>

By writing "<trace enabled="true"/>" we can trace our application and see exactly what happens in Request and Response messages. After making above configuration settings our HttpModule should work and compress the Http Messages. In browser url part, write "../Default.aspx/trace.axd". Click "View Details", if you see "Gzip compression on" ( like below snapshot ) then your HttpModule is working and you can send compressed Http Messages.  Congratulations.....
 


HOW TO MAINTAIN SCROLL POSITION AFTER PAGE REFRESH, POSTBACK?

clock June 12, 2009 08:51
In ASP.NET, after PagePostBack is done, to maintain the scroll position can be quite important in long web pages. ASP.NET gives us 3 methods to do this. They are:

       1. In Web.config :

               <pages maintainScrollPositionOnPostBack="true">

       2. In single Page :

              <%@ Page MaintainScrollPositionOnPostback="true" ...

       3. Programatically :

              Page.MaintainScrollPositionOnPostBack = true;


.NET IO - 1 ( Creating and Deleting Files and Directories and Listing subfiles and subdirectories )

clock June 10, 2009 07:13
There are advanced classes in .NET for IO processing. Even though we have some classes that allow us to carry out low level IO operations, we can usually do our work with several static methods. Now let's see how a directory and a file is created, deleted and how directory hierarchy in a disk volume or in a directory can be displayed in tree view. Although IO operations are same in all .NET projects, to make easier our article I use ASP.NET. Hence you can easily copy and paste code below in, for example, WPF. Classes, we will use, are:

  • DriveInfo
  • DirectoryInfo
  • FileInfo
  • Directory
  • File
To create a directory or file
Directory and File classes in System.IO namespace allow us to create and delete directories or files:
Directory.Create(@"C:\exampleDirectory");
Directory.Delete(@"C:\exampleDirectory");
If we want to work on files and directories in current project folder, 
Directory.Create(@"Server.MapPath("exampleDirectory"));  
Directory.Delete(@"Server.MapPath("exampleDirectory"));  
we can use. When operating on files, use File class:
File.Create(@"C:\exampleFile.doc")
File.Delete(@"C:\exampleFile.doc")
or
File.Create(@"Server.MapPath("exampleFile"));  
File.Delete(@"Server.MapPath("exampleFile"));  
Now let's work on displaying directory and file hierarchy in treeView like "windows explorer" style. We will use these classes:

  • System.IO.DriveInfo        //allows us to access the name, available space, total space etc. of a disk volume
  • System.IO.DirectoryInfo    //allows us to access the name, available space, total space etc. of directory
Create a new site, add TreeView and wrote below code in Page_Load event:
rotected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            System.IO.DriveInfo drive = new System.IO.DriveInfo(@"D:\"); 
            //work on local disk D
            TreeNode node = new TreeNode(); 
            //we create TreeNode's dinamically

            node.Value = drive.Name;  
            TreeView1.Nodes.Add(node); 
            //add local disk D to main node

            loadDirectories (node, drive.Name);//in this recursive method,
            // we pass name and full address of the local disk 
            // as parameters            
        }
    }

    private void loadDirectories(TreeNode parent, string path)
    {
        System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(path); 
        //now we don't work on drives but directories

        try
        {
           //with  GetDirectories(), we get all sub directories
            foreach (System.IO.DirectoryInfo d in directory.GetDirectories()) 
            {
                TreeNode node = new TreeNode(d.Name, d.FullName);                

                parent.ChildNodes.Add(node);  

                //call the same method (call "loadDirectories()" recursively )
                loadDirectories(node, d.FullName);        
            }
        }
        catch (System.UnauthorizedAccessException e)
        {
            parent.Text += "(acces forbiddeni)";
        }

        catch (System.IO.IOException e)
        {
            parent.Text += "(unknown error hata: " + e.Message + ")";
        }   
    }
We displayed just content of volume D by writing ?System.IO.DriveInfo drive = new System.IO.DriveInfo(@"D:\");". If we wanted to display all files and directories in computer hard disk, we would write:
protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            foreach (System.IO.DriveInfo drive in System.IO.DriveInfo.GetDrives())  
            //to work on all volumes
            {
                TreeNode node = new TreeNode();
                node.Value = drive.Name;

                if (drive.IsReady)
                {
                    node.Text = drive.Name;
                    loadDirectories(node, drive.Name);
                }                            

                TreeView1.Nodes.Add(node);
            } 
        }
}
The code below takes several minutes. As you can estimate,  our recursive method "loadDirectories()" needs many IO operations.

Now add a GridView to the project. We want to select a file from the TreeView we just created, and see alll subfiles and subdirectories with their name, space, last access time etc. Select SelectedNodeChanged event in "Properties Window" after clicking on TreeView and write the code below.
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
    {
        DirectoryInfo directory = new DirectoryInfo(TreeView1.SelectedNode.Value);

        GridView1.DataSource = directory.GetFiles();
        GridView1.DataBind();
    }
We learned how to create and delete files and directories and displaying all subdirectories and files in a disk, hierarchically in a TreeView.


BUILDING AND CONSUMING XML BASED WEB SERVICE

clock May 6, 2009 18:50
Building a Web Service means creating a class and expose this class's some methods to web so that a client can consume this web service.To do so create an ASP.NET Web Service in VS2008 by selecting File > New > Web Site and select ASP.NET Web Service. (We will get a data set from a remote machine)

 
Now in solution explorer you have a service.asmx file. Delete it and add a new file to your project.Select Web Service, name it as "Customer.asmx".



Write this code to your Customer.cs in your App_Code directory. 
[WebMethod] //expose our method to the web
public DataSet GetCustomers()   //method to get dataset from a database
{
     SqlConnection conn;
     SqlDataAdapter adapter;
     DataSet result = new DataSet();
     string cmdString = "SELECT * FROM [SELECT * FROM SalesLT.Customer]";  //command string
     conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AdventureWorks"].ConnectionString);
     adapter = new SqlDataAdapter(cmdString, conn);
     adapter.Fill(result);  //our sqladapter fills the data set
     return result;  //return resulting dataset
}    
Now view in the browser our Customer.asmx You will see ASP.NET's specific page for Web Services.

Click GetCustomer() method.There is SOAP messages and also an invoke button to invoke the WebService.You can check whether the webservice is working or not. At this point we can consume this webservice.Create another ASP.NET website and right click on the project name.Select "Add Web Reference"
 
 
In URL part copy your asmx file's URL. In web reference name part, write Customer Service.Click "Add Reference" Now VS2008 has created necessary classes in the second website to work with web reference.In Default.aspx page add a button a GridView.In click event of button write:
protected void Button1_Click(object sender, EventArgs e) 
{
    CustomerReference.Customer ws = new CustomerReference.Customer(); 
    //CustomerReference is the name we defined when adding Web Reference
    GridView1.DataSource = ws.GetCustomers(); 
    GridView1.DataBind();
}

If there is no exception, when we click the button we should see the results.:)