Friday 6 November 2009

ASP.Net Keeping Session Alive

ASP.Net Time-out

We have a problem with a client with a slow network that does a file upload. This takes only a minute or some on our development network. The client IIS server has a timeout of 60 minutes. However, the file upload may take longer than 60 minutes, and the page times out before the operation is complete.

Looking into the mechanics of what is going on I have found the following:

IIS Time-out is controlled by 3 settings

Note: none of these can be set to zero, or indefinite. The value for the first two is in seconds.
  • ConnectionTimeout - How long since the link between the client and server is idle.
  • HeaderWaitTimeout - I don't understand this one, but it is to do with client requests
  • MinFileBytesPerSec - This measures the amount of data received at the client.

It seems the best approach is to find a way to tell the server that our page is actually still alive.
Here are two code examples of an approach to doing this:

The common logic to each of these methods is to have a small part of the page, such as a frame, automatically refresh before the page is due to expire. So if it should expire every hour, have it refresh every 50 minutes. The question in our scenario will be - will this work when part of the page is still waiting for SQL Server.

To handle this we need to do something like threading. In other words - send the page off to do some database work, and in the meantime, continue to be responsive.

This link shows how to do that Threading in ASP.Net

To achieve this in ASP.net, as well as understanding threading and automatic page refreshing we need to know how to use frames too. This is elementary to most web developers, but I am not a web developer!!.

To create a page with two frames I actually created 3 aspx pages. This is the key part of the code that appears on the parent page.

Refreshing Frames Individually

To refresh a frame manually, you can put code like this in the click event of a button, or some other event. This is client side javascript.

parent.frames[1].location.href=parent.frames[1].location;

To refresh a frame automatically, put this line in the head section:

<meta http-equiv="REFRESH" content="15" />

(This is the on-line application I used to convert html code into something that will display properly in a blog: www.felgall.com/htmlt47.htm)

To solve the problem with the client application that we have:
1) Rename the data load form
2) Create a new form with the name of the old dataform
3) Add a frameset to the new form, the old form will be the first frame in the frameset
4) Create a new form
5) Add the new form to the frameset
6) Add the automatic refresh feature to the new form.

NOTE:
The proof of concept still needs to show that this works in conjunction with a dataload taking place in another frame, and that it is sufficient to keep the session open.
Carry on from here on Thursday.


Wednesday 7 October 2009

Pie Chart Control

I found a nice pie chart control here: www.codeproject.com/KB/graphics/julijanpiechart.aspx.

To include this in one of my own projects this is the quick start method.

Copy the PieChart.dll into the solutions folder.
Go to toolbox and browse for the dll to add it.

Drag the piechart control to a form.

There are two sets of values that must be setup, otherwise an exception occurs.
Here is a sample of the most basic code:
Dim Vals(4) As Decimal
Dim Texts(4) As String
Texts(0) = "apples"
Texts(1) = "plums"
Texts(2) = "grapes"
Texts(3) = "cherries"
Try
Vals(0) = 45
Vals(1) = 20
Vals(2) = 75
Vals(3) = 45
Me.PieChartControl1.Values = Vals
Me.PieChartControl1.Texts = Texts
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try


This produces a odd looking pie chart. For nice charts some other settings should be changed too.

Setting up displacements give a chart that looks like this:


Displacements should have values like 0.05 and o.20


SliceRelativeHeight gives depth to the chart



These are the minimum settings to create a nice 3-D pie chart.

Tuesday 18 August 2009

Working of Office Docs within VB

When clients move to Office 2007 I have a new option for working with their documents.
The new xlsx and docx formats are based on the OpenXML standard. This means that these can be opened without office even being installed on the machine.

So my application could open and read the contents of these documents without having to use com. The number of problems and issues this would solve!
The technology to look into for this is Linq to XML

Tuesday 12 May 2009

SSIS Packages Saved to SQL Server

When creating an SSIS package through a wizard, one of the options when saving it is to save it to SQL Server. However, when you do this the package may appear to disappear and cannot be found. The answer to finding these packages again is in SQL Management Studio, choose connect and choose Integration Services from the list.











Then, in object explorer, open the Integration Services instance for the server and drill down to find the saved SSIS packages.

Thursday 26 March 2009

Creating ClickOnce Projects

It is quite easy to create ClickOnce projects. These are normal .Net projects that are built using the Publish option on the Build menu.

All the settings related to publishing a ClickOnce project are found on the Publish tab of the project properties screen.

The screen shot below shows the settings on the main screen.



The most important things to bear in mind are:
1) The publish location must be reachable from the development machine. This is the equivalent of the release folder in a normal build.
2) The install folder must be reachable from the client machines. This can be a web server or a network share (can also be a CD). You will copy the files to this location once they are published.
3) Click theUpdate button to bring up the update options screen. This is important because by default the update folder is the same as the publish folder. In reality it should be a location reachable by client machines.

The reason that the update and install locations are important, even though we will be copying the installation files to a specific location is because they are included in the application manifest and the deployment manifest.

It is possible to specify .Net Framework and certain other packages as prerequisites. However, not everything is supported here, so it may be necessary to install certain other things manually, or even edit the Publish.htm file to include links for them too.

On visiting the client site I encountered an error message "The application requires that assembly *** be installed in the Global Assembly Cache". This message related to SQL SMO.
As it happens, all the files required for SMO were already installed on these machines.

The answer is:go into the VB project properties page, publish tab, click application files.
Then for the files that will be installed separately and not updated as part of the clickonce package, change their setting from Prerequisite(Auto) to Include(Auto).





ClickOnce Deployment


This looks very promising, especially where an application does not need to deploy any files to the GAC (Global Assembly Cache). An example of .Net applications that deploy to the GAC would be those that use Microsoft Office PIAs (Primary Interop Asseblies)

However, there may be work arounds for this, such as installing PIA's separately.

This page gives a good walk through of ClickOnce deployment.

In visual studio, Build\Publish takes you to the simple publishing wizard.
When you publish, a set of folders and files is created that inclused Publish.htm.
This is the starting point for installing the ClickOnce application on the user's PC.
When choosing the local web server screen shot one shows the resulting folders\files that are created.
Opening Publish.htm gives this screen:


Click Install and this dialog follows:


As in my test scenario the application was not signed, this dialog appeared.

The application is not actually stored on the client machine. (At least not in the usual location, it is not is program files sub directory)

When an update is posted to the update location, and a user clicks on the application shortcut they will see this message. Note, the update has it's own version number system, and does not depend on the application version number.


Deploying ClickOnce Solutions On Client Sites
In the project properties\publish tab there are options that can be set that make it possible to have install and update locations that are different from the publish location.
On the main page there is an installation URL as well as a publish URL. Make the installation URL the location of the files on the client site. On the Update page, set the Update Location to the place on the client network where updates will be located. This can be the same as the publish URL.


Friday 6 March 2009

VB.Net Tracing

Use Trace is very much like Debug, but it allows you to  tracing on the client machine without visual studio.

I have created a class trace which can be used in any project, and writes basic information about the application and the user away to a config file.
This should be include in a project, and a start statement should be called during the application load.
The trace flag should be set to on in the project options.
Then anywhere in the application where I want to check a value, put Trace.WrineLine("")

Tuesday 24 February 2009

SQL Server Debugging

I have tried this out today and to be able to step through a stored procedure after it has been called by a .net application is fantastic. This can save so much time now I know what to do.

The key to this is the server explorer in Visual Studio - I should be in the habit of always setting up a connection to SQL server when working on a database project.

Four steps:
1) Attempt to step into a stored procedure and receive warning that certain opptions have to be set on the machine. OK this and it will do it automatically. (I did not get the exact messagage)
2) In Project properties, debug tab,  Check "Enable SQL Server Debugging"
3) In server explorer, right click and open a stored procedure. Set a break point
4) In connection strings, add Polling=false; to string

The the application branches into the stored procedure you can step through it like any other piece of code, even inspecting values of TSQL variables within the procedure.

This could save a lot of time if I get used to these steps.

I need to watch that I have a means of setting connection polling only for testing, and having a different setting for the released versions of the code.
One possibility is to check processes to see if visual studio is running. Then only have pooling set to true if it is not, otherwise explicitly set it to false.

This works at Scotts but not on my home PC, I need to troubleshoot this because this functionality is so useful. You can even step through stored procedures on their own.

Wednesday 18 February 2009

Exporting to CSV, Opening In Excel, Special Character Problem

When creating a csv file from VB.net, then opening this file in Excel using the file association method (ie process.start(file.csv)) special characters such as Nestlé are not recognised by MS Excel. Instead it is shown as Nestlé 
When opening the same CSV file in notepad the foreign characters are shown correctly.

However, if the Import feature is used in Excel, and the encoding is specified as UTF-8 then the data is displayed correctly.

By default, the vb.net streamwriter will use UTF-8 encoding. 
In UTF-8 the two-byte sequence 0xC3 0xA9 = é
In Windows-1252 0xC3 0xA9 = Ã©

To solve this problem I could write the data as an Excel file using COM. However, this ties the application to a particular version of Office and could break if the company upgrades from Office 2003 to 2007.
Instead I have changed the encoding within vb.net.
stwriter = New StreamWriter(File.Create(FilePath), System.Text.Encoding.UTF32)
Using UTF32 did cause Excel to handle foreign characters correctly, although at the cost of automatically splitting the data into columns. 
The TextToColumns feature I added into a macro that automatically selected the first column, split the data into columns and autofit the columns to the contents.