Webservices: The request failed with HTTP status 400: Bad Request#

We have a webservice that is called from an application under heavy use.

From time to time we are getting errors coming back from the webservice:

The request failed with HTTP status 400: Bad Request

The stack trace is not very helpful:

at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

So basically the webservice is just throwing back a 400 error to the webservice request.

I haven't seen anyone online who has this type of issue.  I have seen several where they ALWAYS get this error, but none where it works most of the time and fails sometimes.

I am considering that it could be something in the network, like a proxy server or AV sniffer, but not sure.

 

Categories:  |  |  |  | 
Tuesday, November 18, 2008 5:21:48 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

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]  | 

 

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]  | 

 

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]  | 

 

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:  |  | 
Tuesday, September 16, 2008 1:17:08 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Careful With Those Cookies#

When doing testing, you might find yourself wanting to delete cookies for some URLs on your development machine.

Now, you need to be careful about how you delete these cookies, because Microsoft decided to pull a little trick on you.  They created a folder:

C:\Documents and Settings\[user]\Cookies

This folder seems to contain all your cookies!  But, actually it doesn't.  Deleting these cookies really doesn't clear out the cookies you think you are deleting because the REAL cookies are stored in:

C:\Documents and Settings\[user]\Local Settings\Temporary Internet Files

This folder contains cookies and other temporary internet files, but of the most importance here is that THIS is where you need to clear your cookies from.

I came across another thing on a recent project is that you can't test for the existance of an outbound cookie.

If Response.Cookies.Item("ASDFA") Is Nothing Then
     Response.Write("This Will Never Execute")
End If

Why is this?  It is because with the Response.Cookies collection (but not on the Request's cookies collection) when you request an item from the collection that doesn't exist it CREATES it, with a value of an empty string.

 

Categories:  |  | 
Thursday, July 31, 2008 4:42:33 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

DOs and DONTs of getting a development job#

I have been accepting resumes for a while now trying to find developers for a client of mine.

I will be updating this article from time to time with new stuff.

DO have someone proofread your resume, cover letter, and email body.  Espically if you are not a native english speaker.  If you want your resume to go directly into the trash, then please, write your email with lots of grammer and spelling problems.

DON'T write in your cover letter that, while you don't have the skills/experience they are looking for, you DO have the skills/experience that really matters.  You have just managed to tell the person reading your resume that a) you don't have the skills they need, b) you think you are smarter than the person who came up with the needed skills/experience, and c) you are probably not easy to get along with.  All in the first sentence of your cover letter: BRAVO!

DON'T send a 9 page resume including every project you have ever worked on and details about said project.  I remember when I was told that resumes should be 1 page long (2 at the most) and I thought how wrong that was.  "My resme will be so awesome, 2 pages can't contain it!"  I realized very quickly how wrong I was.  I don't need to know the specifics of some project you worked on for 3 months back in 2002, and I don't need to know a list of every programming langauge, technique, or technology that you have ever touched. 

DO supply a cover letter, or at least turn your email into your cover letter.  It will get you bonus points.

DON'T include a stupid signature on your emails.  I actually received a resume that was signed like this:

--
If fishes could talk they'd ask for legs

Ok I guess that is somewhat funny in a Jack Handy kinda way, but it really doesn't belong on an job application email.

DON'T list "Internet Connection Technologies" that you have experience with.  I swear I got a resume with this as the 2nd heading (after education).  It listed "AOL Dial Up, AOL High Speed DSL, SBC DSL".  Before you start thinking, ok well maybe these were projects they worked on, you know, like working on the team to create AOL's dial up service... no this was not what they meant, it was clear from the rest of the resume.

DON'T just make up stuff if you don't know the answer to a question.  This isn't the ACT: there are penalities for guessing (it makes you look really stupid).  Now clearly there is a difference between making an educated guess (or talking in generalities instead of specifics) and trying to totally pull something out of thin air.  I recently interviewed a candidate who said he didn't have any project experience using AJAX but was aware of AJAX technologies.  So I asked him, can you explain how AJAX works?  I wasn't expecting much, just something about using client side script to make calls to the server w/o reloading the entire page.  Instead the answer we got back was "It's like JAVA running on top of Microsoft."  Up until that point I hadn't decided if this guy was qualified, and had he simply said "No, I am sorry I am not that familiar with AJAX" I probably would have still been considering him, but his terrible attempt at an answer removed all doubt that he was not qualified.

Categories:  |  |  |  | 
Sunday, July 27, 2008 10:26:33 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Validating Enum Values#

