2005 2006 2007 2008 2009 2010 2011 2015 2016 2017 2018 aspnet azure csharp debugging docker elasticsearch exceptions firefox javascriptajax linux llblgen mongodb powershell projects python security services silverlight training videos wcf wpf xag xhtmlcss

XmlHttp Service Interop - Part 2 (Utilizing WCF)

Today I'm publishing the second in an article series regarding XmlHttp Service Interop. In this article, entitled "Utilizing WCF", I explain how to build WCF services, how to trace their XML messages, and how to communicate with them and other SOAP services via raw XmlHttp.

Instead of posting the entire thing on my blog, from here on out I'm going to be posting articles in their own pages to make them easier to read and easier to access. This will also make it easier for me to update and edit as well. You may access this article as well as others in the series by the links below.

.NET Slides

Back in 2005 I taught a class where I gave an overview of various parts of the .NET universe (at the time, the WinFX universe). I covered everything from C# to data binding to ASP.NET to service-oriented architecture to web standards. My goal was to give a familiarization with each of the topics so that the students can then learn the topics on their own in a way that best fits them.

My first session, however, was a presentation experiment. Instead of using really nasty verbose slides, I had just a few words on a slide and on one slide I had simply the number 42. Don Box would have loved my presentation. The point of the experiment was to make sure that people were paying attention to the topic and not simply reading a useless slide. I really think that PowerPoint is a massive hindrance to education. You can access my experimental presentation, named .NET Overview, below.

My next to last session was on web standards and in this session I simply told a story and then gave a few examples showing how web standards development is the only web development that is acceptable. You can access this presentation, named Web Standards Presentation, below.

Below is also a link to a video where Don Box talks about giving great technical presentations. I would recommend this video to anyone who gives talks on really any topic. Don't just watch it, study it. It takes practice.

English Standard Version Bible Web Service via WCF

The WCF version of this died years ago. The new versions are at https://bitbucket.org/davidbetz/esv-bible-services-for-.net

Many of the applications that I create are Bible based applications and my designs are made easier thanks to the the English Standard Version of Scripture. Long before I used it for development, I fell in love with it and made it my primary Bible version, not only because it's an incredible Bible translation with incredible accuracy and amazing readability, but also because it's so widely accessible. Their website at http://www.gnpcb.org/esv/ is by far one of my favorite websites. I can read on my screen, adjusting the font-size on a whim or click on an audio link to listen to any chapter in a variety of formats. Furthermore, they have great Firefox support and great technical articles explaining the internals of the system.

Not only that, you can also access the ESV text through e-mail and through a SOAP interface. Being someone deeply involved with interop and someone who has commited myself to the study of Scripture I am overjoyed to have the ability to directly access the ESV Bible data source. That said, now adays I'm a WCF user and the ESV Bible Web Service interface has methods and properties which, when used in WCF, are very Java-ish. Not a problem... I went ahead and got the svcutil code and modified it a bit to make the proxy follow the .NET Framework Design Guidelines. I cleaned up the svcutil output, added XML comments, added an added enumeration class and then split into different files for easier modification. Feel free to take the classes and combine them back into one proxy file as you wish. Here is a sample application using the fixed proxy:

using (var client = new ESVBibleClient( )) {
    var options = new OutputOptions( );
    options.IncludeFootnotes = true;
    options.IncludeCopyright = true;
    options.OutputFormat = OutputFormat.PlainText;

    String text = client.DoPassageQuery("TEST", "1 John 2", options);

    Console.WriteLine(text);
    Console.ReadLine( );
}

XmlHttp Service Interop - Part 1 (Simple Service Creation)

This entry is the first is a series on XmlHttp Service Interop.

In my day job I am constantly making diverse systems communicate. I make classic ASP talk to the .NET 2.0 Framework, .NET systems talk with Java systems, a Pascal-based system communicate with a custom .NET mail server, and even make .NET components access systems from the stone age. I love interop, but I'm finding that many people don't. From what I see, it seems to be a lack of understanding more so than a lack of desire. It's actually some pretty cool stuff and you can find great books on various interop topics.

While I do work a lot with COM, ES, and web service interop, my favorite communication mechanism is via straight XmlHttp calls. It's just so easy to do and support for it is just about universal. You can take JavaScript and make a call to ASP.NET, go to a VBS WScript and make a call to a web service, or force the oldest, nastiest product in your company to communicate with WS-* services. In this part of the series, we are going to discuss XmlHttp in general and see a call from JavaScript to a manually created service endpoint.

To start off with lets make it clear what we are and are not talking about. We are not talking about sockets or direct TCP calls nor are we talking about a service framework. XmlHttp is a way to transfer XML over HTTP. However, even though we talk about XML, in your using XmlHttp you'll find that this isn't a requirement at all, so, at root what we are doing is making simple HTTP calls.

To see what we're talking about in action, lets create a simple XML service endpoint that accepts a well-defined XML format to allow the sending of e-mail. Then, lets access the service via JavaScript. This is very similar to something I recently created to allow a very old system to send e-mails using the .NET Framework. Of course, in that situation I used the programming language of the system in question (Pascal), not JavaScript.

To begin with lets create the client. I know it seems a bit backwards, but lets look at this from the standpoint of a framework designer: look at how it will be used first, then implement mechanics. Now, the first thing we need to do this is a simple "htm" document. I want the page to be "htm" for the sake of this demonstration, simply to show that there is no server-side processing at all in this page.

Next, we need a way to access our endpoint. I'm not going to get into severe detail about how to do this in every single browser in the world, but, rather, I'm only going to show the standardized way. You can quickly do a search online to see how to extent this behavior to IE5 and IE6.

Skipping the lame setup and stuff many 6th graders can do, let's get right to the core of what we are going to do. The full implementation of everything seen here is in an accompanying VS2005 solution. It would probably be a good idea to have that open as you go through this.

To send a request to a server, simply use syntax similar to the following:

var xmlhttp = new XMLHttpRequest( ); xmlhttp.open('POST', ' Service.aspx', true); xmlhttp.onreadystatechange = function ( ) { if(xmlhttp.readyState == 4) { alert(xmlhttp.responseText); } }; xmlhttp.send(data);

This syntax works in any version of Firefox, the newer versions of Opera, and IE7 (or what I like to call " IE6.5"). Basically, what's happening here is this: you are creating a new instance of an HTTP requestor, giving it some connection information, setting a callback function, and sending some data to the service.

The part that you should look at closely is the XMLHttpRequest::open (note: my double colon syntax is from C++ and simply means Class::Member)function. This obviously takes three parameters: the HTTP method, the HTTP endpoint, and a boolean stating asynchronous communication. I want this to be an asynchronous call, so I'm setting the third parameter to true. I'll come back to the HTTP method in a moment and the HTTP endpoint is just the service address.

After that we see that the property XMLHttpRequest::onreadystatechange is being assigned a JavaScript anonymous function. If you are unfamiliar with these, just think of them as anonymous delegates in C# 2.0. This is the function that's going to be called when the state of the XmlHttp call changed. When inside this function, there are a few parameters you can look at when this function gets calls, but here I'm only testing one: readyState. This property basically states the status of the call. Notice the XMLHttpRequest property is called "onreadystatechange", not "oncomplete". This function is actually called when the state of the HTTP request changes. When I test for readyState == 4 I'm looking for round trip completion. Frankly, you probably never touch the values 1, 2, and 3 though you could check for 0, which means that the XMLHttpRequest::open function has not yet been called. In this situation, if the readyState is 4, then I want to display a message box showing the response content, which is accessible via XMLHttpRequest::responseText. One other very important property you will definately be using a lot is the XMLHttpRequest::status. This property gives values like 404, 415, 500, and so on. If the request did a successful round trip the status will be 200, so that's something you'll probably be testing for quite a bit.

Finally we see the XMLHttpRequest::send method. This simply sends a set of data to the service... well, kind of. In the XMLHttpRequest::open, the first parameter, the HTTP method, is very important. Depending on what you want to do you will either set it to GET or POST. If you are calling a pre-existing page that has no idea what a HTTP stream is, but knows about querystrings, then you will want to use GET. In this situation, you will want to put parameters in the querystring in the HTTP end point, that is, in the second parameter of XMLHttpRequest::open. However, if you are creating your own service, you may want to use POST instead as using POST makes the development on both the client and service simplier. On the client, you don't pack stuff in the querystring (though you still could) and on the server, you can access the data via a stream rather than via parsing the URL or doing any iteration. As that last sentence implies, by using the POST method you send the data you want to submit to the HTTP endpoint as a parameter of the XMLHttpRequest::send function. For those of you who understand WCF terminology, you can think of the HTTP method as being analogous to the WCF binding and the HTTP endpoint as being analogous to the WCF address. The only thing analogous to the WCF contract is the XML schema you use to create your data stream.

Now, since we are sending the information in the data variable to the service, we need to put something in it. For this service, I'm using the following XML, though it doesn't have to be XML at all.

var data = ''; data += '<Mail>'; data += '<ToAddresses>'; data += '<ToAddress>johndoe@tempuri.org</ToAddress>'; data += '</ToAddresses>'; data += '<CcAddresses>'; data += '</CcAddresses>'; data += '<BccAddresses>'; data += '</BccAddresses>'; data += '<FromAddress>no-reply@tempuri.org</FromAddress>'; data += '<Subject>XmlHttp Service Interop - Part 1</Subject>'; data += '<DateTime>03-08-07 2:26PM'; data += '</DateTime>'; data += '<Body>This is the message body.</Body>'; data += '</Mail>';

Given proper event management in JavaScript, you have everything you need to have a fully functional client. Now onto the server.

As we saw when we looked at the client code, the service endpoint is Service.aspx . To help us focus on the task at hand, we aren't going to do anything fancy like using URL aliasing (aka URL rewriting) to make it look cooler, though in reality you would probably do that.

In the code behind for the Service.aspx, we have code that starts like this:

XmlDocument doc = new XmlDocument( ); doc.Load(Request.InputStream); XmlNode documentRoot = doc.DocumentElement; XmlNode mailRoot = documentRoot.SelectSingleNode("//Mail");

Here what we're doing is creating a new XmlDocument and loading the data streamed from the client into it. Then we are getting the root of the document via XPath. The rest of the code is in the accompanying project and simply consists of a bunch of XPath queries to get the information from the document.

After we found all the values we needed in the XML document, either via XPath or another mechanism, we can do whatever we want with what we found. The important point is this: all we have to do is a simple Response.Write ("") to send data sent back to the client, which in turn changes the readyState in the previously seen JavaScript to 4, thus allowing the client to display the output in the alert window. It's really just as simple as this: the client sends stuff to the service, the service does something and sends stuff back.

Now, we could beef this up a bit by adding some HTTP headers. This is something you may find yourself doing often. To do this, use XMLHttpRequest::setRequestHeader to set a key/value pair on the connection. Here's an example.

xmlhttp.setRequestHeader('X-App-Source', 'My Client');

That 'X-App-Source' was completely made up. You could use 'My Awesome Service Caller' if you wanted. That doesn't matter, what does matter however is that you put this after the call to XMLHttpRequest::open or else you will seriously want to throw something across the room, because it's a painfully subtle error that will cause the call will fail every time.

On the server side, to access a header, simply do this:

String xAppSource = Request.Headers["X-App-Source"];

I know. You were expecting something a bit more profound. Okay, I can satisfy that need. If you have many headers and you want them all, here's what you can do.

foreach (String header in Request.Headers) { // Do whatever you want... }

Whatever you do, try to fight the temptation to do this:

Dictionary<String, String> headers = new Dictionary<String, String>( );
foreach (String header in Request.Headers) {
    headers.Add(header, Request.Headers [header]);
}

As nice as that looks, if you really want to have a headers key/value pair collection, you can just do this:

NameValueCollection headers = Request.Headers;

Regardless of what you do with the headers, remember that they are there for a reason and if you do a lot of service calls, you will find yourself using HTTP headers a lot. This is something you will see in the next part of the series.

So, that's a quick overview of XmlHttp. Please see the solution provided with this post for the full code. The next part of the series discusses making manual XmlHttp calls to WCF.

Materials

Comments Fixed

A few weeks ago I started to flood my public blog with parts of the next CTP of Minima. Then I took a break for a week or so, but in my flooding I carelessly broke comments and didn't find out about it until today. Oops!

So, if you left a comment anywhere you'll have to resubmit the comment.

Sorry!

The Universal HttpHandlerFactory Technique

In the past two months I've done more with HttpHandlers than probably anything else. One technique that I'm finding myself use a lot is one that uses a universal HttpHandlerFactory to filter ALL ASP.NET 2.0 traffic. In fact, this is exactly what I'm doing in the next release of Minima. The next release actually has many HttpHandlers, each utilized by a master HttpHandlerFactory. Here's an example of what I'm doing and how you can do it too:

First, I create a wildcard mapping in IIS to:

c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll

When doing this you want to make sure to uncheck the "Verify that file exists" or else your pages will have to actually exist. For most of the HttpHandlers that I create, the pages that are being accessed are completely imaginary.

Next, I create my HttpHandlerFactory. The normal way of doing this is to create a class which implements the IHttpHandlerFactory, have your logic in the GetHandler method do whatever it must do, and then return an instance of a class implementing IHttpHandler. If I don't want to do anything fancy with the request, I can just process it as an ASPX page. Unfortunately, since we are going to run EVERYTHING in the website through the HttpHandlerFactory, we can't do that. Why? The HttpHandlerFactory that processes ASPX pages is PageHandlerFactory, which you can't return from our custom HttpHandlerFactory. Here's what I mean...

public IHttpHandler GetHandler(HttpContext context, String requestType, String url, String pathTranslated) {
    if (url.EndsWith("/feed/")) {
        return new FeedHttpHandler( );
    }
    else {
        return new PageHandlerFactory( );
    }
}

The preceding code in no way compiles. First off, PageHttpFactory implements IHttpHandlerFactory (well, IHttpHandlerFactory2, which in turn implements IHttpHandlerFactory), NOT IHttpHandler. Secondly, though completely irrelevant by the first reason, the single constructor for PageHttpFactory is marked as internal.

Fortunately, however, we can get around his by actually inheriting from PageHttpFactory and overriding the GetHandler, which is marked as virtual.

Here's an example that does compile and works beautifully:

namespace MyProject.Web.HttpExtensions
{
    public class MyProjectHttpHandlerFactory : PageHandlerFactory
    {
        public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) {
            if (context.Request.Url.AbsoluteUri.EndsWith("/feed/")) {
                return new FeedHttpHandler( );
            }
            if (context.Request.Url.AbsoluteUri.Contains("/files/")) {
                return new FileMapperHttpHandler( );
            }
            if (context.Request.Url.AbsoluteUri.Contains("/service/endpoint/")) {
                return new XmlServiceHttpHandler( );
            }
            if (context.Request.Url.AbsoluteUri.Contains("/images/")) {
                return new ImageProcessorHttpHandler( );
            }
            else {
                return base.GetHandler(context, requestType, virtualPath, path);
            }
        }
    }
}

To complete the solution, you simply have to add the following in your web.config file:

<httpHandlers>
  <add verb="*" path="*" type="MyProject.Web.HttpExtensions.MyProjectHttpHandlerFactory"/>
</httpHandlers>

Now we are filtering all content through our HttpHandler. By doing this, you have full control of what URLs mean and do without having to screw with a ton of strange HttpHandlers in your web.config file. Furthermore, by doing it this way you get better control of what your web.config looks like. In Minima, for example, I have a type which controls all access to various configurations. My primary HttpHandlerFactory looks at this type to determine what paths do what and go where. You can either use the defaults in Minima or you can override them in the web.config file.

