Compressing Web Service Calls#

Most webservers will compress data if the clients support it.

Unfortunately for .net developers the auto generated proxy classes that access webservices don't include this functionality.

I'll show you how to achieve this while avoiding changing any code in the auto generated proxy classes.

(These classes utilize ICSharpCode.SharpZipLib.dll so you'll have to download this)

This following class will deal with decompressing a response.

Imports System.Net
Imports ICSharpCode.SharpZipLib

Public Class UncompressedGzipResponse
    Inherits System.Net.WebResponse

    Private cCompressedGzipResponse As HttpWebResponse

    Public Sub New(ByVal compressedGzipResponse As HttpWebResponse)
        MyBase.New()
        cCompressedGzipResponse = compressedGzipResponse
    End Sub


    Public Overrides Function GetResponseStream() As System.IO.Stream

        Dim compressedStream As System.IO.Stream = New GZip.GZipInputStream(cCompressedGzipResponse.GetResponseStream)
        Dim decompressedStream As New System.IO.MemoryStream
        Dim size As Integer = 2048
        Dim writeData(2048) As Byte
        While True
            size = compressedStream.Read(writeData, 0, size)
            If size > 0 Then
                decompressedStream.Write(writeData, 0, size)
                Dim s As String = System.Text.Encoding.ASCII.GetString(writeData)
                s = s & ""
            Else
                Exit While
            End If
        End While
        decompressedStream.Seek(0, IO.SeekOrigin.Begin)

        Return CType(decompressedStream, IO.Stream)

    End Function

    Public Overrides Property ContentType() As String
        Get
            Return cCompressedGzipResponse.ContentType
        End Get
        Set(ByVal value As String)
            cCompressedGzipResponse.ContentType = value
        End Set
    End Property

    Public Overrides Property ContentLength() As Long
        Get
            Return cCompressedGzipResponse.ContentLength
        End Get
        Set(ByVal value As Long)
            cCompressedGzipResponse.ContentLength = value
        End Set
    End Property

    Public Overrides ReadOnly Property Headers() As System.Net.WebHeaderCollection
        Get
            Return cCompressedGzipResponse.Headers
        End Get
    End Property

End Class

This next class will handle most of the logic so that your proxy class can be as small as possible:

Public Class WebServiceCompressionHelper
    Public Shared Function GetWebRequest(ByVal uri As System.Uri, ByVal output As WebRequest, ByVal compress As Boolean) As WebRequest

        '*** add gzip
        If compress Then
            output.Headers.Item(Net.HttpRequestHeader.AcceptEncoding) = "gzip"
        End If

        Return output
    End Function

    Public Shared Function GetWebResponse(ByVal output As WebResponse, ByVal request As System.Net.WebRequest) As WebResponse

        Dim compressedResponse As HttpWebResponse = Nothing
        If TypeOf output Is HttpWebResponse Then
            compressedResponse = CType(output, HttpWebResponse)
        End If

        If compressedResponse IsNot Nothing AndAlso compressedResponse.ContentEncoding = "gzip" Then
            output = New UncompressedGzipResponse(compressedResponse)
        End If
        Return output
    End Function
End Class

In order to make use of this we need to tap into a few methods in the auto generated proxy.  The easiest way to do this is to extend the proxy class into your own subclass, like so:

Public Class MyService
    Inherits generated.proxy.class.here
    Protected Overrides Function GetWebRequest(ByVal uri As System.Uri) As System.Net.WebRequest
        Return Walshgroup.Webservices.Common.WebServiceCompressionHelper.GetWebRequest(uri, MyBase.GetWebRequest(uri), True)
    End Function
    Protected Overrides Function GetWebResponse(ByVal request As System.Net.WebRequest) As System.Net.WebResponse
        Dim output As System.Net.WebResponse = MyBase.GetWebResponse(request)
        Return Walshgroup.Webservices.Common.WebServiceCompressionHelper.GetWebResponse(output, request)
    End Function
End Class

Now, instead of instantiating your generated proxy class, you will simply instantiate your subclass.

That's it!

 

Categories:  |  | 
Monday, November 17, 2008 5:30:44 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Deleting Projects From TFS#

For some reason the TFS Team Explorer UI doesn't give you the ability to delete team projects.

To do this you need to make use of the TfsDeleteProject command line utility.

Basically just navigate to:

C:\Program Files\Microsoft Visual Studio 8\Common7\IDE

and run the command:

TfsDeleteProject /server:http://SERVERNAME:8080 PROJECTNAME

After you do this, you may need to run the "TfsVersionControl Administration Job" job on the machine running SQL for TFS.  It's under SQL Agent/Jobs.

Finally, the team projects will continue to show up in Source Control Explorer.  This is because you need to do a "GET" on the projects in order for them to clean up local files.  Once you do a get on the projects they will be gone from your workspace list.

Categories:  | 
Wednesday, November 05, 2008 1:18:22 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Killing a process#

99 times out of 100 you can kill any process from within task manager, but what about that 100th time when it just doesn't work?

That's when it's time to get out the command prompt.

In task manager, you need to first get the PID.  Click View -> Select Columns and put a check next to PID (Process Identifier).  This will show you the PID in the task manager Processes tab.

Now, open command prompt and run:

Kill -f PID

If the process you want to kill was started by a scheduled task you need to run:

AT HH:MM <path>\kill -f PID

or

Soon <path>\kill -f PID

 

Categories:
Monday, October 27, 2008 7:58:26 AM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Veracruz Spanish Immersion School#

I am in the process of looking for a spanish school for this winter when I will be traveling to the Yucatán Peninsula.

I had meant to write something on here about my last trip to Mexico when we went to Veracruz.

We stayed at the Veracruz Spanish Immersion School.  Well, actually because we were there during their most busy week and we requested an odd schedule they put us up in one of their other houses, which was a short bus ride (or walk) from the school. 

The school is run by an American couple, who I think have setup a great program in Veracruz.  They meet you at the airport to make sure you arrive without issue.  Our rooms were nice, and all the rooms had A/C, which was extremely important as it was the hight of the summer.  Wireless internet access turned out to be equally important as some things with one of my clients meant that I needed to have internet access from my laptop to assist them, and I was able to do this without problem.

We met a lot of interesting people who were staying at the school.  I think probably the idea of language immersion programs might bring out some slightly odd people, and there were some for sure :), but we met a lot of nice people and spent a good amount of time hanging out with them.

