10

我有一个奇怪的问题,我有一个 Web 服务作为我系统的一部分安装在一些客户上,这意味着每个客户都有一个相同的 WS 副本。

当我编译 WS 时,在我的服务器和大多数客户机器上一切正常,但有一个客户有时会报告以下错误(通常 WS 对这个客户工作正常,90% 的时间):

Description:
AgentWS: [2852] [525] [Emergency] 
System.Xml.Schema.XmlSchemaException: The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.
   at System.Xml.Schema.XmlSchemaSet.InternalValidationCallback(Object sender, ValidationEventArgs e)
   at System.Xml.Schema.BaseProcessor.SendValidationEvent(XmlSchemaException e, XmlSeverityType severity)
   at System.Xml.Schema.BaseProcessor.AddToTable(XmlSchemaObjectTable table, XmlQualifiedName qname, XmlSchemaObject item)
   at System.Xml.Schema.Compiler.Prepare(XmlSchema schema, Boolean cleanup)
   at System.Xml.Schema.XmlSchemaSet.Compile()
   at System.Xml.Serialization.XmlSchemas.Compile(ValidationEventHandler handler, Boolean fullCompile)
   at System.Web.Services.Description.SchemaCompiler.Compile(XmlSchemas schemas)
   at System.Web.Services.Description.WebServicesInteroperability.AnalyzeDescription(ServiceDescriptionCollection descriptions, BasicProfileViolationCollection violations)
   at System.Web.Services.Description.WebServicesInteroperability.CheckConformance(WsiProfiles claims, ServiceDescriptionCollection descriptions, BasicProfileViolationCollection violations)
   at ASP.defaultwsdlhelpgenerator_aspx.Page_Load(Object sender, EventArgs e) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\DefaultWsdlHelpGenerator.aspx:line 1439
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

任何人有任何想法?谢谢!

4

8 回答 8

11

你的问题正是它所说的:你得到了两次定义的特定属性。这可能是由于 .NET 中的错误(我稍后会提到)或仅仅是由于配置问题而发生。为了理解我在说什么,以便您弄清楚如何在您的特定环境中最好地处理它,我将为您提供如何重现它的秘诀。它都基于相同的XmlSchemaSet对象,在您的堆栈跟踪中引用。

其中一些步骤特定于我正在使用的工具;我将尝试提供我能想到的替代方案。

Base.xsd :这是代替 xml.xsd 文件

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="something">
        <xs:sequence>
            <xs:element name="aha" type="xs:string" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

Some.xsd:这是您设置中其他 XSD 文件的占位符。它的特别之处在于,它通过各种包含/导入“延伸”到上述 Base.xsd。

<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">    
    <xsd:include schemaLocation="base.xsd"/>
    <xsd:include schemaLocation="http://localhost:9090/base.xsd"/>

    <xsd:element name="a" type="something"/>    
</xsd:schema>

我设置了两个包含,以模仿不止一种可能的方式来“接触”Base.xsd。

localhost URL 应该通过一些 http 服务器:使用您的本地 IIS、任何其他 HTTP 服务器或您可以根据需要控制的 HTTP 模拟软件。

编写一个基于 XmlSchemaSet 编译“Some.xsd”的小 C# 脚本。Compile 方法的在线帮助中的类似内容会起作用。

首先,确保第二个包含中的 URL 不可用。运行脚本。你会看到结果是编译成功!

然后,确保 URL 服务正常;运行脚本。您将收到与您的场景相同的错误,内容已定义。

您必须了解模式加载在 .NET 中的工作原理,以及模式编译的工作原理。底线是,如果您从相同的 uri 加载相同的内容两次或更多次,XSD 编译器通常足够聪明,可以弄清楚。如果你从两个不同的 URI 加载相同的内容,那么编译器就猜不出你的意图是什么;不管怎样,不同的 URI 意味着不同的模式,因此“已经声明”错误。

综合以上,可能是在你得到异常的机器上,通过不同的URI访问xml.xsd。

