开发者

How do I extend WCF WebHttp (REST) to support ETags and Conditional Gets?

I have a read-only WCF REST service (all GET's baby!) I'd like to add ETag/Conditional get support to every single operation in my service.

Basically I'm interested in extending the technique in this article: http://blogs.msdn.com/b/endpoint/archive/2010/02/25/conditional-get-and-etag-support-in-wcf-webhttp-services.aspx

My site is backed by a couple of XML files, and my app knows (and raises an event) when any of them change. I don't understand where the extension points are though. How do I hook into 开发者_StackOverflow社区the pipeline to add these headers for every call instead of one-at-a-time?


This turned out not to be so bad. I used an IDispatchMessageInspector which I hooked into a ServiceBehavior that's applied to all my services. I'm a little uncomfortable with how the request gets routed but it seems to work.

public class ConditionalGetMessageInspector : IDispatchMessageInspector
{
    private enum GetState { Modified, Unmodified }

    private string ETag { 
        get { return XmlDataLoader.LastUpdatedTicks.ToString(); }
    }
    private DateTime LastModified { 
        get { return new DateTime(XmlDataLoader.LastUpdatedTicks);}
    }

    public object AfterReceiveRequest(ref Message request, 
        IClientChannel channel, InstanceContext instanceContext)
    {
        try
        {
            WebOperationContext.Current.IncomingRequest
                .CheckConditionalRetrieve(ETag);
        }
        catch (WebFaultException)
        {
            instanceContext.Abort();
            return GetState.Unmodified;
        }
        // No-op
        return GetState.Modified;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        if ((GetState)correlationState == GetState.Unmodified)
        {
            WebOperationContext.Current.OutgoingResponse.StatusCode = 
                HttpStatusCode.NotModified;
            WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = 
                true;
        }
        else
        {
            WebOperationContext.Current.OutgoingResponse.SetETag(ETag);
            WebOperationContext.Current.OutgoingResponse.LastModified = 
                LastModified;
        }
    }
}


That's what a HttpOperationHandler is for in the new WCF Web API http://wcf.codeplex.com I don't know if there is any easy way to do it with WebHttpBinding.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