Как синтаксический анализатор WSDL решает создать метод void для операции запроса / ответа?

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

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

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

1 ответ

Решение

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

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

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

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

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

public class Stackru_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) имеют как входные, так и выходные сообщения

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

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

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

Другие вопросы по тегам