Как синтаксический анализатор 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, вы увидите, что:
- Операция
Process1
(в разделе wsdl: portType / wsdl: operation) есть только входное сообщение - и то и другое
Add
а такжеProcess2
(операции r / r) имеют как входные, так и выходные сообщения
Теперь часть сообщения для выходного сообщения для этих двух операций ссылается на их схему в импортированной схеме (по адресу http://localhost:8000/service?xsd=xsd0). Ты это видишь:
- Схема ответа для
Process2
операция (сложный типProcess2Response
) является пустым элементом (т. е. пустой последовательностью) - Схема ответа для
Add
операция (AddResponse
) представляет собой последовательность, содержащую один элемент (xs:int
значение).
Таким образом, процессор будет генерировать void
метод для Process2
(так как он ничего не возвращает) и не пустые методы для Add
,