The instructors were mostly in their early 20s.  Based on talking with some of the other students who had been doing these immersion programs for a while, it seemed like that might be different from most other programs, where older more experienced instructors were used, but I thought it was great.  I enjoyed talking with all our teachers, and they were all immensely friendly and helpful. 

All the instructors and students ate breakfast and lunch together, which gave you a chance to meet some of the other students/instructors that you might not have in your classes.  They also have one of the instructors during non-lesson hours from 5am to 9pm in the common area/living room.  This is a great idea, because if nothing is going on you can go hang out and practice your spanish, or just listen to others if you don't feel like talking.

The other thing they do, which is a really great idea, is that for 2 hours a day you go out on the town with one of the instructors.  You can use this time to practice your spanish, to learn about the city, to learn the bus system, to see sites, or in our case, to go find out how we can buy tickets for the upcoming futbol game between Cruz Azul and Los Tiberones Rojos.

One day a week is a day long trip to one of a number of destinations.  This is when we went to see some ruins.  We walked into the local town for lunch, and walked across a suspension bridge.  It was fun.

Veracruz was a nice place.  Safety was not an issue during our trip.  We were our walking around the city past midnight, and it was no big deal.  The buses that run up and down the main road were really easy to use and we took them several times a day to get all over the place.

The only problems we had were that I got sick (sore throat/cold) and then near then end of our trip got "sick" (montezuma's revenge!).  I probably had some bad ice somewhere.  Next time I'll bring some medicine in case that happens.  But overall, it wasn't that big of a deal. 

We have a few other places we would like to visit, but I would definitely go back.  We had fun and I think we learned a lot even though we were only there for a week.

 

Categories:
Monday, October 20, 2008 12:52:05 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Sub Sub Notebooks#

This is really pretty cool. 

It's really really small: 95mm by 65mm by 15.5mm, but with a resolution of QVGA, I don't see it doing all that well among people who really would consider using this for their email/internet access.

 

But this does pose an interesting question, will we ever have a smartphone that is able to run a normal OS and standard resolutions when connected to a doc?  My phone has more processing power than my old laptop did.  Why can't it run a real OS and standard apps?

Categories:  | 
Monday, October 20, 2008 12:21:49 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Putting code in server controls attributes#

You can't do something like this:

<asp:Label id="lbl1" runat="server" Text=<%= CurrentUserName %> />

That is because it won't let you assign a server tag result to the attribute of a server control.

Thankfully, there is a solution:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx

 

Categories:  |  | 
Wednesday, October 08, 2008 2:25:31 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Master of Science#

This week I received a notification that I had been awarded a letter of commendation from the University of Chicago.

I realized that I never posted anything on here about my graduation.  I graduated this summer with the degree of Master of Science in Computer Science.

I'm obviously proud to have been able to graduate from such a well regarded school. 

I know that I learned a lot of valuable things while I was going to class, in areas that I probably would not have entered otherwise.

Best news is, I paid it all as I went.  So I have no debt!  :)

 

