Archive for April 20th, 2011

WinInet Apps failing when Internet Explorer is set to Offline Mode

Ran into a nasty issue last week when all of a sudden many of my old applications that are using WinInet for HTTP access started failing. Specifically, the WinInet HttpSendRequest() call started failing with an error of 2, which when retrieving the error boils down to:

WinInet Error 2: The system cannot find the file specified

Now this error can pop up in many legitimate scenarios with WinInet such as when no Internet connection is available or the HTTP configuration (usually configured in Internet Explorer’s options) is misconfigured. The error typically means that the server in question cannot be found or more specifically an Internet connection can’t be established.

In this case the problem started suddenly and was causing some of my own applications (old Visual FoxPro apps using my own wwHttp library) and all Adobe Air applications (which apparently uses WinInet for its basic HTTP stack) along with a few more oddball applications to fail instantly when trying to connect via HTTP. Most other applications – all of my installed browsers, email clients, various social network updaters all worked just fine. It seems it was only WinInet apps that were failing. Yet oddly Internet Explorer appeared to be working.

So the problem seemed to be isolated to those ‘classic’ applications using WinInet. WinInet’s base configuration uses the Internet Explorer options dialog. To check this out I typically go to the Internet Explorer options and find the Connection tab, and check out the LAN Setup. Make sure there are no rogue proxy settings or configuration scripts that are invalid. Trying with Auto-configuration on and off also can often fix ‘real’ configuration errors. This time however this wasn’t a problem – nothing in the LAN configuration was set (all default). I also played with the Automatic detection of settings which also had no effect.

I also tried to use Fiddler to see if that would tell me something. Fiddler has a few additional WinInet configuration options in its configuration. Running Fiddler and hitting an HTTP request using WinInet would never actually hit Fiddler – the failure would occur before WinInet ever fired up the HTTP connection to go through the Fiddler HTTP proxy.

And the Culprit is: Internet Explorer’s Work Offline Option

The culprit in this situation was Internet Explorer which at some point, unknown to me switched into Offline Mode and was then shut down:

WorkOfflineMode[4]

When this Offline mode is checked when IE is running *or* if IE gets shut down with this flag set, all applications using WinInet by default assume that it’s running in offline mode. Depending on your caching HTTP headers and whether the page was cached previously you may or may not get a response or an error. For an independent non-browser application this will be highly unpredictable and likely result in failures getting online – especially if the application forces requests to always reload by disabling HTTP caching (as I do on most of my dynamic HTTP clients).

What makes this especially tricky is that even when IE is in offline mode in the browser, you can still browse around the Web *if* you have a connection. IE will try to load anything it has cached from the local cache, but as soon as you hit a URL that isn’t cached it will automatically try to access that URL and uncheck the Work Offline option. Conversely if you get knocked off the Internet and browse in IE 9, IE will automatically go into offline mode. I never explicitly set offline mode – it just automatically sets itself on and off depending on the connection. Problem is if you’re not using IE all the time (as I do – rarely and just for testing so usually a few commonly used URLs) and you left it in offline mode when you exit, offline mode stays set which results in the above head scratcher. Ack.

This isn’t new behavior in IE 9 BTW – this behavior has always been there, but I think what’s different is that IE now automatically switches between online and offline modes without notifying you at all, so it’s hard to tell when you are offline.

Fixing the Issue in your Code

If you have an application that is using WinInet, there’s a WinInet option called INTERNET_OPTION_IGNORE_OFFLINE. I just checked this out in my own applications and Internet Explorer 9 and it works, but apparently it’s been broken for some older releases (I can’t confirm how far back though) – lots of posts seem to suggest the flag doesn’t work. However, in IE 9 at least it does seem to work if you call InternetSetOption before you call HttpOpenRequest with the Http Session handle.

In FoxPro code I use:

DECLARE INTEGER InternetSetOption ;

   IN WININET.DLL ;

   INTEGER HINTERNET,;

   INTEGER dwFlags,;

   INTEGER @dwValue,;

   INTEGER cbSize

