« April 2007 | Main | June 2007 »

2007.05.28

WCF Web Ask

So a couple of proposals, a presentation at a internal conference, and some work on our [long overdue] website makeover, I am ready to start playing with the model some more. Two things immediately come to mind. I am going to address the first one here.

So, if you've never had the distinct pleasure of working directly with softies, you may not recognize a peculiar quirk of their culture, an "ism" if you will. That quirk is the tendency to convert verbs into nouns. So, if you are working with a client that has an incumbent non-MS infrastructure, then you are working a "compete." If you have a question or request or favor, it is often referred to as an "Ask."

SO.

This is an ASK.

I want an ognl or xpath-like syntax in uri templates to allow me to map down into object. So, instead of:

        [OperationContract]

        [WebInvoke(Method = "PUT", UriTemplate = "/customer/{id}" )]

        void PutCustomer(int id, Customer customer );

I could instead have

        [OperationContract]

        [WebInvoke(Method = "PUT", UriTemplate = "/customer/{customer.id}" )]

        void PutCustomer(Customer customer);

This might also be helpful when I use post to create a new customer, e.g.

        [OperationContract]

        [WebInvoke(Method = "POST", UriTemplate = "/customers" )]

        [Location(UriTemplate = "/customer/{return.id}" )]

        Customer CreateCustomer(Customer customer);

Note that the location header does not exist currently. It is my suggestion of how you might specify the location header when a resource has been created via POST. I threw "return" in there as a variable to reference the return value. The idea is definitely half-baked at best, but I think that, given that we're using HTTP as the contract here, and HTTP says return a location header, then it makes sense that we provide a way in the contract to handle that.

I think it would also be interesting to modify the template behavior to adopt some uri conventions codified in Sam Ruby and Leonard Richardson's new book Restful Web Services. From Udell's post:

"[use] commas to encode ordered siblings (/parent/child1,child2), and semicolons to encode unordered siblings (/parent/red;green)."

So, we could do something like GET /customers/1,2,3,4,5, and receive back the customers specified by the list, e.g.

        [OperationContract]

        [WebInvoke(Method = "GET", UriTemplate = "/customers/{ids}" )]

        List<Customer> CreateCustomer(int[] ids);

I hope that you find that useful feedback.

2007.05.22

Free .NET 3.0 e-learning

Here are some free e-learning seminars from Microsoft on .NET Framework 3.0.  You can activate a license to access them for a full year.  These offers often don't stay out there forever, so activate now and you'll have a year to come back and view them.

2007.05.20

Microsoft Popfly

 

Popfly looks really cool. I can't wait to get an invite. Here's a funny q&a from the FAQ. Good to see the sense of humor.

Q: Why did you call it Popfly?

A: Well, left to our own devices we would have called "Microsoft Visual Mashup Creator Express, May 2007 Community Tech Preview Internet Edition," but instead we asked some folks for help and they suggested some cool names and we all liked Popfly.

Source: Microsoft Popfly

2007.05.18

Contracts?

 

