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

被刻印的时光 ゝ 提交于 2019-12-11 05:51:55

问题


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 the pipeline to add these headers for every call instead of one-at-a-time?


回答1:


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;
        }
    }
}



回答2:


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.



来源:https://stackoverflow.com/questions/6233105/how-do-i-extend-wcf-webhttp-rest-to-support-etags-and-conditional-gets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!