Я получил некоторую документацию от одного из наших поставщиков для веб-службы, которую они публикуют, и они очень специфичны, что в одном из их WebMethods аргумент имеет модификатор out (? Не уверен, что это правильный дескриптор), например, рассмотрите следующая подпись WebMethod:
[WebMethod]
public void HelloWorld(out string strVal)
{
strVal = "Hello World";
}
[Очевидно, что настоящий метод не является методом Hello World]
Я никогда не думал о разработке WebMethod с аргументом out / ref, и это заставило меня задуматься, зачем они его использовали.
Пытаясь понять приложение для этого дизайнерского решения, я бросил прототип вместе с несколькими базовыми веб-методами в стиле Hello World ... один с одним строковым аргументом, другой с двумя строковыми аргументами и один, который не получает никаких аргументов, но возвращает строка.
Пытаясь сослаться на мои веб-методы из отдельного приложения, я замечаю, что мне нужно получить доступ к методу с единственным строковым аргументом, точно так же, как если бы я определил метод для вывода строки, так что в действительности для клиента:
public string HelloWorld1()
{
return "Hello World";
}
а также
public void HelloWorld2(out string strVal)
{
strVal = "Hello World";
}
точно такие же ... в том, что я должен ссылаться на них обоих как на таковые [где x заменяет правильный метод]:
string val = HelloWorldX();
Попытавшись ссылаться на методы так, как я бы получил к ним доступ, если бы они не были веб-методами [вот так]:
string val = string.Empty;
MyService1.HelloWorld(out val);
Console.WriteLine(val);
что вызывает ошибку компиляции, указывающую, что ни один аргумент метода не принимает 1 ввод. Это почему? Очевидно, существует веб-метод, который принимает один аргумент - я смотрю на него [HelloWorld2].
Изучив ответы SOAP, я заметил, что содержимое ответа для HelloWorld1:
<HelloWorld1Response xmlns = "http://tempuri.org/">
<HelloWorld1Result>string</HelloWorld1Result>
</HelloWorld1Response>
И HelloWorld2 это
<HelloWorld2Response xmlns = "http://tempuri.org/">
<strVal>string</strVal>
</HelloWorld2Response>
Пройдя еще дальше, я подумал, что, если у меня есть 2 аргумента ref ...
public void HelloWorld3(out string strVal1, out string strVal2)
{
strVal1 = "Hello World";
strVal2 = "Hello World Again!";
}
Это генерирует содержимое SOAP:
<HelloWorld3Response xmlns = "http://tempuri.org/">
<strVal1>string</strVal1>
<strVal2>string</strVal2>
</HelloWorld3Response>
Я думал достаточно справедливо, поэтому теоретически [при условии, что я могу найти способ передать аргументы / ref в WebMethods], это означает, что я могу просто передать два аргумента, которые могут быть установлены методом, но когда я сделаю это:
string val1 = string.Empty;
string val2 = string.Empty;
MyService1.HelloWorld3(out val1,out val2);
Console.WriteLine(val1);
Console.WriteLine(val2);
Я должен получить ту же ошибку компиляции, что и при попытке сослаться на HelloWorld2 таким образом. За очевидным исключением, что он жалуется на 2 аргумента вместо 1 [и на самом деле я получаю такое же исключение, я его тестировал].





Может это поможет:
Моя любимая часть:
STATUS
This behavior is by design.
Я не знаю, каков протокол предоставления ответов на ваши собственные вопросы, но статья, на которую ссылается Стивен Бенке, дала мне некоторые подсказки, чтобы найти решение этой странной ситуации. И вместо того, чтобы оставлять всех остальных разбираться с последствиями, я подумал, что поделюсь своими выводами.
Итак, рассмотрим следующие веб-методы, определенные в моем WebService:
[WebMethod]
public string Method1()
{
return "This is my return value";
}
[WebMethod]
public void Method2(out string strVal1)
{
strVal1 = "This is my value passed as an output";
//No return value
}
[WebMethod]
public void Method3(out string strVal1, out string strVal2)
{
strVal1 = "This is my strVal1 value passed as an output";
strVal2 = "This is my strVal2 value passed as an output";
//No return value
}
[WebMethod]
public string Method4(out string strVal1, out string strVal2)
{
strVal1 = "This is my strVal1 value passed as an output";
strVal2 = "This is my strVal2 value passed as an output";
return "This is my return value";
}
Теперь, согласно документу, первый параметр определен как Out, если метод возвращает void, то первый параметр автоматически используется как возвращаемый параметр. Итак, я бы получил доступ к каждому из моих методов следующим образом:
Метод 1:
public string Method1() {}
var str = svc.Method1();
Console.WriteLine(str);
Метод 2:
public void Method2(out string strVal1) {}
var str = svc.Method2();
Console.WriteLine(str);
Таким образом, вы получаете доступ к ним одинаково, что очень сбивает с толку. Кто на Земле мог бы это понять, если бы не услышал об этом от кого-то другого? Я не понимаю, как это могло быть хорошей идеей.
Метод 3:
public void Method3(out string strVal1, out string strVal) {}
var str2 = String.Empty;
var str1 = svc.Method3(out str2);
Console.WriteLine(str1);
Console.WriteLine(str2);
Метод 4:
public string Method4(out string strVal1, out string strVal2) {}
var str1 = String.Empty;
var str2 = String.Empty;
var str3 = svc.Method4(out str1, out str2);
Console.WriteLine(str1);
Console.WriteLine(str2);
Console.WriteLine(str3);
Итак, как вы заметили - если подпись метода не предоставляет возвращаемого значения [которое возвращает void], тогда первый параметр становится возвращаемым значением. Если он уже предоставляет возвращаемое значение, значит, это не так.
Это может сильно сбить с толку тех, кто не сталкивался с этим документом. Большое спасибо за ссылку, Стивен - я очень ценю это.
Для тех, кто решил, что этот шаблон проектирования - хорошая идея для написания в .NET Framework - я не могу представить, что заставило вас думать, что это хорошая идея. После всего этого ты мне действительно сильно не нравишься.
ДОБАВЛЕНИЕ:
Я только что понял, что, чтобы добавить путаницы, если вы используете ссылка вместо вне, тогда вы сделаете это не, вы будете обращаться с WebMethods точно так же, как если бы вы использовали их для вызова обычного метода внутри вашего заявление:
[WebMethod()]
public void Method3(ref string strVal1, ref string strVal2)
{
strVal1 = "First argument return value";
strVal2 = "Second argument return value";
}
Теперь, чтобы вызвать это, вы бы использовали:
string val1 = String.Empty;
string val2 = String.Empty;
svc.Method3(ref val1, ref val2);
Console.WriteLine(val1);
Console.WriteLine(val2);
Это несоответствие ошеломляет. То, что это сделано по дизайну, мне непонятно.
Когда вы достигнете репутации 2000 года, я считаю, что правильным протоколом было бы отредактировать ответ Стивена Бенке ... как бы навязчивым он ни казался. Но хорошая работа по размещению вашего резюме. +1
Хорошо, спасибо - статья была очень информативной. Мой единственный комментарий к этой дизайнерской идее: «Кто, черт возьми, придумал эту идею, она облажалась!»