Welcome to MSDN Blogs Sign in | Join | Help

Reader Trends

A few of the more noticeable changes in this week's site design might prompt some questions as to how the Web audience is evolving over time. I thought it would be interesting to take a look at the actual numbers that back up reader's requests and complaints by comparing a snapshot from this week with a snapshot from one year ago. In each time period I pulled out a sample of 10000 visitors. The 75% of you that read this through RSS can go back to wondering why anyone still uses a web browser.

Why have site features that don't work or don't look as good in Internet Explorer?

Browsers 1 year ago (1% or higher share)

  • IE7: 45.6%
  • Firefox 2: 25.9%
  • IE6: 23.3%
  • Opera: 2.5%
  • Mozilla: 1.1%

Browsers this week (1% or higher share)

  • IE7: 47.1%
  • Firefox 3: 25.4%
  • IE6: 12.7%
  • Firefox 2: 11.2%
  • Opera: 1.4%
  • Safari: 1.2%

There's one number that is increasing very quickly and the rest are either flat or declining for the most part. I'll credit Silverlight for bringing in enough readers on Safari to make the cutoff.

Why all of the emphasis on font sizes, content spacing, and other issues for large displays?

Resolution of largest dimension 1 year ago

  • Bigger: 28.8%
  • 1280: 46.6%
  • 1024: 23.5%
  • Smaller: 1.1%

Resolution of largest dimension this week

  • Bigger: 40.9%
  • 1280: 45.3%
  • 1024: 13.1%
  • Smaller: 0.7%

I'm evidently atypical in not having moved to increasingly larger displays over the last few years. It turns out that automatic scaling and device independence is still weak enough that you have to do some fine tuning to work over even the most common variations of scale.

Next time: Web Address Filters

Posted by Nicholas Allen | 1 Comments
Filed under:

Trusting IP Addresses

How do I find the address of a client connection to make a trust decision?

Don't base security decisions on the perceived client address. Any address that we have comes from the underlying socket implementation and could be spoofed. The data that the socket has is sourced by the client. You should be using a source of information that has a verification process that the server trusts, such as a certificate, to distinguish clients.

Next time: Reader Trends

Help with Security Programming

Security programming today tends to contain large amount of plumbing code to handle the modeling, management, and evaluation of identities. An identity is the basis of many common security operations, such as authentication, personalization, authorization, and access control. There are a variety of different kinds of identities and ways of implementing security operations on top of those identities. Here are two libraries that help make dealing with identities easier.

Zermatt is a claims-based identity system that focuses on simplifying the use of claims in web services. You can download Zermatt from its Connect site.

LeastPrivilege.IdentityModel is a library by Dominick Baier that simplifies the existing identity model rather than introduces a new one. You can download LeastPrivilege.IdentityModel from leastprivilege.com.

Next time: Trusting IP Addresses

Standards Guide

Looking for a guide to all of the web services protocols implemented by WCF? There's no single document that captures all of the information, but there is a group of documents that talk about the implemented protocols and some of the choices in those implementations. The level of detail varies from document to document as a few are high-level summaries across areas of the product while others are low-level details of a particular protocol.

Next time: Help with Security Programming

Posted by Nicholas Allen | 2 Comments
Filed under: , ,

Annual Site Redesign

I don't actually promise to update the design every year but it makes it sound more exciting- as if there's some kind of recurring event that people might look forward to. This year's design focused on improving content readability. I removed some of the design elements and dead space to get enough room to expand the text size and content area. In the process I lost the indigo-themed color scheme although I hope to bring it back some day. Having both light and dark backgrounds in the main part of the page caused some grief due to the way element styles are used in this template.

The new design rolled out over the weekend to test for any major issues. I've fixed all the ones I know about so let me know if you see something broken. The site is less polished in Internet Explorer than Firefox due to the level of CSS support, but I was able to work around the one major rendering bug I hit.

Posted by Nicholas Allen | 5 Comments
Filed under:

Finding a Client Channel

Where can I get the IContextChannel that OperationContextScope requires?

OperationContextScope allows you to create a temporary scope in which context for a service operation can build up before and after the operation is actually called. The constructor for OperationContextScope takes an instance of IContextChannel, which is a type that you've probably never seen before. Why are you expected to have this unknown type? It's because you have instances of it floating around all the time even though there's no particular hint of this.

There are different ways to get an IContextChannel depending on whether you're using a proxy generated by svcutil or a proxy generated at runtime. In either case, pretend that I've got service contract called IService with a single method called Foo.

When I generate a service client using svcutil, the client object has a member called InnerChannel that works as an IContextChannel.

ServiceClient client = new ServiceClient(binding, new EndpointAddress(address));
using (new OperationContextScope(client.InnerChannel))
{
WebOperationContext.Current.OutgoingRequest.Headers["X"] = "from compiled proxy";
client.Foo();
}
client.Close();

Otherwise, if I'm using a ChannelFactory to create the proxy at runtime, the channel that I get back happens to be an IContextChannel as well.

ChannelFactory<IService> factory = new ChannelFactory<IService>(binding);
factory.Open();
IService proxy = factory.CreateChannel(new EndpointAddress(address));
using (new OperationContextScope((IContextChannel)proxy))
{
WebOperationContext.Current.OutgoingRequest.Headers["X"] = "from runtime proxy";
proxy.Foo();
}
factory.Close();

Next time: Standards Guide

XQuery 1.1 Draft

A working draft for a 1.1 revision to XQuery went up earlier this week. The changes from XQuery 1.0 (which was finished just last year) to XQuery 1.1 appear to be small. There are two additional operators for grouping and windowing over a data stream. The group operator is fairly standard while the window operator is a bit more unusual. Applying a window controls what it means to draw a sequence of consecutive items from the stream.

You can get the complete specification from the W3C site.

XQuery 1.1 W3C Working Draft 11 July 2008

Posted by Nicholas Allen | 1 Comments
Filed under:

Conversation with the C# Team

Channel 9 posted a video a few days ago with the C# 4.0 design team talking about some of their motivations and ideas for language design. I tend to enjoy the videos like this one that are focused on the people a lot more than the ones that are focused on the outputs of technology. It's hard to stay awake while watching someone write code on a board even when played at double speed. There's no problem keeping attention here even though they barely talk about what's changing with the language itself.

Posted by Nicholas Allen | 0 Comments
Filed under:

Hosting Queued Services in IIS

Over the past few days Tom Hollander has been posting his experiences hosting a queue-based WCF service in IIS. These posts go into a lot of detail about setting up the machines, configuring the service, and troubleshooting problems. If you're looking for a step-by-step guide, this is a great resource.

Posted by Nicholas Allen | 1 Comments
Filed under: , ,

Architect Insight Conference Talks

Slide decks are available from the Architect Insight Conference 2008 held in the UK at the end of April. These talks are fluffier than ones that I normally point to and since you only have the slides and not the audio, I recommend picking a few based on their titles and trying them out quickly to see if you find something interesting.

Here are two that I thought looked interesting.

Building an Enterprise Service Bus with BizTalk Server 2006 & WCF

Standardising SOA

You can access all of the content from the post event resources.

Naming Contracts for Versioning

Some tips for building support for versioning into the naming of data contracts.

First, the primary route for versioning should be through the namespace part of the contract rather than the member name part of the contract. Versioning the contract through member names tends to leak across the service boundary more forcefully. The programming experience of the service often makes a member name directly visible while a namespace is more or less invisible.

Second, choose a single consistent scheme for identifying the version. Two popular schemes are the date of the contract and a sequential numbering system of major and minor versions. Both schemes provide the basic element required of a versioning identity, which is an unambiguous total order among the different versions. However, multiple schemes should not be mixed together for a single contract and preferably not for a single system as well.

The date scheme, http://company.com/year/month/name, has issues around granularity but can be very evocative since you probably already associate dates in your mind with other events. The issue with granularity is that you have to plan ahead for a maximum update frequency. In the previous example, two updates in the same month would collide with the same name, suggesting that a contract that is updated frequently might include additional levels of refinement, such as the day of the month. However, unnecessarily fine granularity makes the name cumbersome.

The numbering scheme, http://company.com/major/minor/name, gives less of a clue about what the version corresponds to but has fewer issues with granularity. Updates can happen as frequently as you want since you can just keep picking new numbers. However, you still have to give some thought to granularity when deciding how many numbering components to include. For example, a single version number may be sufficient if no distinction is needed between major and minor updates.

Next time: Finding a Client Channel

Transaction Header Magic

Simplicity is elusive. A few weeks ago I learned that part of transaction flow, propagating information about the source machine between the client and server, is more complicated than I thought. It's not that the details were inherently complicated but rather that they were inconsistent. The information was passed in a certain header of the message, except when using a particular transaction protocol and transport protocol together. Someone noticed that a few bytes could be saved by optimizing this particular combination and in that case put the information in a different header in a different format. Efficiency was achieved at the cost of forcing everyone trying to understand the protocol to think harder about it.

Most of the protocols that have stood the test of time on the web have sacrificed efficiency to achieve simplicity. Consider all of the protocols out there that are large, bloated, and redundant but easy to think about and tolerant to misunderstandings. What keeps them alive against their slimmer and more advanced competition other than that they were able to attract many people to speak them?

Next time: Naming Contracts for Versioning

Posted by Nicholas Allen | 1 Comments
Filed under: ,

Configuring SSL Host Headers

Host headers in IIS are a way to associate multiple names with a single address. The typical use of host headers is to be able to host more than one web site at a single IP address by giving each of the web sites a distinct DNS name. Host headers also play a role in WCF beyond the definition of a web site. Metadata for a web service, such as that appearing WSDL, uses host headers as a way to pick a preferred name when talking about the service.

The user interface for setting host headers is relatively straightforward when the web site is hosted over HTTP but becomes a challenge when the web site is hosted over HTTPS. Here are the command line equivalents that you can use to set HTTPS host headers.

On IIS 6, you need to know the id of the web site. Assuming that SSL is taking place on the default port, the command looks like this.

cscript.exe adsutil.vbs set w3svc/<id>/SecureBindings ":443:<header>"

On IIS 7, the command line looks very different due to the more flexible but complicated support for different web site bindings. You can also use a name that's meaningful for you to distinguish web sites.

appcmd set site /site.name:<name> /+bindings.[protocol='https',bindingInformation='*:443:<header>']

To keep the example simple, I'm assuming that you're adding a new binding rather than modifying an existing binding.

Next time: Transaction Header Magic

Adding Headers to a Call (HTTP Version)

Yesterday I talked about adding SOAP headers to an outgoing request using a variety of different methods. The most straightforward method was to create an OperationContextScope in your application code to establish an OutgoingMessageHeaders collection.

Although HTTP headers are similar in spirit to SOAP headers, manipulating an HTTP header through code looks a bit different. SOAP headers are elevated to a special significance in the programming model. Everything else, including HTTP headers, is relegated to a general-purpose but distinctly second-class collection of message properties.

On the OperationContextScope you'll find a parallel OutgoingMessageProperties collection that can be used for HTTP headers. In Orcas, the plain OperationContext also works as a WebOperationContext that gives the same first-class programming model to HTTP headers as you get with SOAP headers.

Here's a comparison of the two approaches.

using (new OperationContextScope((IClientChannel)proxy))
{
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
requestProperty.Headers["X-header"] = "value1";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
proxy.Operation();
}

using (new OperationContextScope((IClientChannel)proxy))
{
WebOperationContext.Current.OutgoingRequest.Headers["X-header"] = "value2";
proxy.Operation();
}

Next time: Configuring SSL Host Headers

Adding Headers to a Call

How do I add SOAP headers to an outgoing request?

There are a few different ways to add headers to a message depending on how you need to control the header content and where you need to insert the header. I like to think of these methods as being split among the application, the proxy, and the protocol.

In your application code you can create an OperationContextScope around the request in order to change some of the request properties. Inside an OperationContextScope, you have a valid instance of OperationContext.Current, which allows manipulation of the message headers through the OutgoingMessageHeaders collection. Use of this method deeply bakes control of the headers into the application code. You would have to be responsible for copying the appropriate code wherever it was needed.

Now, assume that you want the header to be present whenever you're talking to a particular service and the header value can be determined consistently. Rather than having to put the same code at each call site, you can centralize the code in the proxy or in a protocol.

The simplest way to centralize header manipulation in the proxy is to create an instance of the IClientMessageInspector and attach that to the proxy. This gives you a hook for every message going through the proxy to modify the message headers.

An instance of IChannel similarly gives you a hook for every message going through the channel stack to modify the message headers. Using the Message Interceptor sample gives you an extensibility point in the binding that is similar in spirit to the extensibility point provided by a message inspector.

The primary difference from your perspective of a message inspector and a channel is a matter of timing. A message inspector always runs before any of the protocols in the binding while a channel can be positioned precisely in the protocol stack. In most cases you don't need precise positioning, so you should go with the simpler approach.

Next time: Adding Headers to a Call (HTTP Version)

More Posts Next page »
 
Page view tracker