Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (0)

I have been working in a Load balancer for a web server, with the news of IIS 7 I stop the project and I’ll start working in the new Load Balancer for IIS7.  http://forums.iis.net/thread/1297689.aspx

 

You can find the control if you want to play with it at

http://alpascual.com/control/loadbalancer.htm

This is a great load balancer without using any hardware, only issue, you are going to need to dns every computer with a different name:

www1.domain.com

www2.domain.com

www3.domain.com

 

Please any feedback will be very helpful to develop my next control for IIS7.

 

IIS7 comes with a great API to allow developers to get control of the web server, something that all of us have been waiting for a very long time. This is the link to develop modules for IIS 7: http://www.iis.net/default.aspx?tabid=2&subtabid=25&i=942

There is also an API for C++ : http://www.iis.net/default.aspx?tabid=2&subtabid=25&i=938

 

So no more interrogating the metadata of IIS6 or making requests to check if the server is down.

 

Cheers

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (4)

I have been working in a Load balancer for a web server, with the news of IIS 7 I stop the project and I’ll start working in the new Load Balancer for IIS7.  http://forums.iis.net/thread/1297689.aspx

 

You can find the control if you want to play with it at

http://alpascual.com/control/loadbalancer.htm

This is a great load balancer without using any hardware, only issue, you are going to need to dns every computer with a different name:

www1.domain.com

www2.domain.com

www3.domain.com

 

Please any feedback will be very helpful to develop my next control for IIS7.

 

IIS7 comes with a great API to allow developers to get control of the web server, something that all of us have been waiting for a very long time. This is the link to develop modules for IIS 7: http://www.iis.net/default.aspx?tabid=2&subtabid=25&i=942

There is also an API for C++ : http://www.iis.net/default.aspx?tabid=2&subtabid=25&i=938

 

So no more interrogating the metadata of IIS6 or making requests to check if the server is down.

 

Cheers

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (4)

Http Modules in ASP.NET 2.0 makes live so easy to separate the HTTP layer from the UI. You can add as many HTTP Modules as you require or add modules inside only one HTTP Module. Useful ones are:

 

Compressing the response back to the browser. When using IIS 5 this is a great module to add in all your solutions.

Easy URL paths. Used by forums.asp.net.

Installing a new Session Manager, copywriter notice, etc …

 

This is the skeleton of an HTTP. As you can see you need to inherited from IHttpModule so will create the functions Dispose() and void Init(HttpApplication context); for you.

 

 

Lets look at a compression HttpModule:

 

class AlHttpModule : IHttpModule

    {

 

        public AlHttpModule()

        {

 

        }

 

        #region IHttpModule Members

 

 

        public void Dispose()

        {

            // Clean any resources you may used

        }

 

        public void Init(HttpApplication context)

        {

            context.BeginRequest += new EventHandler(context_BeginRequest);

        }

 

        #endregion

 

        public void context_BeginRequest(object sender, EventArgs e)

        {

            HttpApplication app = (HttpApplication)sender;

 

            string encodings = app.Request.Headers.Get("Accept-Encoding");

 

            // No encodings stop the HTTP Module processing

            if (encodings == null)

                return;

 

            if (app.Request.Url.AbsolutePath.IndexOf(".aspx") == -1 &&

                app.Request.Url.AbsolutePath.IndexOf(".asmx") == -1 )

                return;

 

            Stream baseStream = app.Response.Filter;

 

            encodings = encodings.ToLower();

 

            if (encodings.Contains("gzip"))

            {

                app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);

                app.Response.AppendHeader("Content-Encoding", "gzip");

            }

            else if (encodings.Contains("deflate"))

            {

                app.Response.Filter = new DeflateStream(baseStream, CompressionMode.Compress);

                app.Response.AppendHeader("Content-Encoding", "deflate");

            }

        }

    }

 

 

As you can see .Request.Url.AbsolutePath is where everything happens. You can create a simple easy URL path like used by http://forums.asp.net by just looking at Request.Url.AbsolutePath and using Server.Transfer() to the right page. So people can browser to http://domain.com/1244 and you can convert that to Server.Transfer(“http://domain.com/Page.aspx?id=1244”);

 

Cheers

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (1)

So Microsoft deploys Visual Studio 2005, we are all so exited but in the process we all complain about all those DLLs into the bin file. Well not a problem, fast as a bullet Microsoft releases the Web Deployment Projects. Something else to download in your computer as an add-in or service pack :-)

Well all the intructions to download it and install it. Please make sure you close all versions of VS2005:

http://download.microsoft.com/download/c/c/b/ccb4877f-55f7-4478-8f16-e41886607a0e/WebDeploymentSetup.msi

Now read how to use them:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/web_deployment_projects.asp

So let's start with the problems; once you create the project, you 'll find the internally VS2005 uses aspnet_merge.exe, great tool as we are going back to the same thing that VS2003 worked, add every aspx.cs into a common DLL. You may encounter errors like: “error MSB6006: "aspnet_merge.exe" exited with code 1“ Personally my favourite. What does it mean? Well I can let you know you can find out by changing your  build outpout verbosity. To do so, Tools/Options go to Projects and Solutions, / Build and Run and the last drop down change it to Diagnostic.

Or I can let you know that 2 modules are using the same .cs file. Guess witch ones, or better check the debug after the verbosity is that high.

After you finish fixing all “collisions“ you may find the deployed website with a DLL names “ProjectName“_deploy.dll

There are a few more errors, but I learn that using the diagnostic high I can resolve many of them, if you leave the diagnostic low, the error message will not allow you to find what the problem is.

Please make sure you send me any other error message that the compiler message error does not give you enough information.

Cheers

Al

Best material to read: http://weblogs.asp.net/scottgu/archive/2006/05/08/VS-2005-Web-Application-Project-V1.0-Released.aspx

 

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (2)

How to uninstall SQL 2005 CTP and install the real thing without “many” problems.

Please make sure you uninstall the SQL 2005 CTP in this order so no component will be left behind, failing in doing that will cause the new SQL 2005 to complain and not wanting to be install.

Even if you follow this order some registry keys may be left behind, dining you the new installation to proceed.

 

1 – Uninstall SQL Native Client and SQL

2 – Uninstall SQL Server Support Files

3 – Uninstall any other development component on the Remove Program that you see

4 – Uninstall .Net framework 2.0 Beta

 

After this process you can go ahead and install the new SQL 2005, if still complains about any product install in your computer and you cannot see it on the Add/Remove program, open the registry and go to:

 

HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Installer/UserData/[UsernameorNumber]/Products

 

Check every single key for Product Name, if says SQL you should deleted. After that, try to install SQL, should not give you any warnings.

 

Cheers

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (0)

After putting it off for a long time I stated working on a new Data Layer. I wanted to know what DataLayer will be better against a SQL 2005. I decided to create an abstract class call DatabaseManager:

 

public abstract class MasterDatabaseManager : IDatabaseManager

    {

        public abstract void Close();

 

        public abstract int GetNonQuery(string sQuery);

 

        public abstract System.Data.SqlClient.SqlDataReader GetQuery(string sQuery);

 

        public abstract DataTable GetQueryPaging(string sQuery);

 

        public abstract DataView GetQueryPagingDataView(string sQuery);

 

        public abstract void Dispose();

     

    }

 

Then I added 2 classes with this base class. MicrosoftDatabaseManager and OldDatabaseManager.

 

Microsoft Database Manager uses Microsoft.Practices.EnterpriseLibrary.Data.Sql library, mine just uses the old System.Data and System.Data.SqlClient;

 

Comparing a function to clarify:

 

Microsoft:

public override System.Data.SqlClient.SqlDataReader GetQuery(string sQuery)

        {

            SqlDatabase dbSvc = new SqlDatabase(m_sConnectionString);

 

            DbCommand dbCommand = dbSvc.GetSqlStringCommand(sQuery);

 

            return ((SqlDataReader)dbSvc.ExecuteReader(dbCommand));

        }

 

Mine:

public override SqlDataReader GetQuery(string sQuery)

            {

                  SqlConnection myConnection = new SqlConnection(m_sConnectionString);

 

                  SqlCommand myCommand = new SqlCommand(sQuery, myConnection);

                  myCommand.CommandTimeout = 120;

                  myConnection.Open();

 

                  SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

 

                  m_myConnection = myConnection; // The class will close the connection

 

                  return result;

            }

 

So I created a class to test it with:

