Archive

Archive for the ‘JavaScript’ Category

Update Obsolete JavaScriptSerializers

April 2, 2008 Comments off

I have three extension methods in a shared library we use that convert Json back and forth.  The “obsolete” JavaScriptSerializers work just fine—as long as I ignore the warnings from Visual Studio whenever I modify the library.

Along with a few other changes, I set off today to update those extension methods to the new DataContractJsonSerializer.  What a pain.

Here’s what it takes—step-by-step.

1. Decorate all of the classes you wish to serialize with the [Serializable].  This is easy enough for internal, controlled classes.  The [DataContract] attributes do not appear to be needed (feedback?).

[Serializable]

public sealed class School { }

2. Change your two to three lines of simple code into painful MemoryStreams.

The old code, which can be found here, was pretty darned simple.  Use the JavaScriptSerializer and either Serialize or Deserialize.  One returned a string, one returned the object.

Unfortunately, the new DataContractJsonSerializer is a bit more complicated on both sides.

The ToJson extension method:

public static string ToJson(this object obj)

{

var serializer =

new DataContractJsonSerializer(obj.GetType());

      

using (var stream = new MemoryStream())

       {

             serializer.WriteObject(stream, obj);

             return Encoding.Unicode.GetString(stream.ToArray());

}

}

The FromJson extension method:

public static T FromJson<T>(this object obj)

{

var returnObject =

Activator.CreateInstance<T>();

       var serializer =

new DataContractJsonSerializer(returnObject.GetType());

 

using (var stream = new

MemoryStream(Encoding.Unicode.GetBytes(obj.ToString())))

{

              return (T) serializer.ReadObject(stream);

}

}

Gone are the Serialize and Deserialize methods; replaced by ReadObject and WriteObject.  Unfortunately to read/write, a stream is required.  It’s not ‘terrible,’ but is another object to create and destroy.

3. Rerun unit tests.

Thank goodness for tests—nuff said. :)

That’s it.  So far, both the tests and the few places I’d ran additional, manual tests of data objects<->Json, things have worked well with these new methods.  I’d love to hear/understand WHY the methods changed and what benefits dumping to/from streams provides us for extensibility.  I’m sure there’s a reason.

Oh, and Visual Studio doesn’t throw warnings anymore—yay.

IE8 – JavaScript window.open invalidates session?

March 14, 2008 6 comments

Anyone else having this problem?  On web sites (my own included) that open a new window with the JavaScript window.open method, that new window no longer has access to session variables from the parent.

In IE7 and FF2, if I have a page that:

Session[”MyVar”] = “Hello, world”;
ClientScript.RegisterClientScriptBlock(
     this.GetType(),
     “PopupReport”,
     “<script language=’javascript’>window.open(‘RunReport.aspx’)</script>”);

Then, RunReport.aspx could read Session[”MyVar”] and output ‘Hello, world’.  That works fine.

Unfortunately, in IE8, the spawned window from window.open doesn’t have access to those session variables.  I ran across this again reading through some Microsoft Training materials—the new window couldn’t tell I was logged in—and there was nothing (that I could figure out) to fix it.

Going into IE7 mode doesn’t appear to fix it either, which is a bummer.

Ideas?

 

Categories: JavaScript, Microsoft

New Articles Section and AJAXing in .NET Article

January 11, 2008 7 comments

Last year, I had several requests to take my “longer” blog posts and series and make articles out of them.  I understand where readers are coming from and empathize—reading 4–5 posts that are 2–3 pages long across a week of entries can be… very disconnected.  In addition, code formatting, images, and such are difficult to get exactly right on a blog image (I tend to avoid capturing code in images so that it’s still searchable).

So, to that, I’ve added a new section to the blog, Articles.

In this, I’ll tend to focus on using the blog for short bits of information, key points, and summaries of various topics.  The Articles section will be for the longer, in-depth reviews of technologies, practices, and guides.

The first post in this section is from the recent AJAXing in .NET series

AJAXing in .NET – #3 – Live Volta and Script#

January 8, 2008 Comments off

