jjzjj

c# - .Net WebServices 和 out/ref WebMethod 参数

coder 2024-05-29 原文

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

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

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

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

为了理解这个设计决定的应用,我将一个原型(prototype)和一些基本的 Hello World 风格的网络方法放在一起......一个有一个输出字符串参数,一个有两个输出字符串参数,一个不接收任何字符串参数参数,但返回一个字符串。

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

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 个输入。这是为什么?显然有一个接受一个参数的 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 时看到的相同的编译错误。明显的异常(exception)是它提示 2 个参数而不是 1 个 [事实上我确实得到了相同的异常,我测试了它]。

  • 什么给了?
  • 在 WebMethods 中使用 out/ref 参数是否有我遗漏的原因或方法?
  • 如果有,我如何使用多个 out/ref 参数引用 WebMethods?

最佳答案

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

因此,请考虑在我的 Web 服务中定义的以下 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,那么第一个参数自 Action 为返回参数。所以我会按如下方式访问我的每个方法:

方法一:

public string Method1() {}

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

方法二:

public void Method2(out string strVal1) {}

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

因此您以完全相同的方式访问它们,这非常令人困惑。地球上谁会在没有被其他人告知的情况下弄清楚这一点?我无法理解,这怎么可能是个好主意。

方法三:

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 是一个好主意的人 - 我想不出是什么让您认为这是一个好主意。毕竟我真的非常讨厌你。

附录:

我才刚刚意识到的是,如果你使用 ref 而不是 out 那么你会更加困惑这样,您将完全按照使用 WebMethods 来调用应用程序中的常规方法的方式对待 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);

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

关于c# - .Net WebServices 和 out/ref WebMethod 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/379648/

有关c# - .Net WebServices 和 out/ref WebMethod 参数的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  3. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  4. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  5. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  6. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  7. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  8. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  9. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  10. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

随机推荐