You were a good developer and created an enum to represent the integer values that are being passed into your method.

It makes life easy for everyone.  Good job.

But now you realize that ANY integer can be passed into your function, even though your type only defines a handful of values.

Well, you need to validate the enum values that are coming into your method.

This can be done quickly with the following code snippet:

If Not [Enum].IsDefined(localId.GetType, localId) Then
    Throw New System.ComponentModel.InvalidEnumArgumentException("Invalid local value.")
End If

In this example localId is the variable name of type LocalType.

Categories:  |  | 
Thursday, July 24, 2008 12:55:29 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Generating Resx Files For Globalization and Localization#

Using resource files (resx files) for globalization is a standard technicque.  ASP.NET allows you to create 1 resx file per page to help you manage your content.

But when it is time to convert those files into the correctly named localized version to send to the translator, you might find yourself doing a lot of copying and renaming.

So I wrote a little script that does this for you:

Imports System.IO
Module Module1

    Sub Main()
        Dim languages() As String = {"es", "pl", "de", "fr"}
        For Each filepath As String In Directory.GetFiles("C:\translationTest")
            If filepath.Contains("x.resx") Then
                For i As Integer = 0 To languages.Length - 1
                    File.Copy(filepath, filepath.Replace(".resx", "." & languages(i) & ".resx"))
                Next
            End If
        Next
    End Sub

End Module

This will generate all the files for you, and then all you need to do is send the off and wait for the translator to do the REAL work :).

Categories:  |  |  | 
Tuesday, July 22, 2008 2:13:50 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Model View Presenter Guidance From MS Patterns and Practices#

Microsoft's Patterns and Practices group has released some guidance for creating MVP web applications.

http://www.pnpguidance.net/Tag/MVPBundle.aspx

I haven't checked this out, so I can't verify if they are worth looking into you, but I will be reading them in the near future.

Categories:  |  | 
Tuesday, June 24, 2008 4:55:57 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

FancyUpload Component#

I recently wrote about how the Flickr Uploadr tool sucks, but the other part of that article was how the web upload tools for Flickr is very nice!

FancyUpload is a set of code using Flash/Javascript to perform out of band file uploads.

This is basically how Flickr allows you to queue files for upload in their web client, and it is very useful in this sense because it would be extremely painful to be forced to post every single image individually.

For me, I am more interested in the ability to post very large files without leaving the brower in a fashion that seems to make it look like it is "stuck" when really it is just uploading a giant file.

 

Categories:  |  |  |  | 
Tuesday, June 24, 2008 9:26:51 AM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Globalization and Localization in ASP.NET#

This is a good article from Microsoft on globalization and localization of asp.net applications.

The article describes how to automate the process of moving static content from pages (inside labels) into resource files and setup the proper binding between the content controls and the resource files.

This article has some interesting and useful information as well about some other topics such as global vs local, implicit globalization settings, dealing with scripts etc.

Categories:  |  | 
Monday, June 23, 2008 4:52:24 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

e.Item.Dataitem is nothing?#

So you have some code running in your itemdatabound event handler and you are trying to do someting with e.item.dataitem but it keeps bombing out with errors because e.item.dataitem is nothing.

So, why is e.item.dataitem is nothing??

Answer: Because you are probably using a header or footer in your binding object.  The header/footer will cause the itemdatabound event to fire, but there is no dataitem for them.

Check if the current row is the header or footer, and then you will have no issues with using e.item.dataitem.

Categories:  |  | 
Thursday, June 19, 2008 3:22:37 PM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

VS.NET Extensions for Sharepoint#

My experience with developing for Sharepoint was very painful.  The jist of it was, unless you are truly going to hook into a lot of the core functionality of sharepoint (document collaboration and workflow) it will be MUCH harder to build an app to run in sharepoint than it would be to build a standalone application.

But MS has released some new extensions that will hopefully ease the pain a little bit:

Announcing: Visual Studio extensions for SharePoint – Developer User Guide

I don't know if I will ever have enough time to implement anything in sharepoint, but these will be nice to have.

Categories:  |  | 
Thursday, June 12, 2008 11:50:21 AM (Central Standard Time, UTC-06:00) #    Comments [0]  | 

 

Highslide#

We have been working with a pretty cool little javascript toolkit called Highslide.

http://vikjavev.no/highslide/

It gives you some nice lightbox type effects but I like it more because of some of the options to load in iframes and stuff.

Someone wrote some asp.net wrappers as well to make it easier to add to your pages:

http://encosia.com/

 

Categories:  |