lnOptionValue = 1   && BOOL TRUE pass by reference

 

*** Set needed SSL flags

lnResult=InternetSetOption(this.hHttpSession,;

   INTERNET_OPTION_IGNORE_OFFLINE ,;  && 77

   @lnOptionValue ,4)

 

DECLARE INTEGER HttpOpenRequest ;

   IN WININET.DLL ;

   INTEGER hHTTPHandle,;

   STRING lpzReqMethod,;

   STRING lpzPage,;

   STRING lpzVersion,;

   STRING lpzReferer,;

   STRING lpzAcceptTypes,;

   INTEGER dwFlags,;

   INTEGER dwContextw

 

 

hHTTPResult=HttpOpenRequest(THIS.hHttpsession,;

   lcVerb,;

   tcPage,;

   NULL,NULL,NULL,;

   INTERNET_FLAG_RELOAD + ;

   IIF(THIS.lsecurelink,INTERNET_FLAG_SECURE,0) + ;

   this.nHTTPServiceFlags,0)

… 

And this fixes the issue at least for IE 9…

In my FoxPro wwHttp class I now call this by default to never get bitten by this again… This solves the problem permanently for my HTTP client. I never want to see offline operation in an HTTP client API – it’s just too unpredictable in handling errors and the last thing you want is getting unpredictably stale data. Problem solved but this behavior is – well ugly. But then that’s to be expected from an API that’s based on Internet Explorer, eh?

© Rick Strahl, West Wind Technologies, 2005-2011
Posted in HTTP  Windows  
kick it on DotNetKicks.com

DevExpress wins 2 awards at GIDS 2011 in Bangalore, India! #GIDS

DevExpress wins two awards today at the Great Indian Developer Summit 2011:

GIDS Awards GIDS Awards II 

Best in Development Environment

CodeRush, our IDE productivity enhancement tool, won an award in Development Environment category!

Best Analytics

The DevExpress analytics tools: ASP.NET & WinForms PivotGrid won in the Database category!

We are honored and humbled that our first visit to the Great Indian Developer Summit (GIDS) in Bangalore, India resulted in 2 awards!

Day 2 Summary

The second day at GIDS was all about the Web technologies and we met several developers interested in our ASP.NET and Silverlight technologies.

Thanks for everyone who dropped by the booth.

DXperience? What's That?

DXperience is the .NET developer's secret weapon. Get full access to a complete suite of professional components that let you instantly drop in new features, designer styles and fast performance for your applications. Try a fully-functional version of DXperience for free now: http://www.devexpress.com/Downloads/NET/


Custom SharePoint Ribbons and Current List Item in JavaScript

I recently had to build a custom ribbon item displayed when a user viewed a list item. The ribbon button would whisk the user away to a view on another list, passing the current list item ID to the view to use as a query string filter. The secondary list has a field that references the first list (sort of a parent/child relationship).

The challenge (besides creating a Ribbon item which is a Hell unto itself) was to get the current list item ID and pass it to the view via a query string so the view could be filtered. The SP.ClientConext class in the ECMAScript Class Library for SharePoint lets you get all kinds of things like retrieving lists and even list items from SharePoint through JavaScript. I didn’t find any way to get the current list item (it’s easy to get all list items for the current list but there didn’t seem to be a property like SP.ListItem.get_current()). Maybe I overlooked it.

After posting a few pleas for help on Twitter (including one dude who told me to go trolling Stack Overflow because “several MVPs frequent” there, to which I replied “Yes I know. I’m one of them.”) I caved in and posted the question on Stack Overflow (well, the recently promoted SharePoint site on StackExchange).

It got a few answers but nothing that really worked for my situation. Remember, I want to a) create a custom ribbon item that links to another view on another list and b) pass along the id of the current list item to that view for filtering (via a query string). Finally I stumbled over the answer buried deep on MSDN.

So here’s the effect we’re going after. A ribbon button on the display form of a list item that links to an associated view:

