Можно ли изменить UriTemplate во время выполнения - PullRequest
1 голос
/ 29 сентября 2011

У меня есть следующий атрибут WebInvoke:

        [OperationContract]
        [WebInvoke(
        Method         = "POST",
        UriTemplate    = "",
        BodyStyle      = WebMessageBodyStyle.Bare,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat  = WebMessageFormat.Json)]

Я бы хотел, чтобы значение UriTemplate было установлено на основе значения времени выполнения. Есть ли способ установить UriTemplate в реализации сервиса во время выполнения?

1 Ответ

5 голосов
/ 29 сентября 2011

Да, вы можете сделать это, если вы используете поведение конечной точки, которое добавляется перед WebHttpBehavior. Это поведение может изменить свойства WebGetAttribute / WebInvokeAttribute. Приведенный ниже код демонстрирует пример поведения, которое изменяет свойство UriTemplate для [WebGet], но оно будет работать так же хорошо для [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();
    }
}
...