Friday, November 16, 2007

BLowery Compression module and Visual Studio Webserver (Cassini)

We have been using the HTTPCompress module (BLowery), and when running your web site in development mode using the built-in web server in Visual Studio 2005 you can get the error "Server cannot append header after HTTP headers have been sent." in cases where you want to do a Response.Flush (e.g. for downloading a file to the client).
Now the HTTPCompress module can be configured to exclude certain pages by using the "excludedPaths" tag in the web.config file. But this did not seem to work.
The cause was this:

This is the line in the HTTPCompress Module that is supposed to chop off the absolute portion of the path:

string realPath = app.Request.Path.Remove(0, app.Request.ApplicationPath.Length+1);


This works fine if your web application is not at the root. But in the Visual Studio Development Web Server (formerly Cassini), the Request.ApplicationPath always comes back as "/". In that case the above code will actually chop off the first character of the relative path.
I.e. "/WebResource.axd" will become "ebResource.axd".

The Solution:
This is ugly, but when you do development using the Visual Studio built-in web server you need to add both paths to the web.config file.

<excludedPaths>
<add path="ebresource.axd"/>
<add path="WebResource.axd"/>
</excludedPaths>

Of course another option is to modify the HTTPCompress source code and fix this.

Friday, June 1, 2007

Formatting a Column in a GridView with DataFormatString

Today I came across a little gotcha with the ASP.Net GridView control.
If you have a bound column bound to a DateTime field and you want to change the formatting say from "05/30/2007 15:25:22" to "05/30/2007" then the way to do this is to use the DataFormatString parameter of the BoundField:


<asp:BoundField datafield="EVENT_DATE" headertext="Event Date" DataFormatString="{0:MM/dd/yyyy}">
<ItemStyle width="10%"></ItemStyle>
</asp:BoundField>



But this didn't seem to work for some reason. The fix is to switch off HTML encoding for the column, as explained in this Microsoft post.

So the correct code is:

<asp:BoundField datafield="EVENT_DATE" headertext="Event Date" DataFormatString="{0:MM/dd/yyyy}" HtmlEncode="False">
<ItemStyle width="10%"></ItemStyle>
</asp:BoundField>



Now it works like a charm ...

Thursday, May 31, 2007

How to enable ASP applications and ASP.Net applications on WSS

On a server running Windows Sharepoint Services (WSS) where WSS has taken over the default web site, ASP applications are disabled by default. Also, ASP.Net applications will not run by default since WSS imposes some serious security restrictions on the web site. See this MS KB article (828810) for details and resolution. Basically you need to set up an excluded path in the Sharepoint Services Administration page.

Friday, May 18, 2007

Object-Oriented Techniques in Javascript

Here is a good MSDN article about some of the more object-oriented principles in JavaScript:
Create Advanced Web Applications With Object-Oriented Techniques.

Wednesday, May 16, 2007

AJAX Tips and Tricks

Here is an interesting article about some AJAX internals, put together by one of the co-founders of PageFlakes. Interesting is especially the part on caching web service responses (if appropriate in your case).

Monday, May 14, 2007

Microsoft JScript runtime error: 'AjaxControlToolkit' is undefined

Just ran into this weird error when trying to add an AJAX control to a web page and we spent a lot of time trying to resolve this.
Basically the web page worked fine but when moving it to the server it generated a client-side JS error: "Microsoft JScript runtime error: 'AjaxControlToolkit' is undefined".

this is the corresponding code:

Sys.Application.add_init(function() {
$create(AjaxControlToolkit.ModalPopupBehavior, {"BackgroundCssClass":"modalBackground", ...}, null, null, $get("btnNew"));
});



Google search did reveal people having similar problems but no good solution.
Then there was some good information in this thread.
Basically it turns out that the the script is being compressed under certain circumstances (like debug mode vs. non-debug) and whether the compression settings are defined in the web.config file.

Here is what fixed it for us. The important setting is the one "enableCompression='false'":

