.Net WebServices и out/ref аргументы WebMethod

Я получил некоторую документацию от одного из наших поставщиков для веб-службы, которую они публикуют, и они очень специфичны, что на одном из своих WebMethods аргумент имеет модификатор out ( "не уверен, что это правильный дескриптор" ) например, рассмотрим следующую подпись WebMethod:

[WebMethod]
public void HelloWorld(out string strVal) 
{ 
    strVal = "Hello World";
}

[Очевидно, что фактический метод не является методом Hello World]

Теперь я никогда не думал о разработке WebMethod с аргументом out/ref, и мне стало интересно, почему они использовали его.

Пытаясь понять приложение для этого дизайнерского решения, я бросил прототип вместе с несколькими базовыми веб-способами Hello World style... один с одним строковым аргументом, один с двумя строковыми аргументами и один, который не получает никаких аргументы, но возвращает строку.

Попытка ссылаться на мои веб-методы из отдельного приложения, я замечаю, что мне нужно получить доступ к этому методу с единственным строковым аргументом точно так же, как если бы я определил метод для вывода строки так, чтобы, по сути,:

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 [и на самом деле я получаю одно и то же исключение, я его протестировал).

  • Что дает?
  • Есть ли причина или способ использования аргументов out/ref в WebMethods, которые мне не хватает?
  • Если есть, как мне обратиться к WebMethods с несколькими аргументами out/ref?

Ответ 1

Er... Я не знаю, что такое протокол для предоставления ответов на ваши собственные вопросы, но статья, на которую ссылается Стивен Бекке, предоставила мне некоторые подсказки, чтобы вывести решение этой странной ситуации и вместо того, чтобы оставлять всех остальных в поиске каковы последствия, я думал, что делюсь своими выводами...

Итак, рассмотрим следующие веб-методы, определенные в моем 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: общедоступная строка 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: общедоступная строка 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 - я не могу думать, что бы вы полагали, что это хорошая идея... Мне очень не нравится вы очень интенсивно после всего этого.

ДОПОЛНЕНИЕ:

То, что я только что понял, заключается в том, что для добавления к путанице, если вы используете ref вместо out, тогда вы этого не сделаете, вы будете обрабатывать WebMethod точно так же, как если бы вы использовали их для вызова регулярный метод внутри вашего приложения:

[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);

Эта несогласованность - это умение... тот факт, что он по дизайну непостижим для меня.