This is the third and final part of the series looking at several “AJAXing” technologies for .NET—ranging from “old school” JavaScript to new, VERY alpha technologies like Volta.

Post 1:

  • Example #1 – Plain ASP.NET Page with PostBacks
  • Example #2 – ASP.NET AJAX with UpdatePanels

Post 2:

  • Example #3 – Standard HTML and JavaScript
  • Example #4 – ASP.NET AJAX Framework and JavaScript

Post 3 (this post):

  • Example #5 – Nikhil Kothari’s Script#
  • Example #6 – Microsoft Labs Live Volta

This post, to be totally honest, will be short.  Why?  After FAR too long of dinking with them, I simply can’t get either solution to work.  Here’s where I’m at NOW.  Once I get these working, I’ll better evaluate them against current JavaScript solutions.  That said, the sheer idea of learning a language to avoid writing a language seems odd at best…

#4. Microsoft Live Labs Volta

I previewed Microsoft Live Labs Voltron Volta back in December and was quite impressed—a Microsoft-designed solution for creating type-safe JavaScript within C#.  I wasn’t thrilled with the special project layouts or 45K of compiled Volta code that attached to each project; however, it’s in … alpha, I expected that.

In our Volta code-behind, we have the following logic. 

public partial class VoltaPage1 : Page

{

 

Select photoList;

Image photoPreview;

 

public VoltaPage1()

{

InitializeComponent();

photoList.Change +=

new HtmlEventHandler(photoList_Change);

}

 

void photoList_Change()

{

photoPreview.Style.Display = “block”;

       photoPreview.Src =  “Images/” + photoList.Value;

}

 

partial void InitializeComponent()

{

photoList =

Document.GetById<Select>(“PhotoList”);

photoPreview =

Document.GetById<Image>(“PhotoPreview”);

}

}

That compiles, is easy to read, and type safe.  Neato.  The HTML code is identical to our prior examples, so a simple copy and paste from there.  That saves some time.

The problem?

It appears that Volta doesn’t appreciate resources that are not embedded.  I’ve posted up to the Volta community groups and will slowly work through either a) rectifying what the correct code should be or b) accepting that this is “outside the scope” of the current Volta design.  I can’t fathom having hundreds of embedded resources in a project—for simple graphics.

Finally, it appears the problem that Henry discussed in my last post also exists in Volta—Document.GetById isn’t case sensitive at all. :(  Thanks Henry for the heads-up to keep that in mind!

[Update: 10 January 2008 : Danny van Velzen’s explaination in the forums helped out a lot.  At this time, as expected, the CTP simply doesn’t support anything besides embedded resources; however, has logged the request as a future work item.  *cheer*  To work around this problem, he recommended a post-build event, which is basically a batch command.  I’ve tried that out and this example works like a champ!

The only gotcha is figuring out where to copy the files to and what correlates to the “root” of your application.  It’s not the root of our bin\Debug or bin\Output.  It’s the Volta directory underneath.  With that information, you can write up a quick event:

xcopy /i /y “$(ProjectDir)Images” “$(TargetDir)Volta\Images”

Given this simply copies the images for this prototype project; however, you could use these events to copy pages, .css, or anything that you didn’t feel like “embedding” into your project.  As I noted on the Volta communities post—I’m looking forward to this maturing and having this functionality built into the compiler. :)

With this updated information, I can finally compare implementation with our other options..

  • HTML Code: 9, Code Behind: 5 with whitespace and method names.
  • To me, this code is just as simple to read as JavaScript—maybe a bit easier because it’s strongly typed and hooks up event handlers just like .NET code.
  • All tests come back clean—and Volta supports FireFox debugging out-of-the-box, which is great because I have come to prefer FireBug over the IE Developer Toolbar.
  • Pitfalls are, at this time, the fact it’s VERY alpha and still in development.  Most of the DOM appears to be ready to go, however, issues like the embedded resources make this impractical for production use at this time.  In addition, Volta requires a special project type for its tier-splitting—you can’t just drop some Volta/JavaScript into a project and go.  That’s a HUGE drawback to me.  I’d love to see the technology integrated into the existing web platform so I could program JavaScript like this against Web Forms, MVC, or whatever.

#5. Script# 0.4.5.0

The latest build of Script#, 0.4.5.0, appears to have a few glitches in the Scriptlet editor (cutting out the top and bottom lines, throwing compile errors when they don’t exist, etc) and after blowing through about a dozen project—it just won’t compile.  Period. 

Here’s the code for the class.  It looks right, from what I have as examples, but blows up that I have extra “}” (which is a known bug apparently) and believes that my IDisposable doesn’t exist, though I see it right there. :(

using System;

using System.DHTML;

using ScriptFX;

using ScriptFX.UI;

 

public class Viewer : IDisposable

{

    private SelectElement _photoList;

    private ImageElement _photoPreview;

    private DOMEventHandler _photoListOnChangeHandler;

 

    public Viewer()

    {

        _photoListOnChangeHandler =

new DOMEventHandler(PhotoListOnChange);

        _photoList =

(SelectElement)Document.GetElementById(“PhotoList”);

        _photoList.AttachEvent(“onchange”, _photoListOnChangeHandler);

    }

 

    public void PhotoListOnChange()

    {

        _photoList =

(SelectElement)Document.GetElementById(“PhotoList”);

        _photoPreview =

(ImageElement)Document.GetElementById(“PhotoPreview”);

 

        _photoPreview.Src = “Images/” + _photoList.Value;

    }

 

    public void Dispose()

    {

        if (_photoListOnChangeHandler != null)

        {

            _photoList =

(SelectElement)Document.GetElementById(“PhotoList”);

            _photoList.DetachEvent(“onchange”, _photoListOnChangeHandler);

 

            _photoListOnChangeHandler = null;

        }

    }

}

I’m going to keep working with it (because the prototypes I have gotten working have worked well, but also don’t seem to work under 0.4.5.0) and I’ll update this post when I have more information.  If anyone out there is a Script# expert and has 0.4.5.0 up and going with VS2008, email me, please. :).

AJAXing in .NET – #2 – Pure JavaScript and AJAX Framework JavaScript

January 7, 2008 7 comments

This is the second in the three part series looking at “AJAXing” technologies for .NET developers.

Post 1:

  • Example #1 – Plain ASP.NET Page with PostBacks
  • Example #2 – ASP.NET AJAX with UpdatePanels

Post 2 (this post):

  • Example #3 – Standard HTML and JavaScript
  • Example #4 – ASP.NET AJAX Framework and JavaScript

Post 3 (this post):

  • Example #5 – Nikhil Kothari’s Script#
  • Example #6 – Microsoft Labs Live Volta

In these two examples, we’ll take a look at the differences of JavaScript programming—between “standard” JavaScript and using the methods and objects provided by the ASP.NET AJAX Framework, but without using the actual server-side controls.

#3. Standard HTML and JavaScript

The next example is a classic—clean HTML and a JavaScript function.  This is a standard HTML page without any “fancy” .NET or framework technologies.  How does this compare to .NET?

In our header, there’s a simple JavaScript function to handle the OnChange event of the drop down list:

<script type=”text/javascript” language=”javascript”>

function LoadPhoto()

{

PhotoPreview.style.display = ‘block’;

       PhotoPreview.src = Images/ + PhotoList.value;

}

</script>

Next, our HTML.

<select id=”PhotoList” onchange=”LoadPhoto()”>

<option label=”ABCs – Blocks” value=”abc_blocks.jpg” />

       <option label=”ABCs – Chalkboard #1″ value=”abc_board.jpg” />

       <option label=”ABCs – Chalkboard #2″ value=”abc_board2.jpg” />

       <option label=”Graduation” value=”capandgown.jpg” />

</select>

<br /><br />

<img id=”PhotoPreview” style=”display: none; src=”” />

As we can see from the Fiddler capture, the HTML, of course, is EXTREMELY thin here and, since postback events are not firing, the page ever reloads, simply loads the resources (in this case, images) as necessary.  In addition, the images are cached, so additional downloading isn’t necessary..

  1. HTML Code: 8 + 2 4 JavaScript function lines (see below).
  2. I may be a bit older, but this is how it “used” to be done, so it’s readable to me.  For those unfamiliar with JavaScript may be turned off by it.
  3. IE 7 and Safari (*shocked*) work, however, Opera and FireFox are broken.  See details below.
  4. As you’ll read below, managing compatibility between JavaScript functionality on each platform is a HASSLE and can be a major turn off for DIY JavaScript AJAX.

Details for Compatibility Issues:

IE 7 and Safari actually render correctly because they use the “label” property from HTML 4.0 for option boxes.  FireFox and Opera turn out blank.  To have options in those browsers, we’ll need to place the text in the body of the tag. 

<option label=”ABCs – Blocks” value=”abc_blocks.jpg”>
ABCs – Blocks
</option>

That fixes Opera, but FireFox is still broken.  Why?  Because FireFox can’t read the DOM directly, you have to populate each element into a variable and manipulate the variable.  Updating our JavaScript to the following code will fix the problem.  Also, since this method works in all the OTHER browsers, this would be the “preferred” method to accomplish this.

var photoPreview = document.getElementById(‘PhotoPreview’);

var photoList = document.getElementById(‘PhotoList’);

 

photoPreview.style.display = ‘block’;

photoPreview.src = ‘Images/’ + photoList.value;

While this code works, you can run into challenges for browsers that do not yet support getElementById.

#4. ASP.NET AJAX Framework and JavaScript

In our last example, browser compatibility was the most challenging pitfall to overcome.  If we want to write our own JavaScript, but would like the padding of a framework, we can use the ASP.NET AJAX framework without all the fancy server-side controls.

When we add a new AJAX Web Form, a single control is added, the ScriptManager.  In this example, we’re not going to use UpdatePanels, but simply access the objects provided for us by the ScriptManager.

The JavaScript in our Header:

<script type=”text/javascript”>     

function LoadPhoto() {    

       $get(‘PhotoPreview’).style.display = ‘block’;

       $get(‘PhotoPreview’).src = ‘Images/’ + $get(‘PhotoList’).value;

}

</script>

And the HTML:

<asp:ScriptManager ID=”ScriptManager1″ runat=”server” />

<select id=”PhotoList” onchange=”LoadPhoto()”>

<option label=”ABCs – Blocks” value=”abc_blocks.jpg”>

              ABCs – Blocks</option>

<option label=”ABCs – Chalkboard #1″ value=”abc_board.jpg”>

              ABCs – Chalkboard #1</option>

<option label=”ABCs – Chalkboard #2″ value=”abc_board2.jpg”>

              ABCs – Chalkboard #2</option>

<option label=”Graduation” value=”capandgown.jpg”>

              Graduation</option>

</select>

<br /><br />

<img id=”PhotoPreview” style=”display: none; src=”” />

The $get alias simply returns browser-compatible JavaScript for getElementById.  You can read more about how this alias works on Irena Kennedv’s blog.  The short is that this alias will generate the correct code based on the browser.

The Fiddler logs are nearly identical to the plain JavaScript; however, the .aspx page is a bit heavier.

  1. HTML Code: 9 + 2 JavaScript function lines.
  2. Aside from familiarization with the aliases and framework functions in JavaScript, this code is nearly identical to the
  3. The only difference at this point is that the code allows us to access the $get alias and, most importantly, cross-browser compatibility handled by the framework—not you.
  4. Past the bit of losing “update panels”, this is a nice middle ground between pure JavaScript and pure server-side AJAX Framework.

This methodology also has another benefit: you can directly access web services (.asmx) from your JavaScript client code.  For more information on this topic, read Calling Web Services from Client Script.  I haven’t done a lot with this yet, but have a few notes sitting around to give it a try and see how it compares when reading actual data across the wire.

AJAXing in .NET – #1 – Plain ASP.NET and ASP.NET AJAX

January 7, 2008 2 comments

With the release of Microsoft Live Labs Volta, Nikhil Kothari’s recent update of Script# to support VS 2008, the ASP.NET AJAX Library’s new functionalities, and good ‘ol JavaScript—developers are not limited on AJAX solutions for the Microsoft platform.  Given, JavaScript can be on any platform, I tend to focus more on .NET solutions. :)

One of my holiday projects was to weigh and see exactly what went back and forth across the wire for each of these technologies and compare that to:

  • Implementation lines of code,
    • I don’t count using statements, headers, and “required” coding lines, simply those lines that implement the solution.
  • Intuititiveness of code,
    • Does the code make sense to write?
  • Browser support,
    • Does it work and look the same on IE 7.0, FireFox 2.0, Opera, and Safari?
  • Weight of transmissions (using Fiddler).
    • How much data is going across the line for comparable transactions?
  • Pitfalls?
    • What are the gotchas?

Download Source Code : Download Project Solutions (coming soon)

Note: This project contains two solutions, one for Volta project and one for all the others.

To make this a bit easier to read (and to write :) ), I’ve broken the content into a series of posts.

Post 1 (this post):

  • Example #1 – Plain ASP.NET Page with PostBacks – Seeing our prototype page with standard ASP.NET—no AJAX.  This will provide our baseline.
  • Example #2 – ASP.NET AJAX with UpdatePanels – The “default” implementation of the ASP.NET AJAX Framework—using UpdatePanels to manage partial rendering with “postbacks” still happening in the background.

Post 2:

  • Example #3 – Standard HTML and JavaScript – This is the “old” way to do things: directly manipulating the DOM.
  • Example #4 – ASP.NET AJAX Framework and JavaScript – Manipulating the DOM using the aliases and cross-browser compatibility features of the AJAX Framework.

Post 3:

  • Example #5 – Nikhil Kothari’s Script# – Script# is a scripting solution that sits on top of the C# development environment.
  • Example #6 – Microsoft Labs Live Volta – Previewed before, we’ll build the same example as the rest of the examples in Volta for comparison.

Now, let’s get started!

#1. Plain ASP.NET Page – Postbacks

Moving into .Net, let’s start with a simple ASP.NET page—no AJAX involved.  This page has a drop down list (PhotoList) and an image control (PhotoPreview)—populating the image control OnChange of the drop down list.

<asp:DropDownList ID=”PhotoList” runat=”server” AutoPostBack=”true”

OnSelectedIndexChanged=”PhotoList_SelectedIndexChanged”>

<asp:ListItem Text=”ABCs – Blocks” Value=”abc_blocks.jpg” />

<asp:ListItem Text=”ABCs – Chalkboard #1″ Value=”abc_board.jpg” />

<asp:ListItem Text=”ABCs – Chalkboard #2″ Value=”abc_board2.jpg” />

<asp:ListItem Text=”Graduation” Value=”capandgown.jpg” />

</asp:DropDownList>

<br /><br />

<asp:Image ID=”PhotoPreview” runat=”server” Visible=”false” />

In our code behind:

protected void PhotoList_SelectedIndexChanged(object sender, EventArgs e)

{

PhotoPreview.ImageUrl = “~/Images/” + PhotoList.SelectedValue;

       PhotoPreview.Visible = true;

}

Using Fiddler, an HTTP debugging tool, we can see that each time the page is requested, it posts back and grabs the image.  It’s also important to note that there isn’t any caching at this point.  Notice how events #39 and #43 request the same image and transmit it.

Using our scale above:

  • HTML Code: 9, Code Behind: 2
  • Being standard HTML and .NET code-behind, this is easily readable and makes sense. 
  • As we can see from the image below, the page looks much the same on every browser (given, it’s pretty basic).  The browsers, clockwise from top-left, are: Safari b3, IE 7, Opera 9, and FireFox 2.
  • Avoid postback “flash” is the most common, I think, to implement some sort of AJAX technology—cleaning up a UI and improving the user experience.  The lack of caching (with the post back) is also a trouble; however, caching could be implemented with additional coding.

#2. ASP.NET AJAX with UpdatePanel

Our first method would be the standard ASP.NET AJAX technique—surrounding those two controls with an UpdatePanel and adding a ScriptManager to the page.

<asp:ScriptManager ID=”ScriptManager” runat=”server” />

<asp:UpdatePanel ID=”UpdatePanel” runat=”server”

UpdateMode=”Conditional”>

<ContentTemplate>

<asp:DropDownList ID=”PhotoList” runat=”server”

AutoPostBack=”true”

OnSelectedIndexChanged=”PhotoList_SelectedIndexChanged”>

<asp:ListItem Text=”ABCs – Blocks” Value=”abc_blocks.jpg” />

<asp:ListItem Text=”ABCs – Chalkboard #1″ Value=”abc_board.jpg” />

<asp:ListItem Text=”ABCs – Chalkboard #2″ Value=”abc_board2.jpg” />

<asp:ListItem Text=”Graduation” Value=”capandgown.jpg” />

</asp:DropDownList>

<br /><br />

<asp:Image ID=”PhotoPreview” runat=”server” Visible=”false” />

</ContentTemplate>

</asp:UpdatePanel>

While our UI hasn’t changed, our HTTP traffic has changed quite a bit.  Here we can see the WebResource and ScriptResource files pull down to the local client and cache as well as the first load of the page.  What is interesting here is that on request #89, I’ve rerequested the capandgown.jpg image, but it never re-requests it, the cached image just loads on the client.  Good deal and MUCH faster.

Using our scale above:

  • HTML Code: 14, Code Behind: 2
  • This is the basic way of implementing the ASP.NET AJAX Framework—enclosing existing controls in panels and letting partial rendering do it’s magic.  I see this as very intuitive syntax.
  • Functionality is identical on all four platforms; this is because the ASP.NET AJAX framework handles browser support for us via ScriptManager.
  • As you can see from the Fiddler log, this page is extremely heavy—trading off smooth performance during usage for a resource load at the page load.

Flash and Proxy Support on .NET WebBrowser Controls

January 3, 2008 10 comments

At work, I’ve been dealing with Big Brother for the past few weeks (well, before the holiday break)—attempting to both accomplish a bit of work and some play in light of our annoying filter (blocking MSFT blogs, forums, community sites, and almost all useful search engines).

I love Daniel Mackey’s Pandora’s Box application, an encapsulation of the web browser for playing Pandora; however, it doesn’t support proxy servers.  I found a few other players, but, it appears, that IE 7 screws up a few things and the proxy settings don’t work correctly.  Bleh.  So, okay, it’s web browser and I’m a web developer—this can’t be that hard.

Heh.  If I only had a dollar for each time I said that…

Creating a Flash-enabled WebBrowser Control

One of the drawbacks to the current .NET WebBrowser control is that Flash, for some reason, can’t operate.  It just sits there—staring back at you.  I came across a post a few months ago to fix this.  It was originally targeted at 2.0, but seems to work just fine in 3.5

The fix?  Create a new user control and inherit from the WebBrowser control.  The only work is to override the WndProc method:

protected override void WndProc(ref Message m)

{

switch (m.Msg)

       {

             case 0×021:

             case 0×201:

             case 0×204:

             case 0×207:

                     base.DefWndProc(ref m);

                    return;

}

base.WndProc(ref m);

}

If you’re not familiar with how Windows forms messages are processed, you can find more information on MSDN.

Important: If you’re developing on an x64 (64–bit) machine, you must change your compile target platform to x86 (32–bit).  The WebBrowser control renders according to your platform—x64 in 64–bit, x86 in 32–bit.  Most of us use the 32–bit version of Internet Explorer on our x64 Windows because plugins, such as Flash, only have 32–bit editions.  In this case, Flash will not be able to load under the x64 WebBrowser control and will throw errors.

Implementing the Flash-enabled WebBrowser Control

I’m not real original on my control names… my derived control is called FlashWebBrowser.  Good deal.

To implement the control, add a Form to your page and size accordingly.  You can drag/drop your controls onto the form; however, for this example, I chose to do everything in code behind.

public partial class PandoraForm : Form

{

private FlashWebBrowser flashBrowser = new FlashWebBrowser();

 

       public PandoraForm()