The Custom Group contains a series of Buttons, each of which links to a view in another list. Each view was created with a custom filter to only show items where a field in that list matched the value passed in.

Normally you would open the list view in SharePoint designer, select the DataView and add a parameter to filter on a query string value. I’ll follow up with another blog post on how to do this programmatically without opening SharePoint Designer.

When the user clicks on one of the custom buttons, we open another dialog and display that view.

Like I said there were some good answers on the question from the SharePoint community. Brage Tukkensæter posted an answer that involved a custom action that iterated through each item selected and passed it along to a dialog. The problem with this was that you needed to have the user select at least one item in the list in tabular form (I’ve turned this function off in the view) and launching from the Display Form, the SP.ListOperation.Selection property he proposes to use is blank.

Wouter van Vugt, another SharePoint MVP (Stack Overflow is just full of them), had another option. Grab the ID value from the query string of the list form and use it. That sounds like a fairly simple idea but it requires a few lines of JavaScript to grab the query string value. There are many examples on the web that you find to do this but they all require some kind of parsing, maybe some regular expressions, and it all feels awkward.

I thought about using SPServices since we had that available but it meant that I would be relying on the JavaScript to call out to SPServices to do this and all of my buttons would have to be written to pass in something unique to a JavaScript method to do this. Again, more work than I think was necessary. I have the item up on the screen so I *know* SharePoint knows what the ID is. Why is it so freakin’ hard to get it.

Well, it isn’t but it required some lucky digging and MSDN documentation from the previous version of SharePoint to surface it.

Buried on this page in MSDN is a HOWTO on adding actions to the user interface. On that page there’s a list of URL Tokens.

  • ~site - Web site (SPWeb) relative link.
  • ~sitecollection - site collection (SPSite) relative link.
  • In addition, you can use the following tokens within a URL:
  • {ItemId} - Integer ID that represents the item within a list.
  • {ItemUrl} - URL of the item being acted upon. Only work for documents in libraries. [Not functional in Beta 2]
  • {ListId} - GUID that represents the list.
  • {SiteUrl} - URL of the Web site (SPWeb).
  • {RecurrenceId} - Recurrence index. This token is not supported for use in the context menus of list items.

These are normally associated with a UrlAction element but there’s nothing to prevent you from using them in your CustomAction (in my case the CommandAction attribute of a CommandUIHandler since I was building a custom ribbon button).

So I crafted my CommandAction like this:

<CommandUIHandler CommandAction="javascript:viewDialog({ItemId});"/>

I simply call my custom JavaScript method and pass it the {ItemId} token. Inside my JavaScript (which I added to my solution as another CustomAction in a mapped folder to Layouts) I have this snippet:

function viewDialog(id) {  
    var options = {    
        url: "/sitename/Lists/ListName/ViewName.aspx?ID=" + id,    
        width: 800,    
        height: 600,  
    };  
 
    SP.UI.ModalDialog.showModalDialog(options);
}

This takes in an id as a parameter (the {ItemId} token) and builds up the options to pass to the showModalDialog method on the SP.UI object.

The result is a custom button that links to another view passing it the id for the current item.

What’s sad is that it was a bugger trying to find that piece of knowledge. A few people have written short blogs on it but it’s not very discoverable. The 2010 version of the MSDN documentation doesn’t include the URL Token section and frankly its misplaced IMHO. It seems you can use these tokens on any custom action whether it’s a UrlAction or CommandAction. I’m sure there are other uses for it and it’ll be handy in the future.

Hopefully I didn’t kill any kitten or unicorns (or worse, zombies) in answering my own question on Stack Overflow.

If the universe explodes later you’ll know why and you can freely blame me. In the meantime, enjoy this snippet of knowledge.



  • Sponsored Links

  • April 2011
    M T W T F S S
    « Mar   May »
     123
    45678910
    11121314151617
    18192021222324
    252627282930  
  • .

    Copyright © 1996-2010 Answer My Query. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress