środa, 25 maja 2011

Webfarm web servers configuration - Part 1 of 3 - session storage

Today I wanted to share with you my expierience in configuring ASP.NET MVC website running on 2 web servers.

Web servers are going to be configured on 2 servers running on Microsoft Windows Server 2008R2. The net balancing will make the website be served from either server A or server B.

 

The first of 3 parts will cover configuring the session to be available across two machines.

Because the user may be switched from webserver A to webserver B we need to make sure that the same session is available on both Webservers.

 

According to msdn source http://msdn.microsoft.com/en-us/library/ms178586.aspx there are few modes of session state:

·         In-Process Mode – (default) the session is stored within the web server worker process. So for 2 werbserers we’d have 2 different places that the session would be stored at – won’t work

·         State Server Mode – the session state in a process which is separate ASP.NET worker process. This mode ensures that the state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm

·         Sql Server Mode – similar to State Serever Mode, but the data stored in session is stored in sql database.

I’ve chosen the State Server Mode, because as I found in some forum it’s quicker than Sql Server State storage.

 

The configuration that needs to be add

 

To start with I’ve decided to configure it locally to give it a quick test.

After setting this in web.config  system.web section
<sessionState mode="StateServer"

                  stateConnectionString="tcpip=localhost:42424"

                  cookieless="false"

                  timeout="20"/>

In live environment you’ll have to replace localhost with the IP address of the server where the ASP.NET State Service is running.

I got following error:

Server Error in '/' Application.

Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same.  If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection.  If the server is on the local machine, and if the before mentioned registry value does not exist or is set to 0, then the state server connection string must use either 'localhost' or '127.0.0.1' as the server name.

This is because the State Server wasn’t enabled on my machine. To enable it you have to go to AdministrativeTools > Computer Management > Services and Applications >Services and start the ASP.NET State Service

Then following error came out:

Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.

This is because all the objects stored in State Server session must be serializable and in my case these weren’t.

After making objects stored in session serializable (adding attribute to the class definitions) it worked for me.

 

So in web farm configuration you only need to configure ASP.NET State Service on one server and use it from both applications on both web servers.  

 

That’s all for the first part. In second part I’ll write about problem with keeping users signed in across two webservers.

poniedziałek, 31 stycznia 2011

Few notes

These are just few notes, hopefully I'll have a minute soon to explain why do I post it here. Problem 1: 2 linked servers with different logins causing following error: OLE DB provider "MSDASQL" for linked server returned message "[Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user .... Solution:
EXEC sp_addlinkedsrvlogin 'server1', 'false', NULL, 'user', 'test'

wtorek, 20 kwietnia 2010

Quick T-SQL tip: Insert image into db using SQL statement

The goal of this quick post is to show how to insret image into database cell using sql statement. Here is the table that we insert the row into.

The cell is type of image, but the actual data stored inside of it is binary. Here is the insert statement that you can use to insert row into that table:
INSERT INTO MsMailTemplateImages(ContentID, Image, MsMailTemplateID) 
SELECT 'greentree' as ContentID, BulkColumn, 1 as MsMailTemplateID FROM 
OPENROWSET(BULK N'C:\Downloads\environmental.gif', SINGLE_BLOB) as DATA

czwartek, 11 marca 2010

Visual studio QuickReplace using Regular Exporession [Regex]

I don't have to persuade anybody that using regex saves a lot of time. Recently I was about to add 20 new parameters to the stored procedure updating record. The reason for that was the change in table definiton. I had to make following steps: 1) add new parameters to sp, 2) add this parameters to update statement 3) add this parameters to insert statement I could use copy and paste, because all three steps needed only some changes withing string with new columns. 1) The sample from input sql I had to write for sp Input params
@CategoryL3 nvarchar(50), @CategoryL4 nvarchar(50),
2) The sample from update statement
[CategoryL3]=@CategoryL3, [CategoryL4]=@CategoryL4,
3) The sample from insert statement
[CategoryL3], [CategoryL4] 
and then:
@CategoryL3, @CategoryL4 
Here is regex to find things from first sample:
[@]{.[^@ ]*} .[^@ ]*,
- in {} brackets we get the expression we want to extract from what has been found.
I'm looking for:
- @ at sing
- ".[^@ ]* "- all the signs (.*) until space (which is after star) that don't contain @ sign
- then there is space and anything thats between this space and comma, but again without @ sign (to avoid greedy results) .[^@ ]*


then in replace with text box I can put \1 which result with setting it to the values I enclosed with curly brackets.

wtorek, 9 marca 2010

Adding new parameter to WebReport (asp.net 2.0 sql server 2005)

The situation is as follows: we have existing WebReport which users stored procedure for getting data. We want to add new parameter. 1) Alter stored procedure to expect new paramter 2) In the layout tab in report designer go to menu Report => Report Parameters and add new parameter. Img. 1: CustomerIds - new parameter

Initially I thought it's enough, and you can imagine how supprised I was when trying to preview report I got an error: procedure expects parameter which was not supplied. I spend more than half an hour to figure out what caused my problem. There is third step you have to make when adding new param. 3) On dataset properties Parameter tab you have to enter the input parameter of the sp for 'name' and select report parameter under value. Img. 2: 3rd step.

That's it.

piątek, 5 marca 2010

dropdownlist has a SelectedValue which is invalid because it does not exist in the list of items

Enviroment: You've got a FormView or some other data control which displays single item and allows edit it. In edit mode there's a dropdown list with available names that user can select value from. Then when user wants to edit a person the underlaying data for selecting name has changed and has no more an item with value for edited person. (This can happen when for example someone deletes a name record directly in the db) That situation will cause "dropdownlist has a SelectedValue which is invalid because it does not exist in the list of items" error being thrown, because we've binded dropdownList.SelectedValue to an item which isn't in db any more. The workoround is to delete SelectedValue binding in aspx code and and handle unexpected situation in FormView_PreRender event. Here's a code for that:
protected void FormView1_PreRender(object sender, EventArgs e)
    {
        if (FormView1.CurrentMode == FormViewMode.Edit)
        {
            DataRowView rowView = (DataRowView)(FormView1.DataItem);
            DropDownList ddlNames = FormView1.FindControl("ddlNames") as DropDownList;
            bool isItemStillThere = ddlNames.Items.FindByValue(rowView["NameID"].ToString()) != null;
            if ((rowView != null) && isItemStillThere)
            {
                ddlNames.SelectedValue = rowView["NameID"].ToString();
            }
        }
    }
The aspx code:
 
Test website:

środa, 10 lutego 2010

Restoring Database in SQL Server 2005

This is quick tip explaining how to restore database in SQL Server 2005. The new database had different schema than the one I wanted to restore data to.
This is the sql Generated by Sql management studio:
RESTORE DATABASE [DatabaseName] 
FROM  DISK = N'C:\temp\db\DBBackup.bak' 
WITH  FILE = 1,  NOUNLOAD,  STATS = 10
GO

Unfortunately it running it couses an error: Error 3154: The backup set holds a backup of a database other than the existing database.
All you need to do is to add parameter REPLACE. this is how new query looks like:
RESTORE DATABASE [DatabaseName] 
FROM  DISK = N'C:\temp\db\DBBackup.bak' 
WITH  REPLACE, FILE = 1,  NOUNLOAD,  STATS = 10
GO