Archive for April, 2010
Google Calendar .NET API – HTTP 417 Error
3I 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; |
That should fix things right up. Enjoy!
Making jQuery and ASP.NET AJAX Play Well Together
0This 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
5If 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
- 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).
- 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 %> |
Custom Error Pages
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> |