Regardless of what you do, the point is you can do anything you want. I often find myself creating virtual endpoints for web services allowing access in a variety of ways. In one service I recently created I actually have parameters coming in in the form of a URL (http://MyWebsite/Endpoint/ABCCompany/). My HttpHandlerFactory notices that a certain handler is to handle that particular type of request and then returns an instance of that particular handler. The handler then obtains the parameters from the URL and processes the request appropriately. Very little work was done in the actual setup and almost no work was done in IIS, it's all magically done via the master HttpHandlerFactory.

More Flexible XAG Properties

Recently, I found myself constantly writing classes that have many properties with no backing fields (i.e. use ViewState) or are get-only. So, I added this feature to XAG. Now, you can set the "Mode" to "GetOnly" or "SetOnly" and "Backing" to either "true" or "false". Keep in mind that set-only (write-only) properties aren't exactly the best thing to use. If you find yourself wanting to do that, you should really reexamine what you're doing.

Furthermore, I wanted the ability to have values cascade to others. So, now you can set things like the Mode, Backing, Static, and AccessModifier on the entire Properties or Methods group instead of the individual properties or methods.

Here's an example of all this:

<Assembly xmlns:x="http://www.jampadtechnology.com/xag/2007/02/" DefaultNamespace="MyCompany.MyProject.Confguration">
  <ProjectConfiguration Type="Class" AccessModifier="Internal" Static="True">
    <Properties Mode="GetOnly" Backing="False" AccessModifier="Internal">
      <ProjectTitle Type="String" />
      <DatabaseConnectionString Type="String" />
      <ErrorEmailToAddress Type="String" />
      <ErrorEmailFromAddress Type="String" />
      <AutoNotifyOnError Type="Boolean" />
    </Properties>
  </ProjectConfiguration>
  <Configuration>
    <appSettings>
      <add key="ProjectTitle" value="My Title" />
      <add key="DatabaseConnectionString " value="..." />
      <add key="ErrorEmailToAddress " value="dfb@davidbetz.net" />
      <add key="ErrorEmailFromAddress " value="no-reply@tempuri.org" />
      <add key="AutoNotifyOnError " value="False" />
    </appSettings>
  </Configuration>
</Assembly>

In addition, I changed the XAG interface a bit to make it much more user friendly. Personally, I use my WPF version, which I'll probably be releasing soon (as well as documentation for the Web Service).

Data Feed Framework Overview Video

To make understanding and usage easier, I recorded a video on my Data Feed Framework. This video is an overview, a demo, and basically video documentation. Everything in the video is covered in the documentation file I posted on the original blog entry.

Data Feed Framework (DFF) can be used to greatly simplify the creation of RSS feeds and the aggregation of RSS and Atom feeds on websites. Please see the original blog entry for more information (link below).

Data Feed Framework - February 2007

Back in late 2005 I created a system which I'm now calling the Data Feed Framework (DFF) to greatly simplify the creation of RSS feeds and the aggregation of RSS and Atom feeds on web sites. The goal of the feed creation portion of the system was to allow developers and IT professionals to create RSS feeds with little to no work at all thereby allowing them to use RSS for purposes other than blogging or news. The goal of the aggregator portion of DFF was to the integration of information into ASP.NET 2.0 pages.

The Data Feed Framework has two primary components :

  • FeedCreation
  • InfoBlocks

Using the FeedCreation mechanism, developers and IT professionals can quickly create RSS feeds to monitor internal SQL databases, create sales RSS feeds for management, or monitor whatever else they wanted. The aggregator portion of the system, called InfoBlocks, allows web developers to declare a control in ASP.NET 2.0, give it an RSS or Atom feed and walk away having an InfoBlock on their page containing a list of feed entries for the RSS feed.

The two portions of the system work together, but can also be used separately.

To make explaining this a bit easier, below is a link to my documentation for the system. Below that are the links for the source of the system as well as screen shots. I'll soon be creating a video to go over the basic concepts of this system.

I can't over emphasis how simply this system makes RSS creation and RSS/Atom aggregation. It's literally a matter writing a SQL statement. Absolutely no more work than that is required. The simplicity is very much like that simplicity in WCF. Where WCF relies primarily on attributes and a config file, I rely simply on a SQL Server 2005 table called "FeedCreation". You literally write a SQL statement and give it a name and you have a complete RSS feed ready for corporate or public distribution. I'm planning on incorporating this system into the core of Minima in the next CTP.

The license for this is simple: use it all you want for whatever you want, customize it to your own needs, but 1) ALWAYS keep the copyright notice in there and 2) I nor my companies are liable for anything. The typical stuff...

Update: This project has been renamed to SQL RSS Services and has been updated for .NET 3.5 using LINQ and the syndication feed support in WCF.

Related Links

WCF Relative Binding Speed Demo Updated

Last year I released a simple demo showing the relative binding speeds of the various native bindings in WCF. Since that time, WCF the syntax has changed a bit making my original code obsolete. Now I'm posting the the source code based on the final version of WCF.

Here are the changes I made (most are simply to update):

  • The client proxies changed from "Proxy" to "Client"
  • <service type="..."> changed to <service name="...">
  • The 'mex' binding was added.
  • ServiceEndpoint was moved to System.ServiceModel.Description
  • On the service interface, the ServiceContract attribute ProtectionLevel was set to ProtectionLevel.None so that security is not required, thus giving a more accurate benchmark.

You can use these as a bases for you own services, but you may also wish to look at my XML Assembly Compiler which has a WCF service template. You can simply select the template, perhaps design a few types and interfaces, and let it create your entire WCF project for you.

Links