Patrick Logan (whose blog I've stalked for probably 4 years now) comments on my suggestion that we don't always need "contracts."

"Do we need contracts?" Always. The misunderstanding is in answering "what is a contract?" Design-time checked overspecifications are not the only form of contract. For example, the HTTP spec is a contract. The Atom Protocol spec is a contract that builds on that.

He's right. I was treating WSDL and contract synonymously in the context of the post, but perhaps what i should have said is "Do we need *another* contract [over and above HTTP]?"

I agree that there is a good bit of confusion on what constitutes a contract. In my opinion, the problem is with the use of the word "contract" at  all. At a minimum, we need a hunch, some patience, a good sense of humor and forgiveness, and a good lawyer.

Now, beyond that, we often desire a description (may be informal, does not require agreement, may offer no warranty), and we might want a specification (more formal, does not require but may afford agreement, may afford some warranty), and in certain cases, we need a contract (formal, requires agreement, may afford warranties in both directions, may allow for third party arbitration, legal or monetary recourse, etc). Or at least that is how I think about it.

Source: thinking-out-loud: Some Interesting History

2007.05.13

Syntax Across Programming Languages

Nice cross-ref for features/languages.

Link to Syntax Across Programming Languages

2007.05.10

I got an offer that I couldn't refuse

And it is distracting me from playing with WCF. Darn. Stay tuned.

2007.05.08

WCF Web Smackdown - Round 2

 1. Jef 0.

OK. So, I picked myself up, dusted off, and got ready for round 2. Now that I have been sufficiently schooled on the virtues of WebServiceHostFactory, I am ready for my next baby steps. But first, I wanted to demo the simple service and do a quick review. I ripped out all of the <system.serviceModel> configuration, slammed in my factory attribute on the servicehost directive:

<%@ ServiceHost Language=C# Debug="true" Factory="System.ServiceModel.Web.WebServiceHostFactory" Service="Improving.Samples.WCF.Web.Hello" %>

using System.ServiceModel;

using System.ServiceModel.Web;

 

namespace Improving.Samples.WCF.Web

{

    [ServiceContract()]

    public class Hello

    {

        [OperationContract]

        [WebGet()]

        public string Say()

        {

            return "Hello, Cruel World";

        }

    }

}

 

read another blog post from Steve to be on the safe side, and hit f5.

 

 

Ha. Oops. So, I actually know what this problem is. In WCF, endpoints don't map to Services but rather to methods. So when I browse to /Service.svc, I am not actually addressing an endpoint, I am addressing a class that contains methods that are exposed as endpoints in WCF terms. I can fix it by appending the method name to the URL (/Service.svc/Say):

 

I can also (almost) fix it with a wildcarded UriTemplate, but we'll save that for tomorrow. As mentioned, the model is currently a little picky about trailing slashes, so /Service.svc/Say/ yields the first image above.

 

Now.

 

If we revisit the service contract defined above, the only thing excluding the WebServiceHostFactory that is specific to ol' Webby is the WebGet attribute. If we look at the web get attribute, it defines a couple of public properties that allow us to shape the messaging a bit, BodyStyle and UriTemplate. We'll take a glance at BodyStyle first.

 

BodyStyle is an instance of the enumeration type, WebMessageBodyStyle:

public enum WebMessageBodyStyle
{
    Bare,
    Wrapped,
    WrappedRequest,
    WrappedResponse
}

Bare is the default value, and results in the <string ... /> encoding you see above in the browser. It would be a lot more interesting with a more interesting serializable type. WebMessageBodyStyle.Wrapped returns something like:

 

 

WrappedRequest and WrappedResponse give you control over the individual messages. I won't demonstrate those further.

 

I'll look a little more closely at UriTemplate tomorrow. Following that, I want to pllay around with basic HTTP types of things like cache awareness, content negotiation, json, status codes, headers, chunked encoding, streaming, async models, etc. Once we get all of that squared away, I'll start using the API to do "real" stuff. Then I'll dig into the syndication support, etc.

 

Quick review: Currently, I think that IHttpHandler has a slight leg up on WCF in terms of simplicity and adhering to the principle of least astonishment. One thing I do get from the model is serialization to and from .NET types. That is pretty cheap with DataContractSerializer, XmlSerializer, and friends. Another thing that I get is a more simplistic method of mapping HTTP methods to .NET methods, so I can avoid having a Servlet-like interface and I can avoid writing a switch statement. The Microsoft namespace for serialization is interesting, but I would want to avoid that. It's a bit too leaky an abstraction for me, though I suppose I grok why it's there. We haven't done anything terribly interesting yet, so I am still feeling very positive about the model. There's some good stuff under the hood. UriTemplates, for example. Looking forward to it.

Thank you

Steve gave me the course correction I needed. Thank you thank you thank you. So, I'll try to get back to the Smackdown shortly. In the meantime, I wanted to overemphasize a point on the libraries. Steve mentioned this already but *please* *please* don't let the fact that these assemblies are folded into the Biztalk Services SDK deter you from using them. Neither the very cool services that you can interface with via the Biztalk Services SDK or the model require licenses for Biztalk.

Don Box had a really funny bit on how shipping software at Microsoft is like getting riders on bills in the US Legislature, and that they just wanted to set ol' Webby (as I've taken to calling the WCF Web programming model) free it to the world rather than sweat the particulars of the 'branding' of the vessel on which it was freed.

WCF for the Web - a Smackdown

I thoroughly enjoyed the opportunity to learn about the new model, and I am very excited to see the capabilities baked into WCF. The web is a great platform for integration, and so having first class support in WCF is critical for WCF to be useful in truly large-scale context. When I was speaking with Steve Maine, I mentioned that my base level for comparison for the programming model is starting from a raw socket. How far off of the raw socket experience am I, and what am I gaining from the extra layers?

OK. I might not actually go all the way down to a raw socket, but I would go at least to a CGI/Servlet/ISAPI Filter/IHttpHandler/HttpListener level. That is, assuming that I don't have to reinvent listeners or perhaps the extensible web server as a concept, how different and flexible is the model? I think that, in the case of Microsoft.ServiceModel.Web, the answer is going to be "A good bit."

But.

So.

My first naive attempt at a SmackDown failed relatively miserably. I thought I would pair up Harry "I Http" Handler versus Spidey "the web" .svc.

So, I added an IHttpHandler:

<%@ WebHandler Language="C#" Class="Hello" %>

 

using System;

using System.Web;

 

public class Hello : IHttpHandler {

 

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/xml";

        context.Response.Write("<Say>Hello, Cruel World.</Say>");

    }

 

    public bool IsReusable { get { return true; } }

}

(Note: I am using Windows Live Writer, and it doesn't allow me to paste rich text content. Argh. Copy Source As HTML to the rescue.)

I do a GET against the Handler, and viola!

Now granted, I am not even checking to see if the method is GET. I might want to add that in, eh? But for now, it works.

I added a WCF service to the web project (I skipped defining a service contract interface at this point to keep it simple. In actuality, I did it both with and without):

<%@ ServiceHost Language=C# Debug="true" Service="Improving.Samples.WCF.Web.Hello" %>

 

using System.ServiceModel;

using System.ServiceModel.Web;

 

namespace Improving.Samples.WCF.Web

{

    [ServiceContract()]

    public class Hello

    {

        [OperationContract]

        [WebGet()]

        // Not very, um, resourcey, but...

        public string GetMessage()

        {

            return "Hello, Cruel World";

        }

    }

}

wired up the service in the web.config, changed the binding from wsHttpBinding to webHttpBinding:

  <system.serviceModel>

    <services>

      <service name="Improving.Samples.WCF.Web.Hello">

        <endpoint contract="Improving.Samples.WCF.Web.Hello" binding="webHttpBinding" />

      </service>

    </services>

  </system.serviceModel>

Do a GET in the browser, and voila!

 

 

 

 

 

 

 

 

 

 

 

 

OK. OK. Minor set back. Let's try to add the binding in:

  <system.serviceModel>

    <services>

      <service name="Improving.Samples.WCF.Web.Hello">

        <endpoint contract="Improving.Samples.WCF.Web.Hello" binding="webHttpBinding" />

      </service>

    </services>

 

    <bindings>

      <webHttpBinding />

    </bindings>

  </system.serviceModel>

 

 D'oh. Another cup of coffee, please. After a bit of reflectoring, I add in the binding extension (which seems weird, because the binding element is a subclass of StandardBindingElement, hmmm... maybe I need to add the assemblies to the WCF directory?):

  <system.serviceModel>

    <services>

      <service name="Improving.Samples.WCF.Web.Hello">

        <endpoint contract="Improving.Samples.WCF.Web.Hello" binding="webHttpBinding" />

      </service>

    </services>

 

    <bindings>

      <webHttpBinding />

    </bindings>

 

    <extensions>

      <bindingExtensions>

        <add name="webHttpBinding"

            type="System.ServiceModel.Configuration.WebHttpBindingCollectionElement, Microsoft.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

      </bindingExtensions>

    </extensions>

 

  </system.serviceModel>

 

 

OK. So, back to the browser and, Voila!

Argh. OK. So, I expected the metadata to be disabled. I didn't exactly expect the help page, but I know how to disable it via the serviceDebug behavior from a previous spelunking exercise:

  <system.serviceModel>

    <services>

      <service name="Improving.Samples.WCF.Web.Hello" behaviorConfiguration="hello">

        <endpoint contract="Improving.Samples.WCF.Web.Hello" binding="webHttpBinding" />

      </service>

    </services>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name="hello">

          <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

 

    <bindings>

      <webHttpBinding />

    </bindings>

 

    <extensions>

      <bindingExtensions>

        <add name="webHttpBinding"

            type="System.ServiceModel.Configuration.WebHttpBindingCollectionElement, Microsoft.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

      </bindingExtensions>

    </extensions>

 

  </system.serviceModel>

 

 

Almost there. I can taste it...

 

  <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">

    <Code>

      <Value>Sender</Value>

      <Subcode>

        <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</Value>

      </Subcode>

    </Code>

    <Reason>

      <Text xml:lang="en-US">The message with Action '' cannot be processed at the receiver,

        due to a ContractFilter mismatch at the EndpointDispatcher.

        This may be because of either a contract mismatch (mismatched Actions between sender and receiver)

        or a binding/security mismatch between the sender and the receiver. 

        Check that sender and receiver have the same contract and the same

        binding (including security requirements, e.g. Message, Transport, None).</Text>

    </Reason>

  </Fault>

 

 

So, at the end of the day, I am beginning to wonder whether I can use  from within IIS/ASP.NET. And I am beginning to believe that the answer is "No." I am sure that if it *is* "No," it is really just a "Not there yet" rather than a "Not going there." There are challenges with integrating especially the URITemplate functionality into the IIS stack, because IIS doesn't really want to talk to you unless you have an extension (e.g. .aspx, .ashx, .svc). I am guessing that they were wrestling with that limitation. If it was an explicit design decision, I would have liked to have known this sooner, e.g. in a readme.txt or, um, say, an SDR presentation. I actually commented about this when I first learned about URITemplate and friends, but the conversation took a bit of a turn, and I didn't push on it. I wish I had have, because it would have saved me some of my spare time to focus on the features that are there today. Unless I hear otherwise, I probably won't spend any more time trying to work from within a web project. Did I stop short of the prize? Or is it actually a limitation for these bits?

For now, we'll be filing this one under "Simple things should simple."

2007.05.06

Ctrl-Q + IE7 = Cool Tiles

 

Todd just told me about a cool feature in IE 7 - Ctrl-Q. Using Ctrl-Q, you can tile all of your open tabs.

Rad.

November 2008

Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
Blog powered by TypePad

We Like