<system.web.extensions>
<scripting>
<scriptResourceHandler enableCompression="false" enableCaching="true">
</scriptResourceHandler >
</scripting>
</system.web.extensions>


Make sure you switch the compression off, since it seems it does not work, even when using IE7 like I do.

Monday, April 23, 2007

Winforms Tabbed UI using multiple forms

The problem at hand was how to create a Windows Forms application that uses a tabbed UI, but where you want to put the logic into separate forms, i.e. each tab page is a separate WinForm (this is mainly to not have all the code and controls in the main page).

I found 3 main approaches to this (there are probably more, but these accomplish the stated goal without excessive coding):

1. the MDIWindowManager project (free under BSD license)

2. the DockPanel Suite project (free, from SourceForge)

3. do-it-yourself (VB.Net code)

Private Sub AddFormToTab(ByVal objForm As Form, ByRef objTabPage As TabPage)
objForm.TopLevel = False
objForm.Text = ""
objForm.MaximizeBox = False
objForm.MinimizeBox = False
objForm.ControlBox = False
objTabPage.Controls.Add(objForm)
objForm.Dock = DockStyle.Fill ' Expands the form to fill the tabpage
objForm.Show()
End Sub


Use this method in the main form to add a form to a tab page.
The do-it-yourself method is simple and works, the other 2 links with the accompanying source code provide more functionality.

Tuesday, April 17, 2007

Everyone's talking about RIAs now...

It seems to me that the current hot acronym is RIA (Rich Internet Applications). I first read about it on Adobe's website when reading about Adobe Apollo (see my post on this). Now Rick Strahl has published a very good post about the trends we're seeing in the end user application development space. He does a great job putting things like WPF, WPF/E, Adobe Flex/Apollo, HTML/AJAX in perspective. As I said before, something is going on there that every serious developer needs to keep an eye out for...
I like one of the comments to his post (and pretty much mirrors my experiences):

"Another great read Rick. I have to admit that the last two big projects that I was on both were vb6 -> asp.net/ajax conversions and BOTH got halfway through development and were re-architected for clickonce and wpf because ajax still doesn't allow you to throw 30 infragistics web combos on a page. Some presentation layers just don't work well with html and probably never will granted time and a hardware refresh might change that.
When there's a preexisting expectation of the thick client experience, even ajax doesn't cut it. I'd like to see more of this clear separation of layers. The asp.net code behind model doesn't give you the ability to cut with clean lines where ui starts and the last layer stopped. throwing cab and things like ioc into the picture just complicate things. I'm all for the service model. I think Flash is there but they never got it right for the developer. It wasn't until flex builder that they released something with intellisense. Flex is nice but it just adds more overhead and is an abstraction for people who aren't core coders. ..."

Tuesday, April 10, 2007

SQL Server BLOB datatypes going away

This is something to be aware of:
It looks like the SQL Server datatypes TEXT, NTEXT, IMAGE are going away sometime in the future as noted in SQL server Books online: "ntext, text, and image (Transact-SQL)".

So for any new tables that need to store large data fields, M$ is suggesting to use VARCHAR(MAX), NVARCHAR(MAX), and VARBINARY(MAX).

Thursday, April 5, 2007

Adobe Apollo

A colleague of mine pointed out Adobe Apollo to me.
This is a very interesting technology and just confirms the trends that seem to be crystallizing in the application development space.
- pure web applications are reaching their limits in terms of usability
-> Web 2.0 wants to address that with AJAX, but the underlying protocols/languages (HTML) are just too old
- the large deployment of existing browsers, different browser technologies and the security implications that lead to tighter browser security limit what can be delivered to the user even using Web 2.0
- the user wants a seamless experience with applications that are powerful and allow desktop access and disconnected operation

-> It seems that the major players in this field are realizing this and the solution offered is a completely new "browser" - a new runtime to host new and improved content and make it feel more like a desktop application (speed, access to local file system and apps, disconnected operation)
- Microsoft introduced WPF/E as a new runtime to run XAML applications
- Adobe is working on Apollo (synergy between Flash, PDF, HTML, JavaScript, Ajax according to their web site)

