C# .Net WebServices 和 out/ref WebMethod 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/379648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:16:37  来源:igfitidea点击:

.Net WebServices and out/ref WebMethod arguments

c#.netvb.netweb-services

提问by BenAlabaster

I've received some documentation from one of our suppliers for a webservice they're publishing and they're very specific that on one of their WebMethods that an argument has the out modifier(? not sure if that's the right descriptor) for instance consider the following WebMethod signature:

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

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

[Obviously the actual method isn't a Hello World method]

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

Now, I'd never considered designing a WebMethod with an out/ref argument and it got me wondering why they would've used it.

现在,我从来没有考虑过设计一个带有 out/ref 参数的 WebMethod,这让我想知道为什么他们会使用它。

Trying to understand an application for this design decision I threw a prototype together with a few basic Hello World style webmethods...one with a single out string argument, one with two out string arguments and one that doesn't receive any arguments but returns a string.

为了理解这个设计决定的应用程序,我把一个原型和一些基本的 Hello World 风格的 webmethods 放在一起......一个带有单个输出字符串参数,一个带有两个输出字符串参数,一个不接收任何参数但返回一个字符串。

Upon trying to reference my webmethods from a separate application I notice that I have to access the method with the single out string argument exactly as if I'd defined the method to output the string so that in effect as far as the client is concerned:

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

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

and

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

are exactly the same...in that I have to reference them both as such [where x is substituted for the correct method]:

完全一样......因为我必须引用它们[其中 x 替换了正确的方法]:

string val = HelloWorldX();

Having attempted to reference the methods in the way I would access them if they weren't web methods [like so]:

尝试以访问它们的方式引用这些方法,如果它们不是 Web 方法[像这样]:

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

which causes a compilation error stating that no method arguments accept 1 input. Why is that? There's obviously a web method that accepts one argument - I'm looking at it [HelloWorld2].

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

Upon examining the SOAP responses, I notice that the content of the response for HelloWorld1 is:

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

<HelloWorld1Response xmlns="http://tempuri.org/">
  <HelloWorld1Result>string</HelloWorld1Result>
</HelloWorld1Response>

And HelloWorld2 is

而 HelloWorld2 是

<HelloWorld2Response xmlns="http://tempuri.org/">
  <strVal>string</strVal>
</HelloWorld2Response>

Going a step further I thought, what if I have 2 ref arguments...

更进一步,我想,如果我有 2 个 ref 参数怎么办...

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

This generates the SOAP content:

这将生成 SOAP 内容:

<HelloWorld3Response xmlns="http://tempuri.org/">
  <strVal1>string</strVal1>
  <strVal2>string</strVal2>
</HelloWorld3Response>

I thought fair enough, so theoretically [providing I can figure out a way to pass out/ref arguments to WebMethods] that means I can just pass in two arguments that can be set by the method, but when I do this:

我认为足够公平,所以理论上[前提是我可以找到一种将/引用参数传递给 WebMethods 的方法],这意味着我可以只传递可由该方法设置的两个参数,但是当我这样做时:

string val1 = string.Empty;
string val2 = string.Empty;
MyService1.HelloWorld3(out val1,out val2);
Console.WriteLine(val1);
Console.WriteLine(val2);

I should get the same compilation error I saw when I tried to reference the HelloWorld2 this way. With the obvious exception that it's complaining about 2 arguments instead of 1 [and in fact I do get the same exception, I tested it].

当我尝试以这种方式引用 HelloWorld2 时,我应该得到相同的编译错误。除了明显的例外,它抱怨的是 2 个参数而不是 1 个 [实际上我确实遇到了相同的异常,我对其进行了测试]。

  • What gives?
  • Is there a reason or a way to use out/ref arguments in WebMethods that I'm missing?
  • If there is, how do I reference WebMethods with multiple out/ref arguments?
  • 是什么赋予了?
  • 是否有理由或方法在我缺少的 WebMethods 中使用 out/ref 参数?
  • 如果有,如何使用多个 out/ref 参数引用 WebMethods?

采纳答案by BenAlabaster

Er... I dunno what the protocol is for providing answers to your own questions but the article referenced by Steven Behnke provided some clues for me to deduce a solution to this bizarre situation, and rather than leave everyone else to figure out what the implications are, I thought I'd share my findings...

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

So, consider the following webmethods defined in my WebService

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

[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";
}

Now...according to the document, the first parameter defined as Out, if the method returns void, then the first parameter is automatically used as the return parameter. So I would access each of my methods as follows:

现在...根据文档,第一个参数定义为Out,如果方法返回void,则第一个参数自动用作返回参数。所以我会按如下方式访问我的每个方法:

Method1: public string Method1() {}

方法 1:公共字符串 Method1() {}

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

Method2: public void Method2(out string strVal1) {}

Method2: public void Method2(out string strVal1) {}

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

So you access them both in exactly the same manner...which is extremely confusing. Who on earth would figure that out without having been told that by someone else? It's beyond my comprehension how this could be a good idea...

所以你以完全相同的方式访问它们......这非常令人困惑。谁会在没有被其他人告知的情况下弄清楚这一点?这超出了我的理解,这怎么可能是个好主意......

Method3: public void Method3(out string strVal1, out string strVal) {}

Method3: 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);

Method4: public string Method4(out string strVal1, out string strVal2) {}

Method4: 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);

So as you notice - if the method signature doesn't provide a return value [that is returns void], then the first param becomes the return value. If it already provides a return value, then it doesn't.

正如您所注意到的 - 如果方法签名不提供返回值 [即返回 void],则第一个参数将成为返回值。如果它已经提供了一个返回值,那么它就没有。

This can be extremely confusing for someone that hasn't come across that document. Many thanks for providing that link Steven - I really appreciate it.

对于没有遇到该文档的人来说,这可能会非常令人困惑。非常感谢提供该链接史蒂文 - 我真的很感激。

...and to whomever decided that design pattern was a good idea to be written into the .NET Framework - I can't think what would've posessed you to think that was a good idea... I really dislike you quite intensely after all that.

...对于认为将设计模式写入 .NET Framework 是个好主意的任何人 - 我想不出是什么让您认为这是个好主意...我真的非常不喜欢你毕竟。

ADDENDUM:

附录:

What I only just realised is that to add to the confusion, if you use refinstead of outthen you don'tdo this, you'd treat the WebMethods exactly as you would have if you'd used them to call a regular method inside your application:

我刚刚意识到,更令人困惑的是,如果您使用ref而不是out那么您就不要这样做,您将完全像使用 WebMethods 来调用常规方法一样对待 WebMethods在您的应用程序中:

[WebMethod()]
public void Method3(ref string strVal1, ref string strVal2)
{
    strVal1 = "First argument return value";
    strVal2 = "Second argument return value";
}

Now to call that you'd use:

现在调用你会使用:

string val1 = String.Empty;
string val2 = String.Empty;
svc.Method3(ref val1, ref val2);
Console.WriteLine(val1);
Console.WriteLine(val2);

This inconsistency is mindboggling...the fact that it's by design is incomprehensible to me.

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

回答by Steven Behnke

Maybe this will help:

也许这会有所帮助:

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

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

My favorite part is:

我最喜欢的部分是:

STATUS

This behavior is by design.

地位

此行为是设计使然。