.Net WebServices和out / ref WebMethod参数

我收到了一些供应商提供的关于他们正在发布的网络服务的文档,他们非常具体地说,在他们的一个WebMethod上,一个参数有out修饰符(?不确定这是否是正确的描述符),例如考虑以下WebMethod签名:

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

[显然实际方法不是Hello World方法]

现在,我从未考虑使用out / ref参数设计WebMethod,它让我想知道为什么他们会使用它。

试图理解这个设计决策的应用程序我把一个原型和几个基本的Hello World样式webmethods一起抛出…一个带有单个字符串参数,一个带有两个字符串参数,一个没有接收任何参数但是返回一个字符串。

在尝试从单独的应用程序引用我的web方法时,我注意到我必须使用单输出字符串参数来访问该方法,就像我定义了输出字符串的方法一样,以便在客户端方面有效:

 public string HelloWorld1() { return "Hello World"; } 

 public void HelloWorld2(out string strVal) { strVal = "Hello World"; } 

是完全一样的…因为我必须同样引用它们[其中x代替正确的方法]:

 string val = HelloWorldX(); 

尝试以我访问它们的方式引用方法,如果它们不是Web方法[如此]:

 string val = string.Empty; MyService1.HelloWorld(out val); Console.WriteLine(val); 

这会导致编译错误,指出没有方法参数接受1输入。 这是为什么? 显然有一个Web方法接受一个参数 – 我正在看它[HelloWorld2]。

在检查SOAP响应时,我注意到HelloWorld1的响应内容是:

  string  

HelloWorld2是

  string  

更进一步,我想,如果我有2个参考论点怎么办…

 public void HelloWorld3(out string strVal1, out string strVal2) { strVal1 = "Hello World"; strVal2 = "Hello World Again!"; } 

这会生成SOAP内容:

  string string  

我认为足够公平,所以理论上[提供我可以想出一种方法来传递/ 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 [实际上我得到了同样的例外,我测试了它]。

  • 是什么赋予了?
  • 是否有理由或方法在WebMethods中使用我缺少的/ ref参数?
  • 如果有,我如何使用多个out / ref参数引用WebMethods?

呃……我不知道为你自己的问题提供答案的协议是什么,但Steven Behnke引用的文章提供了一些线索,让我推断出这种奇怪情况的解决方案,而不是让其他人弄清楚其含义是什么是的,我以为我会分享我的发现……

因此,请考虑我的WebService中定义的以下webmethod

 [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(输出字符串strVal1){}

 var str = svc.Method2(); Console.WriteLine(str); 

因此,您以完全相同的方式访问它们……这非常令人困惑。 在没有被其他人告知的情况下,究竟谁会想到这一点? 我无法理解这是一个好主意…

方法3:public void Method3(输出字符串strVal1,输出字符串strVal){}

 var str2 = String.Empty; var str1 = svc.Method3(out str2); Console.WriteLine(str1); Console.WriteLine(str2); 

方法4:公共字符串Method4(输出字符串strVal1,输出字符串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,那么你会这样做,你会完全按照你使用它们来调用常规方法时对待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); 

这种不一致是令人难以置信的……事实上,它的设计对我来说是不可理解的。

也许这会有所帮助:

http://kbalertz.com/322624/Proxy-Class-First-Parameter-Service-Method-Returns-Return-Value-Reference.aspx

我最喜欢的部分是:

状态

此行为是设计使然。