我将使用一个专门的工具来加载您的 WSDL 并为您提供所有依赖关系的图表(其他 WSDL 和/或外部 XSD)。在其中您应该立即看到 xml.xsd 是否来自两个不同的地方。

如果以上仍然没有产生足够的理解......要进行故障排除,首先看看你是否可以在没有外部连接的情况下运行你的东西(“拔掉网络插头”他说......)。然后,运行一个 http 调试器,Fiddler 就是一个例子,在运行 WS 的机器上,你在哪里得到异常,在哪里没有。监视错误并与调试跟踪相关联。

这应该让你朝着正确的方向前进。与某些评论不同,我不会费心禁用 WS-I BP 检查;正如您已经知道的那样,这并不能真正解决您的问题。

至于 .NET 中的错误,这是一个非常遥远但可能的情况。我假设您已经检查了补丁级别。我提到它的唯一原因是因为我遇到了它,我不得不编写自己的解析器来解决它。即使最新的.NET仍然存在,但它会一直表现出来......这就是为什么我怀疑你的情况是这个错误......

于 2012-06-08T23:43:31.553 回答
2

我有一个类似的问题,下面的代码也抛出异常,说已经定义了全局属性。

    xmlSchemaSet = new XmlSchemaSet();
    xmlSchemaSet.Add(null, schemaFileName);
    xmlSchemaSet.Compile();

它被缓存在某处,因为我使用的定义是正确的。但是,一个简单的解决方案是添加一个验证处理程序并忽略那些您不希望从中出错的处理程序。

更改原始代码以具有架构验证事件处理程序:

    xmlSchemaSet = new XmlSchemaSet();
    xmlSchemaSet.Add(null, schemaFileName);
    xmlSchemaSet.ValidationEventHandler += xmlSchemaSet_ValidationEventHandler;
    xmlSchemaSet.Compile();

然后有一个处理程序,如:

/// <summary>
/// Ignore the global attribute already declared errors we sometimes get because of some caching.
/// This happens with xml.xsd.
/// </summary>
private static void xmlSchemaSet_ValidationEventHandler(object sender, ValidationEventArgs e)
{
  if (!e.Exception.Message.Contains("has already been declared"))
  {
    throw e.Exception;
  }
}
于 2014-03-25T14:29:39.143 回答
1

当项目未编译时,我在 Microsoft Visual Studio 2013 中添加 Web 引用时遇到了这个问题。这似乎会导致 WSDL 生成器代码中出现多线程问题。

在客户端代码编译时添加 Web 引用时不会出现问题。

于 2014-09-05T12:22:44.570 回答
0

发布到 asmx-webservice 时,我随机弹出此错误。在这个特定站点的 web.config 中,定义了一些遗留程序集重定向:

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
    </dependentAssembly>
    <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
    </dependentAssembly>
</assemblyBinding>
</runtime>

验证后删除该部分,不再需要它,解决了问题。

于 2012-12-10T14:59:43.003 回答
0

我发现这只是在默认应用程序池 .NET 4 下运行的站点,但我的代码针对的是 3.5。更改为运行 .NET 2 的应用程序池可解决此问题。在 2 个客户的服务器上进行此操作,这绝对是一个在深入研究之前可以轻松尝试的解决方法 :-)

问候

利亚姆

于 2016-10-12T14:15:47.703 回答
0

在应用程序从 fw 4.5 代码库更新到 fw 4.7.2 代码库后,在应用程序日志中的 4 台服务器中的 1 台上看到了该错误。应用程序池重新启动有助于解决此问题。

于 2018-12-13T10:47:31.517 回答
0

我通过更改属性 WebService 的默认属性命名空间(“tempuri.org”)在 .NET 中对其进行了修复。

于 2018-10-10T19:42:01.290 回答
-1

如果您的web.config的system.web部分中有这两行:

<compilation debug="true" targetFramework="XXX"/>
<httpRuntime targetFramework="XXX"/>

您需要删除httpRuntime节点才能解决问题。

于 2018-06-19T10:55:53.893 回答