Categories:
Wednesday, October 08, 2008 1:42:27 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Problems Extending Winforms Combobox#

On a recent project, one of my developers was trying to extend the combobox in a winforms project.  We wanted to reuse the same combobox in several places. 

The combobox would always have the same objects bound to it, and we wanted a few functions extra functions on the combobox that would centralize some functionality.

So we inherited from combobox, and in the constructor of our class we created the 5 objects that we need in the dropdown and we added them to the combobox items collection.

So far so good.

But we found that when we made a change in the designer for a form that uses this combobox, the designer put stuff in the designer.vb file.  Lines that were trying to add items to our combobox.

It used the .items.AddRange(...) function and tried to add 1 item for every item that we add in the contructor.

Basically it was looking like the designer instantiated the control, and then was trying to serialize the items in the combobox when we would change anything on the form.

This would eventually cause the designer to blow up, as well as a similar error when we tried to run the compiled code.

The solution was elusive and quite a pain.

Some credit needs to go to Andre for his post.

Basically we needed a way to tell in our code if the control was being hosted in the VS designer.  If it was, then we skipped the part where we populated this dropdown.

So first thing we did was create 2 functions to figure out where the control is hosted:

Private Function IsDesignerHosted() As Boolean
    Return Me.IsControlDesignerHosted(Me)
End Function
Private Function IsControlDesignerHosted(ByVal ctrl As Control) As Boolean
    If ctrl IsNot Nothing Then
        If ctrl.Site IsNot Nothing Then
            If ctrl.Site.DesignMode Then
                Return True
            Else
                Return IsControlDesignerHosted(ctrl.Parent)
            End If
        Else
            Return IsControlDesignerHosted(ctrl.Parent)
        End If
    Else
        Return False
    End If
End Function

Then, because it turns out that testing the DesignMode is useless when you are doing the testing from the constructor, so I had to move the databinding into it's own function along with a instance variable to make sure we only do this one time.

Private cbInit As Boolean = False
Private Sub MyControl_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.VisibleChanged
    If Not cbInit Then
        cbInit = True
        If Not Me.IsDesignerHosted Then
            '*** add items here
        End If
    End If
End Sub

There it is!

 

Categories:  |  | 
Wednesday, October 08, 2008 12:53:28 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Nice Shadow Copy How-To Page#

This article from Petri is pretty nice for showing you quickly and simply how to do basic shadow copy tasks:

http://www.petri.co.il/how_to_use_the_shadow_copy_client.htm

Very useful if you need to explain the process to someone.

 

Categories:  |  | 
Monday, October 06, 2008 10:17:21 AM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Getting Date For Batch Files#

There are lots of times when you might be setting up a batch file or nightly job where it would be nice to have the date in a format that you can use as part of a log file name.  i.e. ErrorLog021508.log (feb 15, 2008).

This is a script I found from a guy who goes by seamonkey, so I left his ownership line intact.

echo on
@REM Seamonkey's quick date batch (MMDDYYYY format)
@REM Setups %date variable
@REM First parses month, day, and year into mm , dd, yyyy formats and then combines to be MMDDYYYY
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2 DELIMS=/ eol=/” %%A IN ('echo %CDATE%') DO SET dd=%%B
FOR /F "TOKENS=2,3 DELIMS=/ " %%A IN ('echo %CDATE%') DO SET yyyy=%%B
SET date=%mm%%dd%%yyyy%
echo %date%
Categories:
Sunday, October 05, 2008 10:15:31 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Removing The Dell Login Background Image#

