【问题标题】:.Net WebServices and out/ref WebMethod arguments.Net Web 服务和 out/of Web 方法参数
【发布时间】:2008-12-18 23:08:59
【问题描述】:

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

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

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

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

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

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

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 的响应内容是:

<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>

我认为很公平,所以理论上 [如果我能找到一种方法将参数传递/引用给 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 中使用 out/ref 参数?
  • 如果有,如何使用多个 out/ref 参数引用 WebMethods?

【问题讨论】:

    标签: c# .net vb.net web-services


    【解决方案1】:

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

    因此,请考虑在我的 WebService 中定义的以下 Web 方法:

    [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,那么第一个参数自动作为返回参数。所以我会按如下方式访问我的每个方法:

    方法一:

    public string Method1() {}
    
    var str = svc.Method1();
    Console.WriteLine(str);
    

    方法二:

    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],那么第一个参数将成为返回值。如果它已经提供了一个返回值,那么它就没有。

    对于没有看过该文档的人来说,这可能会让人非常困惑。非常感谢 Steven 提供该链接 - 我真的很感激。

    对于那些认为将设计模式写入 .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);
    

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

    【讨论】:

    • 当您的声望达到 2000 时,我相信正确的协议是编辑 Steven Behnke 的答案……尽管感觉很麻烦。但是很好地发布您的摘要。 +1
    【解决方案2】:

    也许这会有所帮助:

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

    我最喜欢的部分是:

    状态

    此行为是设计使然。

    【讨论】:

    • 好的,谢谢 - 那篇文章内容丰富。我对这个设计理念的唯一评论是:“到底是谁想出了这个主意,搞砸了!”
    猜你喜欢
    • 2016-04-12
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2021-06-12
    相关资源
    最近更新 更多