【问题标题】:VS2003 Web Reference for a WCF Service has Extra "IdSpecified" ParameterWCF 服务的 VS2003 Web 参考具有额外的“IdSpecified”参数
【发布时间】:2009-07-26 10:38:13
【问题描述】:

我正在使用 VSTS 2008 + .Net 3.5 + C# 开发 WCF 服务,当我还使用 VSTS 2008 开发客户端时它工作正常(使用添加服务引用功能自动生成客户端 Web 服务代理代码)。我开发的 WCF 使用的是 basicHttpBinding。

我遇到的问题是,当我使用 Visual Studio.Net (Visual Studio 2003) 生成客户端 Web 服务代理代码时,OperationContract 方法有一个额外的输入参数,称为 IdSpecified(bool 类型)。我已经测试过,当将 IdSpecified 指定为 true 时,Id 参数的值将正确传递给 WCF 服务器端,但是当我将 IdSpecified 指定为 false 时,无论我为 Id 参数指定什么值,在 WCF 服务器端,Id 都会是始终为0。我也尝试过输入参数类型,如字符串,客户端没有这样的额外输入参数。

我的问题是为什么有一个额外的参数?它的含义是什么,是否可以避免生成这样的附加参数?

这是 Visual Studio.Net 自动生成的客户端 Web 服务代理代码,

public StudentInfo Poll(int Id, [System.Xml.Serialization.XmlIgnoreAttribute()] bool IdSpecified)

这是我的 VSTS 2008 WCF 服务器端代码,

[OperationContract]
StudentInfo Poll(int Id);

编辑 1:这是客户端自动生成的有关 Poll 方法的代码的一部分。

[return: System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public StudentInfo Poll(int Id, [System.Xml.Serialization.XmlIgnoreAttribute()] bool IdSpecified) {
    object[] results = this.Invoke("Poll", new object[] {
                Id,
                IdSpecified});
    return ((StudentInfo)(results[0]));
}

【问题讨论】:

  • here 是关于它的博客
  • 嗨,ArsenMkrt,博客看起来非常棒,但与我在这里提到的问题不同。在博客中,自动生成的客户端代理代码似乎包含一个名为 IdSpecified 的属性,但在我的场景中,没有这样的属性,只是 Poll 方法的一个附加参数。您可以在我的原始帖子的 EDIT 1 部分看到我更新的代码。我的问题有什么解决方案吗?
  • 乔治,同样的事情。添加了一个额外的参数,因为 int 是一个参数,而不是一个属性。如果您传递一个具有单个 int 属性的类,您会看到一个单独的 IdSpecified 属性。
  • 约翰的评论太棒了!

标签: c# .net wcf web-services asmx


【解决方案1】:

乔治,

此行为是设计使然,并且自 .NET 1.0 以来一直存在。事实上,如果你用 VS2003 创建一个 ASMX Web 服务,使用相同的方法签名,你会发现相同的结果。

问题在于在 WSDL 中标记为不需要的值类型。由于它们是值类型,它们不能返回 null(而且 VS2003 没有可空类型)。 Microsoft 实施的解决方案是添加一个单独的布尔字段或属性,您可以设置它来说明您是否提供该值。

这意味着当你的 .NET 1.1 应用程序要调用服务时,它需要设置 IdSpecified 参数:

using (WebReference1.PollService svc = new WebReference1.PollService()) {
    StudentInfo info = svc.Poll(id, true); // True to specify
}

这个我没试过,你为什么不试试呢:

[DataContract]
public class PollParameters {
    [DataMember(Required = true)]
    public int Id;
}

[OperationContract]
public StudentInfo Poll(PollParameters parameters);

尝试一下,看看代理在 VS2003 中是什么样子的。

【讨论】:

  • 谢谢约翰,你绝对正确——我在 VS2003 使用 .Net 1.0。我对您提到的解决方案感兴趣-“解决方案是添加一个单独的布尔字段,您可以设置它来说明您是否提供值。”,您能给我看一些参考代码吗?我们是在客户端还是服务器端解决它?
  • 对不起,我不清楚。 “解决方案”是微软实施的解决方案。您正在看到解决方案。请注意,您有一个名为“IdSpecified”的额外参数。另外,VS2003 是 .NET 1.1。
  • 谢谢 John, 1. 我已经阅读了您的精彩代码示例,我应该将每个值类型包装到 DataContract 中并使用必需的属性? 2.我很好奇VS2003和VSTS 2008生成不同的客户端代码,它们都不符合Web服务(WSDL)标准?
  • 可以做包装。你不必。 WSDL 标准也没有提到客户端代码。
  • 是的,必需的方法必须始终存在。在 XML Schema 中为 minOccurs="1"。对不起,我使用了“返回”这个词。我的意思是 int 永远不能为空。现在在 C# 2.0 中的 .NET 3.5 中,我们可以说“int?id”,它可以是整数或 null。在 .NET 1.0 和 1.1 中我们无法做到这一点,因此微软不得不使用额外的“IdSpecified”参数或属性来伪造它。
【解决方案2】:

您可以尝试使用 DataContract 而不是简单的整数参数。数据协定允许您指定是否需要成员,如果需要成员,则可能会删除那个奇怪的额外布尔值。

【讨论】:

  • 感谢 blowdart,为什么 Visual Studio .Net 和 VSTS 2008 会生成不同的客户端代理代码?
  • BTW: 1.如何使用DataContract指定参数?我搜索了 MSDN,但没有找到答案。 2. required 意味着客户必须提供一个值?
猜你喜欢
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-18
  • 2011-01-10
  • 2014-07-19
相关资源
最近更新 更多