On Dell machines running Windows Server 2003 they are nice enough to stick an ugly bitmap on your background.  So when you VPN and RDP into the server, you get to sit and wait as it paints this image:

Thankfully, you can remove it.

Just use regedit and navigate to:

HKEY_USERS\.DEFAULT\Control Panel\Desktop

Then delete the key for WallPaper.

It's that simple!

 

Categories:  |  | 
Sunday, October 05, 2008 9:41:13 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

White Sox Winner#

I went to the last 2 Sox games: the make up "must win" game to force a tiebreaker, and the tiebreaker with the Twins, which the Sox won 1-0.  Great result!

The game was a "black out" where all the fans wore black, and while I expected only 50% or so to do so, I was amazed to see almost everyone was wearing black.

It was electric!



Categories:
Wednesday, October 01, 2008 3:28:17 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Security#

Ok, this is awesome!

Categories:
Wednesday, October 01, 2008 8:20:11 AM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

SQL Reporting Services Subscription Ownership#

We utilize data driven subscriptions in SQL Server Reporting Services (SSRS) to automate several reports and their distribution to a group of people.  For example maybe when a work order is created in the database a report with info about that order is emailed to everyone who will have to be involved in fulfiling the order. 

We realized that some of these reports were not going out.  By looking at the log files (located at ) it became clear that we were hitting a permissions issue:

ReportingServicesService!library!4!09/25/2008-08:15:04:: 
e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException:
The permissions granted to user 'MYDOMAIN\someuser' are insufficient for performing this operation., ; Info: Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException:
The permissions granted to user 'MYDOMAIN\someuser' are insufficient for performing this operation.

Ok that seemed to make sense.  The user "someuser" had left our company and so I'm sure his account was disabled.  After looking around at the report, it's definition, the subscriptions, the data access, nothing was tied to this old employee. 

But.... the subscription itself still is.

The downside of this is that there is no way to change who "owns" the subscription.

However, you can make the changes manually in the database with the following code:

DECLARE @OldUserID uniqueidentifier
DECLARE @NewUserID uniqueidentifier 

SELECT @OldUserID = UserID FROM dbo.Users 
WHERE UserName = 'MYDOMAIN\someuser'

SELECT @NewUserID = UserID FROM dbo.Users 
WHERE UserName = 'MYDOMAIN\newuserhere'

UPDATE dbo.Subscriptions 
SET OwnerID = @NewUserID 
WHERE OwnerID = @OldUserID
Presto, your subscription has a new owner and will once again start running correctly.

UPDATE: I am going to try to work on something that will monitor the subscriptions and notify me if one of them fail.  Check back later.

Categories:  |  | 
Tuesday, September 30, 2008 2:52:04 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Displaying Chart Data With CSS#

Here is a great article about some of the techniques for displaying chart data using CSS.

Examples: http://apples-to-oranges.com/goodies/css-for-bar-graphs/

Categories:  | 
Sunday, September 21, 2008 6:37:59 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Merging Trillian Log Files#

I recently rebuilt my computer, and after reinstalling and running trillian for several days, I realized that I never moved over my log files from my old drive.

No problem, thanks to this awesome merge tool:
http://www.zalbee.intricus.net/programming.html

It's a simple command line utility written in java.  Took me like 5 minutes to merge all my files.  Awesome!

Categories:
Tuesday, September 16, 2008 1:48:27 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

NHibernate Tutorials#

I have been poking around with NHibernate for a while now, but I am actually writing a small app with it at the moment.

During my time getting it up and running, I came across a few well written tutorials that I want to catalog here in case I want to return to them at some point for more in depth reading.

Great NHibernate Faq:
http://www.tobinharris.com/2007/2/3/nhibernate-faq

Fluent Interface for NHibernate:
http://blogs.hibernatingrhinos.com/...nhibernate.aspx

Alan Northam's Tutorials:
http://devlicio.us/blogs/alan_northam/...part-i.aspx
http://devlicio.us/blogs/alan_northam/...part-ii.aspx
http://devlicio.us/blogs/alan_northam/...part-iii.aspx
http://devlicio.us/blogs/alan_northam/...part-iv.aspx

 

Categories: