Contact

admin

About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

Error retrieving information from external service.
Audioscrobbler/Last.fm

ClustrMap

Page 1 of 2 in the ASPNET category Next Page

Session Manager Available On CodePlex

Posted in ASP.NET | DNUG Leipzig | Tools and Software at Monday, September 10, 2007 8:09 PM W. Europe Daylight Time

Our Dilemma

For this year's .NET Summercamp 2007 we find ourselves in the lucky position of having more speakers and session suggestions than slots available. What we needed was a session suggestion and rating system allowing our speakers to submit proposals that could later be approved by us. Of course there are large conference management systems out there, often with boatloads of unneeded functionality like billing. We rather wanted to use a simple tool at no cost.

The Solution

So I went and wrote it myself an ASP.NET 2.0 web application. The outcome of my efforts, named Session Manager, is available on CodePlex. Session Manager is free software licensed under the BSD License.

Session Manager Screen Shot

If you're running a user group or plan to organize larger events besides regular user group meetings, Session Manager certainly is worth a try. If you find it not yet perfect, please go ahead grab the source code and customize it to your needs or post a suggestion. I already wrote down some ideas on improvements.

Session Manager was a great opportunity to build an application with the Model View Presenter and WebNavigator patterns in mind. One has to write a little more code (mostly interface definitions) but gains great testability and portability across web and rich clients.

Demo

I've created a demo installation based on the current version. Go ahead and fiddle, you can't damage anything.

Have fun!

The Web Proxy Auto-Discovery Protocol (WPAD)

Posted in ASP.NET | Networking at Thursday, March 01, 2007 6:01 PM W. Europe Standard Time

The Web Proxy Auto Discovery Protocol, WPAD for short, simply does what its name implies. An application connecting to the internet may search the local network to find information about proxies and rules which proxy to use when connecting to specific (i.e. local or remote) servers. WPAD leverages a JavaScript file called wpad.dat that is located on a WPAD server. The file itself is retrieved using HTTP. WPAD has been implemented by Netscape in 1996 has not changed much since then.

Publishing WPAD Information

Basically there are two ways for an application to detect the URL to the WPAD server:

  • There is a DHCP option that tells DHCP clients where wpad.dat can be found on a network. By virtue of DHCP this information is only available to DHCP clients. The DHCP option 252 can be used to return an URL to the wpad.dat file, e.g. http://wpad/wpad.dat. Note that URLs specifying non-standard ports are also possible: http://wpad:79/wpad.dat.
  • The other way to retrieve the wpad.dat script is to do a DNS lookup for a host named WPAD and do a HTTP GET for /wpad.dat on this host. The DNS option, however, provides less information to the client application because it only specifies the server and has no way of transmitting information about the HTTP port to the client.

Different Clients

Although WPAD has not become an internet standard yet, both Internet Explorer and Firefox try to acquire the WPAD script if you configure automatic proxy configuration, but in a slightly different way. Internet Explorer prefers DHCP information over DNS whereas Firefox only uses DNS.

Also, Window's built-in WinHTTP Web Proxy Auto-Discovery Service uses either DHCP or DNS to obtain WPAD information.

Possible Problems

Typically, the wpad.dat script is generated and served served by firewalls and proxy servers like Microsoft ISA Server based on the network configuration (you could also write your own custom WPAD script). The WPAD HTTP server, like any other HTTP server,  listens on port 80 for incoming requests. Because this would lead to conflicting ports if you're running another ("workhorse") HTTP server on port 80 of the firewall/proxy, WPAD-enabled firewalls and proxies typically let you choose an alternative port to listen for WPAD requests. All you need to do is to change the DHCP URL accordingly.

But what about the DNS case? As stated above, DNS does not carry port information. A successful DNS lookup for the WPAD host is all to justify a subsequent HTTP request to the server on port 80. But there's not the WPAD server answering, it's the workhorse HTTP server not knowing about a file called wpad.dat: HTTP/404. Bummer.

Solutions

Of course, you could copy wpad.dat to your "real" workhorse web server. But if the firewall/proxy configuration changes, you would need to copy the file over and over again. Certainly nothing a good network administrator strives for.

  1. One solution I tried was enabling URL rewriting on the workhorse web server and redirect requests for /wpad.dat to the WPAD HTTP server running on the alternative port 79. Although Firefox understands HTTP redirects, they were ignored, presumably for security reasons. Does not work.
  2. proxiing redirect on the server would come in handy, but I couldn't find free ISAPI components doing this. If you like to spend some money, ISAPI_Rewrite may be your choice as it has the RewriteProxy directive. Works, if you are willing to spend money.

Wanting a free solution, I a proxy web site on the workhorse IIS with an ASP.NET IHttpHandler.

  1. Set up your WPAD configuration so that the WPAD HTTP server listens on a port that is not used by other applications.
  2. Create a host (A) DNS entry for the WPAD host, pointing to the IP address of your proxy/firewall that also hosts IIS.
  3. Set up option 252 on your DHCP server giving it a value of http://wpad/wpad.dat. The port can be omitted as we're proxiing requests to the real WPAD server.
  4. Create a new IIS web site on port 80, specify host headers wpad and wpad.your-domain. The web site should run as an ASP.NET 2.0 application.
  5. Add a script mapping for .dat files so that they are processed by %windir%\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll. Be sure to uncheck the "Check that file exists" option.
  6. Put these files in the web site's root folder, allow NTFS read access for IUSR_<Machine Name> and NETWORK SERVICE.
  7. Open web.config with a text editor and adjust the URL to the real WPAD server in the only key of /configuration/appSettings.
  8. Test your WPAD configuration with wget:
    rem Test the real WPAD server, this is what the proxy web site uses.
    wget http://wpad:<alternative port>/wpad.dat
    rem Test the proxy WPAD server, this is what clients use.
    wget http://wpad/wpad.dat
    
  9. Test with Internet Explorer, Firefox and other clients. Take a look at the IIS log files if requests were served with HTTP status code 200.

Now Playing [?]: Fujiya & Miyagi – Cassettesingle

ASP.NET Web Site Administration Tool Flaws

Posted in ASP.NET | Visual Studio at Thursday, February 01, 2007 3:47 PM W. Europe Standard Time

While trying to configure an ASP.NET Web Application using the Web Site Administration Tool in Visual Studio I encountered the following error:

An error was encountered. Please return to the previous page and try again.

The following message may help in diagnosing the problem:
System.Configuration.ConfigurationErrorsException: A configuration file cannot be created for the requested Configuration object.
at System.Configuration.MgmtConfigurationRecord.SaveAs(String filename, ConfigurationSaveMode saveMode, Boolean forceUpdateAll)
at System.Configuration.Configuration.SaveAsImpl(String filename, ConfigurationSaveMode saveMode, Boolean forceSaveAll)
at System.Configuration.Configuration.Save(ConfigurationSaveMode saveMode)
at System.Web.Administration.WebAdminPage.SaveConfig(Configuration config)
at System.Web.Administration.WebAdminPage.VerifyAppValid()

Is the ConfigurationErrorsException really helpful? Actually not, because it's not a configuration error the admin tool encounters but rather a compatibility issue. Consider the path the project is located in, it begins with: D:\Benutzer\Alexander Groß\…. The admin tool doesn't expect paths containing special characters like my last name's "ß".

To work around the issue I created a junction named D:\Benutzer\agross pointing to D:\Benutzer\Alexander Groß and lo and behold, the Web Site Administration tool works now.

Now Playing [?]: Mark Knopfler – What it is

Building UTF-8 Compatible QueryStrings (Not Only) for ASP.NET

Posted in ASP.NET | Browser at Friday, September 22, 2006 8:53 PM W. Europe Daylight Time

Whenever you append a query string to an URL, it's a best practice to URL-encode the query string value. On the server side encoding can be done by three methods of the System.Web.HttpUtility class, depending on the desired output.

Here's an example passing "Encoding Test: abcäöüß" to the methods:

Method Output
HttpUtility.UrlEncode Encoding+Test%3a+abc%c3%a4%c3%b6%c3%bc%c3%9f
HttpUtility.UrlEncodeUnicode Encoding+Test%3a+abc%u00e4%u00f6%u00fc%u00df
HttpUtility.UrlPathEncode Encoding%20Test:%20abc%c3%a4%c3%b6%c3%bc%c3%9f

The single method HttpUtility.UrlDecode() decodes all encoded query strings.

On the client side there are JavaScript functions to encode and decode query strings, namely escape() and unescape(). However, these functions have problems with the correct encoding of UTF-8 strings.

Today I had the same problem described in the article above while debugging search in dasBlog, which uses UTF-8 as the default request and response encoding. You can enable UTF-8 for any ASP.NET web site by including the following element in your web.config.

<globalization requestEncoding="utf-8" responseEncoding="utf-8" />

All search queries containing umlauts were retrieved without umlauts on the server side, so a query for König would result in Knig. The solution was to leverage the newer encoding functions encodeURIComponent() and decodeURIComponent() respectively which handle Unicode.

If you're interested in encoding in general I recommend Scott Hanselman's excellent podcast on globalization and internationalization. It gives a good overview without diving too deep into the details.

By the way, I recommend having a look at QuickRef.org, I really like their fast Ajax-enabled search engine for references of C, C++, CSS, HTML, HTML DOM, Java, JavaScript, MySQL, Perl, PHP and Ruby.

Now playing: New Order - Get ready - Vicious streak

Accessing Controls in SharePoint Web Parts using JavaScript on the Client Side

Posted in ASP.NET | Office | SharePoint at Tuesday, February 14, 2006 4:38 AM W. Europe Standard Time

A rather long title for this post, but that's what it comes down to.

SharePoint WebPartSuppose you want to access controls in the same Web Part on the client side using JavaScript. For instance, you have two DropDownLists placed on a Web Part and you want to fill the second one dynamically based on the selected value of the first DropDownList – a simple master/detail type of control. Postbacks are no option here since a selection change of the upper DropDownList shouldn't bother the server and delay business process by having the user to wait for the result. An Ajaxy approach may also be interesting, but out of the scope of this posting.

I've been struggling with some problems an couldn't find anything about this issue on the web, so I decided to post my findings.

Because it is possible to place a Web Part multiple times on a SharePoint web page, SharePoint Server will assign a unique identifier to each control (that is, a Web Part and some of its child controls¹) to be able to distinguish between Postbacks originating from different Web Parts. The unique ID can be found in the ID attribute of a HTML element and looks similar to this:

TopZone_g_d72e1f89_87e6_4f08_b6c5_165dc560ce8a__ctl1

TopZone defines the location of the Web Part, along with its GUID. The bold part (_ctl1) denotes the ID of the control in question, a SELECT in my case.

The JavaScript code to add an onchange event handler to the master control looks like this:

master.Attributes.Add("onchange",
    String.Format("setDetail(document.getElementById('{0}'));",
    detail.ClientID));

However, this will not work: The location and the GUID of the Web Part is evaluated when the page is rendered. These values then serve as a prefix to the control ID (_ctl1) you set in your own code. You have to retrieve the location/GUID prefix along with the control ID and combine them to the actual HTML ID. Because Web Parts should derive from Microsoft.SharePoint.WebPartPages.WebPart this is pretty easy to achieve.

// Combine the Web Part's ID and the control ID.
master.Attributes.Add("onchange",     String.Format("setDetail(document.getElementById('{0}_{1}'));",     base.ClientID,     detail.ClientID));

¹ Those with an ID or a NAME.

Now playing: Audiomatix - What a day

Page 1 of 2 in the ASPNET category Next Page