开发者

Is it possible to change the UriTemplate at runtime

I have the following WebInvoke Attribute:

        [OperationContract]
        [WebInvoke(
        Method         = "POST",
        UriTemplate    = ""开发者_如何转开发,
        BodyStyle      = WebMessageBodyStyle.Bare,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat  = WebMessageFormat.Json)]

I would like the UriTemplate value to be set based on a runtime value. Is there any way to set the UriTemplate in the service implementation at runtime?


Yes, you can do that, if you use an endpoint behavior which is added before the WebHttpBehavior. This behavior can change the properties of the WebGetAttribute/WebInvokeAttribute. The code below shows an example of a behavior which changes the UriTemplate property of a [WebGet], but it would work just as well for [WebInvoke].

public class StackOverflow_7590279
{
    [ServiceContract]
    public class Service
    {
        [WebGet(UriTemplate = "/Add?x={x}&y={y}", ResponseFormat = WebMessageFormat.Json)]
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
    public class MyBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            foreach (OperationDescription od in endpoint.Contract.Operations)
            {
                if (od.Name == "Add")
                {
                    WebGetAttribute wga = od.Behaviors.Find<WebGetAttribute>();
                    if (wga != null)
                    {
                        wga.UriTemplate = "/Add?first={x}&second={y}";
                    }
                }
            }
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        var endpoint = host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "");

        // This has to go BEFORE WebHttpBehavior
        endpoint.Behaviors.Add(new MyBehavior());

        endpoint.Behaviors.Add(new WebHttpBehavior());

        host.Open();
        Console.WriteLine("Host opened");

        WebClient c = new WebClient();
        Console.WriteLine("Using the original template (values won't be received)");
        Console.WriteLine(c.DownloadString(baseAddress + "/Add?x=45&y=67"));

        c = new WebClient();
        Console.WriteLine("Using the modified template (will work out fine)");
        Console.WriteLine(c.DownloadString(baseAddress + "/Add?first=45&second=67"));

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