On a related note, Microsoft's Click-Once technologies try to address the deployment and maintenance problems that plague desktop applications.

So basically the convergence of these technologies is targeted to the enhanced user experience. The user wants the best of both worlds:
- web app's ease of deployment, always up-to-date, highly portable
- desktop app's speed, UI features, disconnected mode, access to local system resources

We'll have to see how this pans out, but this is definitely something that seems to be here to stay and I think we haven't seen the last of this.
Especially if Adobe manages to create their Apollo runtime for the Windows Mobile and Linux platforms (and maybe Symbian/PalmOS devices) this might be a technology that can catch on.

But in general, for me as a developers this means to be aware of this trend and keep up with the technologies involved

ASP.Net Cache clarifications

Tess from MSDN has a very good post on some common ASP.Net Cache pitfalls and misconceptions here.

Sunday, March 4, 2007

Yahoo Pipes

This seems very interesting.
[Yahoo! Pipes] Pipes is a free online service that lets you remix popular feed types and create data mashups using a visual editor. You can use Pipes to run your own web projects, or publish and share your own web services without ever having to write a line of code.

This is an interesting application concept just launched by Yahoo.
Still trying to get a handle on the possibler implications and the types of applications you can build with this, but it seem like a very powerful concept for business intelligence/data mining type of things and to combat the "information overload". More information here on TechCrunch.

Back from vacation

Alright, back to work after a week in Jackson Hole, skiing.

Monday, February 19, 2007

Copy data between 2 SQL servers

Using the BCP utility that comes with SQL Server 2000/2005 you can quickly export data from one SQL server installation and import it into another. This is described on MSDN.

The tricky thing is to get the command line parameters right, you need to specify the -S argument if you have multiple or named instances of SQL server installed.
Example:
bcp Northwind.dbo.Authors out C:\Temp\DataExport.dat -n -T -S MPDESKTOP\SQL2005

Otherwise you will get stupid errors such as: "NativeError = 18456 .... Login failed for user xxxx" ...

Then the import is pretty simple, you can use Query Analyzer (or SQL server Management Studio) to run this query:

USE Northwind
GO
BULK INSERT Authors
FROM 'G:\Transfer\Tempfiles\DataExport.dat'
WITH (DATAFILETYPE='native');
GO

Friday, February 16, 2007

Class Logging and tracing - approach using custom attributes

If, for debugging purposes, you want to see what is going on in your .Net code, one approach would be to add something like

Log.Debug("FindCustomers -> enter method")


Into each method you are interested in.
Another, more generic and actually pretty cool approach would be to "instrument" your classes using custom attributes.
A sample approach is shown here. (Overlook the repeated and dorky use of the term "spy" :) ).

The drawback is that using the above approach, your classes would have to inherit from a common base class ... but maybe there is a way around that and just use the attribute ...

SQL Server Performance Analysis and Tuning

Came across an interesting post today about using SQL Profiler to analyze performance issues in SQL Server. More can be found here.
Basically the author provides a custom SQL Profiler template and then a set of stored procs to analyze the output of the captured data for long-running stored procs and most cpu-intensive stored procs etc.

Incidentally, the author (Vyas) has a pretty good web site for everything SQL Server related.

Enjoy!

Thursday, February 15, 2007

HTTP Streaming - interesting alternative to polling

Triggered by a question that came up about how to create a web page that shows data dynamically without user interaction (like a stock ticker, weather conditions etc.), I came across this post that explains HTTP Streaming.
The obvious answer would be to do "polling" having some Javascript timer on the page that makes a periodic XMLHTTPRequest to get data back to the page.
HTTP Streaming is an interesting alternative.
It is also interesting that apparently IE does not send the response to an XMLHTTPRequest back unless the request is complete, so the article also describes a clever way around that.
The main drawbacks I can see are bandwidth and the required resources on the server, basically one open connection (or thread) per connected client.

Friday, February 9, 2007

VS2005 SP1 - bloat in the Solution (.sln) file