       {

            InitializeComponent();

            flashBrowser.Dock = DockStyle.Fill;

            flashBrowser.AllowWebBrowserDrop = false;

            flashBrowser.IsWebBrowserContextMenuEnabled = false;

            flashBrowser.WebBrowserShortcutsEnabled = false;

            flashBrowser.ScriptErrorsSuppressed = true;

                       

            Controls.Add(flashBrowser);

            Load += new EventHandler(Form1_Load);

       }

Our flashBrowser object applies a few common attributes, such as filling the form and locking out the context menus.  Also, you’ll notice ScriptErrorsSuppressed.  Any JavaScript errors will pop-up automatically using the WebBrowser control (on IE, they’re visible in the status bar and only displayed if you explicitly have the option set to); this causes quite a bit of annoyance using services like Pandora, Google, and Flickr.  ScriptErrorsSuppressed will… suppress those errors.

Information: I’d like to caveat that last statement with a note.  It will USUALLY suppress those errors.  For some reason, IE 7.0 seems to ignore that statement and still throws the errors.  *sigh*  More information can be found ala Google.  I’m still researching this and hope to have a better understanding soon.

Our final method, Form1_Load as specified above, simply contains our flashBrowser’s Navigate method.

private void Form1_Load(object sender, EventArgs e)

{

flashBrowser.Navigate(http://www.pandora.com/?cmd=mini&#8221;);

}

Implementing Proxy Support for the WebBrowser Control

I haven’t cleaned this up into the FlashWebBrowser control yet, but I wanted to post this up for those interested.  Proxy support is REALLY useful if you’d like a particular application or service to use a proxy server, but don’t want to deal with the hassle of constantly changing your Internet settings.

You could use the HttpWebRequest object, pass along a WebProxy, and go that route.  However, quite honestly, I haven’t worked out how you can apply that to a WebBrowser control—only at the console.  I’m sure it can be done and may be more secure than this method, but this forum code works.

Cleaned up, the code looks like:

public struct INTERNET_PROXY_INFO

{

public int dwAccessType;

public IntPtr proxy;

public IntPtr proxyBypass;

};

 

[DllImport(“wininet.dll”, SetLastError = true)]

private static extern bool InternetSetOption(IntPtr hInternet,

int dwOption, IntPtr lpBuffer, int lpdwBufferLength);

 

private void RefreshIESettings(string strProxy)

{

const int INTERNET_OPTION_PROXY = 38;

const int INTERNET_OPEN_TYPE_PROXY = 3;

 

INTERNET_PROXY_INFO struct_IPI;

 

// Filling in structure

struct_IPI.dwAccessType =

INTERNET_OPEN_TYPE_PROXY;

struct_IPI.proxy =

Marshal.StringToHGlobalAnsi(strProxy);

       struct_IPI.proxyBypass =

Marshal.StringToHGlobalAnsi(“local”);

 

       // Allocating memory

       IntPtr intptrStruct =

Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI));

 

       // Converting structure to IntPtr

       Marshal.StructureToPtr(struct_IPI, intptrStruct, true);

 

       bool iReturn = InternetSetOption(IntPtr.Zero,

INTERNET_OPTION_PROXY,

intptrStruct,

Marshal.SizeOf(struct_IPI));

}

wininet.dll is the Windows library that contains most of the internet functions used by Windows and Windows-based applications.  Proxy settings are not the only things configurable using this API; for more information, read here.  Also, for a full understanding of what this code is doing, MSDN has a nice walkthrough demonstrating the various options and how to get/set them.

With that method added to our project, there’s only one change needed—we need to call our RefreshIESettings method prior to the Navigate method of our WebBrowser control.  Our Form1_Load method now looks like:

private void Form1_Load(object sender, EventArgs e)

{

RefreshIESettings(“myproxy.server.com:99″);

       flashBrowser.Navigate(http://www.pandora.com/?cmd=mini&#8221;);

}

I want to integrate the proxy settings INTO the WebBrowser control—and still might.  When that’s done, I’ll post up the code.  For now, however, that’s it.  We now have a WebBrowser control and a baby Windows Forms application that loads up a Flash site, like Pandora AND goes through a proxy server (so I can sit and listen to tunes at work OR be productive and access the MSFT community forums).  Good deal.

Follow

Get every new post delivered to your Inbox.