Archive for April, 2010

Google Calendar .NET API – HTTP 417 Error

3

I never even knew what a 417 error was until today. Apparently it’s an “Expectation Failed” error.  It’s rare, to say the least.  In my 15+ years of working with HTTP I’ve never come across it.  I had to do some research to get this sorted out and while the information needed to diagnose and fix the problem existed elsewhere, it didn’t exist in one place.  So I’m somewhat consolidating here and trying to provide links back to my original references.

What’s The History?

So here’s the skinny on the issue.  There is a piece of an HTTP request called “Expect-100″ which tells a client making a request to first confirm that things are working, and if so to continue with the rest of the request.  The response from the server if everything is working is a response of “100″.

Now technically, you’re only supposed to send “Expect-100″ as true if the server is prepared to handle it [reference].  Depending on the server setup, this may or may not break things.  With more focus on web services, there’s more focus on the intricate settings that go into serving them (it’s not all just web browsers and strawberry jam nowadays, y’know).

What’s The Issue?

Since there is more focus on making sure things are done correctly, many services (Twitter and Google’s APIs are among them – [reference]) have decided that their HTTP requests should be properly formed.  With the amount of traffic they generate, who can blame them.  However, Microsoft’s .NET by default includes “Expect-100″ as “true” in all of its requests.  So using .NET to do something with those API’s can cause a nasty and hard to track down 417 error.  Fiddler to the rescue, right?

What’s The Fix?

Luckily, the fix is pretty easy once you figure out how to do it.  Before you make a service request, just add this line of code (C#):

1
System.Net.ServicePointManager.Expect100Continue = false;

[reference]

That should fix things right up.  Enjoy!

Making jQuery and ASP.NET AJAX Play Well Together

0

This one caused me a few headaches tonight, so I figured I could throw something on the blog in the hopes that Google would lead someone to what turned out to be a less than logical solution, but a solution. ;)

First, the setup:  Basically, I have a page that was written by someone else and that person had an affinity for the Microsoft ASP AJAX Control Toolkit (I have no idea why).  Well me, I have an affinity for jQuery.  So I set about building new functionality on the existing page in jQuery, while trying to keep the functionality that was already there untouched and in tact.  That turned out to be more difficult than expected.

I’m sure there are tons of issues to work through on this and I may update this article as those arise.  But first up I had to figure out why the standard jQuery $(document).ready() functionality wasn’t working when there was, most obviously, a PostBack occurring.  And, as it turns out, there’s a sort of fake PostBack that occurs when using the AJAX.NET toolkit.  Lame.  But here’s how to handle it (full code description follows):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
		$(document).ready(function() {
			EndRequestHandler();
		});
 
		function load() {
			Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
		}
 
		function EndRequestHandler() {
			// do page load things
		}
    </script>
</head>
<body onload="load()">
    <form id="form1" runat="server">
    <div>
 
    </div>
    </form>
</body>
</html>

The Breakdown

First, you need to create a client side (JavaScript) function to execute whenever a page is “loaded” (I put it in quotes because the load event sometimes fires and sometimes doesn’t when using AJAX.NET).  You need the two layers of abstraction here so the function can be called in the multiple scenarios that are created by a real page load and an AJAX.NET partial page load:

1
2
3
function EndRequestHandler() {
	// do page load things
}

Now, once you have created that function you need to call it from both the jQuery and ASP.NET client side load events.

First up, the standard jQuery call will work pretty much as expected:

1
2
3
$(document).ready(function() {
	EndRequestHandler();
});

The ASP.NET version requires that you make another function and attach the first function to the client event… Yeah, I know, it’s wonky.

1
2
3
function load() {
	Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}

Once you’ve done all the jumping through flaming hoops, you can just attach the function to the body tag’s onload event and everything will be wired up and ready to go.

1
<body onload="load()">

Enjoy!

How To Have Multiple Domains Using 1&1

5

If you read my other post, you know about the problems I have had getting a client set up with multiple domains hosted under the same 1&1 account. 1&1′s decision to market their hosting as “have as many domains as you want” is misleading at best, because they require that each domain point to the same place. You have to handle ALL multiple domain requests using a coded solution. This isn’t ideal for far too many reasons to list here, but I figured I could offer someone some help if they are running into the same problem.

Pre-Conditions

  1. First you have to have all of your files set up correctly.  The correct way is to have a sub-directory for each site that you want to host under the account.  You may have better luck, but I couldn’t get directory names with dots in them to work (just another thing on the long list).
  2. Once you have your files set up, you need to make sure that each site’s domain is pointed to the account root.  Not the sub-directory that you have created for the site.

Primary Redirect File

Now, in the account root directory, you need a file called default.asp that will include code similar to the following:

1
2
3
4
5
6
7
8
9
<%EnableSessionState=False
  host = Request.ServerVariables("HTTP_HOST")
 
  if host = "domain1.com" or host = "www.domain1.com" then
    response.redirect("http://domain1.com/domain1-directory/default.aspx")
  elseif host = "domain2.com" or host = "www.domain2.com" then
    response.redirect("http://domain2.com/domain2-directory/index.shtml")
  end if
%>
Your sites will now technically work.  But wait, there’s more!  What if you want to have custom error pages for each site?

Custom Error Pages

Of course, there’s more hoops to jump through.  This can’t be done on the server side because the default IIS error files are .html files.  So you basically have to fool IIS into using your files by naming them the name that IIS uses by default.  Then, you have to use code similar to the following to make sure sites redirect whenever an error page is hit.  Yes, I know this isn’t ideal, but the entire account is now a hack because 1&1 sucks, so I’ll live with it until I convince everyone to abandon 1&1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
		<title>Error!</title>
		<script type="text/javascript">
			if (location.hostname == "domain1.com" || location.hostname == "www.domain1.com") {
				window.location = "http://www.domain1.com/domain1-directory/404.shtml";
			} else if (location.hostname == "domain2.com" || location.hostname == "www.domain2.com") {
				window.location = "http://domain2.com/domain2-directory/error404.html";
			}
		</script>
	</head>
	<body>
	</body>
</html>

After All…

While my preference would be to never have to deal with this crazy hack-happy format for having an account with multiple domains, I will undoubtedly run into this again.  Who knows, maybe someday you will to and this article will prove helpful.  I guess, in the end our world is all about hacking solutions into place, right?  ;)
Go to Top