Just ran across this, when adding a new file to a Visual Studio 2005 solution, now the solution gets all these additional entries for each project:

ProjectSection(WebsiteProperties) = preProject
      Debug.AspNetCompiler.Debug = "True"
      Release.AspNetCompiler.Debug = "False"
EndProjectSection

And these are not even web site projects, just regular DLLs (Class Library) projects used from a Web Application Project (WAP).

What is going on? Looks like this was a "feature" introduced with SP1. At least I am not the only one seeing this.


Call me old fashioned, but I don't like it ...

Wednesday, February 7, 2007

To NOCOUNT or not to NOCOUNT .. that is the question

Well, there has been an ongoing debate whether it is good practice to use "SET NOCOUNT ON" in SQL Server to reduce the network traffic.

I think if you are running UPDATE and DELETE statements or stored procedures where you don't expect any results back or have output parameters that contain the outcome of the stored procedure, it probably makes sense to include it.

There's a post by Jon Galloway that looks at this as well and argues that the RecordsAffected is hardly used anymore in ADO.net and with SqlDataReaders.
So the bottom line is: use SET NOCOUNT ON if you don't need to have the RecordsAffected as part of your business logic.

Tuesday, February 6, 2007

ASP.Net Cache - cached items disappearing

Sometimes when working on my local machine, items that I put into the ASP.Net Cache would just seem to disappear immediately from the Cache, defeating the purpose of caching. When hooking in the "CacheItemRemovedCallBack" in the add method, the reason the items were removed from the Cache was "underused".
Basically I was running into the same issue described here. It seems like the Cache was working as expected, it just "thought" that I had not enough memory left to cache any items.

One solution that was suggested on the web is to "disableMemoryCollection" for the cache as described here.

I think that would be acceptable on a developer's machine for debugging, but not for a production server, because again, letting the Cache manage it's own memory seems the better approach here.
The other option is to add the items to the Cache with a "notRemovable" priority. That also seems like asking for trouble, because then ASP.Net is forced to keep stuff in the Cache even if that memory was better used for serving a spike in user requests for instance.

There are a few settings that control the ASP.Net Cache's policies on reclaiming space and purging items settings: http://forums.asp.net/thread/1199949.aspx

Saturday, February 3, 2007

In search of: Extensible web service framework

I am looking for a good approach to create a web service that is pretty generic and can be extended. Requirements:
- easy to add new functionality
- multiple clients can hit this web service, clients can be on different software versions, new available functionality should not break older clients.

I found this interesting article "A web service as a framework for simplifying development and deployment of business functions". Somewhat against the "true" tenets of designing web service contracts etc., but might fit the bill for what I need.
The input and output parameters of this generic web service are typed datasets, and the business assemblies are loaded using reflection based in a service name given in th request.
The disadvantage is that the functionality is not explicitly described in the web service contract, it needs to be implicitly known by the client and the server (business logic assembly) based on the service name passed in. This keeps the web service interface constant when new functionality needs to be added (versioning is not a problem this way).

Friday, February 2, 2007

Insufficient system resources exist ... what's going on?

So finally today I got my new Seagate Barracuda 320 GB hard drive, put it into a USB 2.0 enclosure and started copying files (I mean thousands of files) onto it. After a while I get the following error "Insufficient system resources exist to complete the requested service." I am running Windows XP Pro, SP2.
Great.... just what I need...
Bad drive?
USB enclosure bad?
So I did some searching, increased my page file size, turned off any background programs, reboot, reboot .. no avail.
I finally found this article by Microsoft "Backup program is unsuccessful when you back up a large system volume" ... I applied the first registry change (PoolUsageMaximum) with a setting of 60 and that did the trick!
I mean how on earth are you supposed to know that there is some system internal kernel memory limit of 160 MB? Well well ... seems to be working fine now.

Hello Blog

Hi there,
I am actually creating this blog to keep stuff around that I think I might want to look up later on again.
Well, and maybe something in here will be useful for someone else ...

On that note, let's get started ...