public class DatabaseManager : IDatabaseManager

    {

        enum DataLayer

        {

            OldSql = 1,

            MsSql = 2

        }

 

        MasterDatabaseManager m_oMan = null;

        DataLayer m_oLayer = DataLayer.MsSql;

        Stopwatch m_oWatch = new Stopwatch();

 

        public DatabaseManager()

        {

            BuildDataLayer();

 

            if (m_oLayer == DataLayer.MsSql)

                m_oMan = new MSDatabaseManager();

            else

                m_oMan = new OldDatabaseManager();

        }

 

        public DatabaseManager(string sConnectionString)

        {

            BuildDataLayer();

 

            if (m_oLayer == DataLayer.MsSql)

                m_oMan = new MSDatabaseManager(sConnectionString);

            else

                m_oMan = new OldDatabaseManager(sConnectionString);

        }

 

        private void BuildDataLayer()

        {

           

            if (ConfigurationSettings.AppSettings["DataLayer"] != null)

            {

                int iLayer = Int32.Parse(ConfigurationSettings.AppSettings["DataLayer"].ToString());

                m_oLayer = (DataLayer)iLayer;

            }

        }

 

        #region IDatabaseManager Members

 

        public void Close()

        {

            m_oMan.Close();

        }

 

       

        public System.Data.SqlClient.SqlDataReader GetQuery(string sQuery)

        {

            m_oWatch.Start();

            System.Data.SqlClient.SqlDataReader oTemp = m_oMan.GetQuery(sQuery);

            m_oWatch.Stop();

 

            Debugger.Log(1, "DataLayer", "DatabaseManager: " + (m_oWatch.ElapsedMilliseconds) + sQuery + "\r\n");

           

            m_oWatch.Reset();

           

 

            return (oTemp);

        }

 

This way just changing the member m_oLayer I could run some numbers. I added them in an excel file after every run. And after more than 10 runs I gave up as the numbers were very different running always the same queries.

 

The numbers are very similar between Data Layers, some times MS was the winner by a few milliseconds, sometime I was the winner for a few milliseconds. I believe that I would never know witch one is faster as SQL 2005 is taking care of making the bentchmarks a little difficult.

 

What I got set up know is a abstract class where I can add as many layers as I can, so if you can use my Iterface, send me your DataLayers and I’ll run them in the test. I’ll be also writing a new one to improve UPDATES in batches, but this is another story ….

 

Cheers

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (5)

How many issues were fix with 1.1 from 1.0 and are coming back on 2.0? Do we need 2.1? I don't have any doubt that Microsoft is going to release 2.1, actually they planned to do so before they ever ship 2.0. I have been finding a few issues that I haven't seen since the 1.0 version.

Now in version 2.50727 I am looking at the new exception:

System.Web.HttpException: The client disconnected. ---> System.Web.UI.ViewStateException: Invalid viewstate.

Client IP: xxx.xxx.xxx.xxx

Port: 37907

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705; .NET CLR 1.1.4322)

ViewState: (deleted here)

So, I look at the old support pages on 1.0 to fix it without much success:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;829743

I have also created a machine name still with the same result :-(

The only solution that works is to disable the ViewState and find another way to store the data between requests. I'll be writing a solution, so keep an eye on this blog if you are having the same problem, also you are very welcome to post your exception here.

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (1)

I configured my first web farm. I added as many IIS servers as I could. Now I have been looking the best way to keep the session states as fast as I can. Out of the box Microsoft provides this Session States:

 - InProc: Memory of the local computer, fast yet not persistent

- StateServer and SQLServer are for web farms, however you need to modify your machine.config or web.config in order to make them work in a web farm enviorement. I used this article to do so:

http://support.microsoft.com/default.aspx?kbid=312906

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/paght000007.asp

Now, my thought was, did anybody improved over this? So you can scale better with web farms? I look on the web and this is want I found:

http://www.scaleoutsoftware.com/ssdownload/pricing.html

So $1,500 for 2 servers up to $49,995 for 64! Are they crazy? What about more than 64 computers?

Anyway, so I started writing my own Windows Service to store Sessions. Any tips or recommendations are welcome, very welcome. Please keep an eye into this blog, I'll be releasing my State Server very soon.

Al

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (0)

Install an 2.0 web app in IIS 6 and the process pool was going down every 5 minutes with the wonderful red label that we all hate learn to love.

What to do next, I check the Event View to find some Hex there. Install debuggers for IIS without any sucess. At the end I had to enable legacyUnhandledExceptionPolicy on the asp.net config file. I learn from this article that you can actually put it on the app.config file:

http://www.julmar.com/blog/mark/PermaLink,guid,f733e261-5d39-4ca1-be1a-c422f3cf1f1b.aspx

Now I know there is a problem in my application, but what kills me is that I won't be able to find it if is “so quiet“.

I am writing a HttpModule to detect it, if I find the error I'll be posting it here. I cannot believe that Microsoft does not raise the exception and output the error on the browser instead, goes into a event viewer in plain hex.

 

Tags: | Categories: Blog Posted by admin on 3/9/2009 5:54 PM | Comments (1)

So I created a new control to help to send emails and make sure you don't “lose” any emails.

There are awesome features for this control. The most important ones are:

Cluster support: Allows you to add as many mail servers to send emails and will load balance between them until sends the email.

All emails will be sent: If the email cannot be send, the control will try for 24 hours per default to send the email.

Broadcast Email: Queues all emails into a master queue and load balances to different mail servers. If they fail, they are queue into a retrying queue. All errors and emails are accessible. All emails will be retry multiple times using different SMTP servers.

Email Tracking: When the user opens the email, will call back into a page on the web.

I'll be adding many different features. Hopefully this control will grow to be a good replacement for list servers. You can download it and try it at:

http://alpascual.com/control/bettermailmessage.htm

Please let me know how it works and what improvements I can add into it.

Thanks

Al