Как анализатор WSDL решает сгенерировать метод void для операции запроса / ответа? - PullRequest
1 голос
/ 29 ноября 2011

Я потратил 5 часов на это, и я уже потратил 30 часов на написание этой спецификации для контракта («агрессивный» крайний срок, эрго глупый), и я не вижу, что мне не хватает.

Я не хочу односторонней операции, поскольку я ожидаю неисправностей.Я уже построил простой сервис WCF и изучил WSDL, который он генерирует, и он делает обход в обратном направлении к пустому методу, но я так долго на него смотрел (а WSDL 1.1 настолько раздражает в лучшем случаераз - катитесь на 2.0, пожалуйста), что я больше не вижу, что такое фокус.

Кто-нибудь может предоставить очень простой WSDL, объясняющий магию?Я нацеливаюсь на jax-ws 2.2 и WCF 3.5 / 4.0 с этим WSDL.Я пишу от руки WSDL и каждый раз, когда пытаюсь создать прокси (в java или .net), он всегда создает метод с сообщением возврата.Я теряю это.

1 Ответ

3 голосов
/ 29 ноября 2011

Метод "void" не обязательно означает, что это односторонняя операция.Две операции ниже отличаются:

[ServiceContract]
public interface ITest
{
    [OperationContract(IsOneWay = true)]
    void Process1();
    [OperationContract]
    void Process2();
}

Первая действительно односторонняя операция - любые исключения / сбои, выданные сервером, не будут распространяться на клиента, в то время как во второй, хотяон ничего не «возвращает», если сервер выдает исключение (например, FaultException), исключение будет возвращено вызывающей стороне.

Обновление : ответитьвопрос, поставленный в заголовке, анализатор WSDL решает сгенерировать пустую операцию (по крайней мере ту, которая используется WCF), если схема для выходного сообщения операции пуста.

Например, в кодениже:

public class StackOverflow_8316567
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract(IsOneWay = true)]
        void Process1();
        [OperationContract]
        void Process2();
        [OperationContract]
        int Add(int x, int y);
    }
    public class Service : ITest
    {
        public void Process1() { }
        public void Process2() { }
        public int Add(int x, int y) { return x + y; }
    }
    static Binding GetBinding()
    {
        var result = new BasicHttpBinding();
        return result;
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.Open();
        Console.WriteLine("Host opened");

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

Если вы запустите его и перейдете к http://localhost:8000/service?wsdl, вы увидите, что:

  1. Операция Process1 (в wsdl: portType /wsdl: operation) имеет только входное сообщение
  2. и Add и Process2 (операции r / r) имеют как входные, так и выходные сообщения

Теперь сообщениечасть для выходного сообщения для этих двух операций ссылаются на их schema в импортированной схеме (на http://localhost:8000/service?xsd=xsd0). Вы можете видеть, что:

  1. Схема для ответа на операцию Process2 (сложный тип Process2Response) является пустым элементом (т.е. пустая последовательность)
  2. Схема ответа для операции Add (AddResponse) представляет собой последовательность, содержащую один элемент (значение xs:int).

Таким образом, процессор сгенерирует метод void для Process2 (поскольку он ничего не возвращает) и метод без пустот для Add.

...