我有一个奇怪的问题,我有一个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)
任何人都有任何想法?谢谢!
答案 0 :(得分:8)
你的问题正是它所说的:你得到两次定义的特定属性。它可能是由于.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文件的掌上电脑。有什么特别之处,就是通过各种include / imports它“伸出”到上面的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方法,this from the online help之类的东西可以正常工作。
首先,确保第二个包含中的URL不可用。运行脚本。你会看到结果是编译成功!
然后,确保网址正常;运行脚本。您将得到与您的方案中相同的错误,已定义的内容。
您必须了解架构加载在.NET中的工作原理以及架构编译的工作原理。底线是,如果您从同一个uri加载相同的内容两次或更多次,XSD编译器通常足够聪明,可以解决它。如果从两个不同的URI加载相同的内容,则编译器无法猜出您的意图是什么;尽管如此,不同的URI意味着不同的模式,因此“已经声明”错误。
基于以上所述,可能是在获得异常的机器上,可以通过不同的URI访问xml.xsd。
我会使用一个专门的工具来加载你的WSDL,并为你提供一个所有依赖项(其他WSDL和/或外部XSD)的图形。如果xml.xsd来自两个不同的地方,你应该立即看到它。
如果以上仍然没有产生足够的理解...要进行故障排除,首先看看你是否可以在没有外部连接的情况下运行你的东西(“拉网络插头”他说......)。然后,在WS运行的机器上运行一个http调试器,Fiddler就是一个例子,在那里你得到了异常,而你却没有。监视错误并与调试跟踪关联。
这应该让你朝着正确的方向前进。与一些评论不同,我不打扰禁用WS-I BP检查;正如你已经弄明白的那样,这并没有真正解决你的问题。
对于.NET中的错误,它是一个非常遥远但可能的场景。我假设你已经检查了补丁级别。我提到它的唯一原因是因为我自己进入它,我不得不编写自己的解析器来绕过它。即使最新的.NET仍然存在,但它会一直显现出来......这就是为什么我怀疑你的情况是这个错误......
答案 1 :(得分:1)
我遇到了类似的问题,下面的代码也抛出了异常,说已经定义了全局属性。
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;
}
}
答案 2 :(得分:1)
在项目未编译时,在Microsoft Visual Studio 2013中添加Web引用时遇到此问题。这似乎会导致WSDL生成器代码中出现多线程问题。
在客户端代码编译时添加Web引用时不会发生问题。
答案 3 :(得分: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>
验证后删除该部分,不再需要它,解决了问题。
答案 4 :(得分:0)
我发现这只是在默认应用程序池.NET 4下运行的站点,但我的代码是针对3.5。更改为运行.NET 2的应用程序池解决了此问题。在2个客户的服务器上有这个肯定是一个简单的解决方案,在深入研究之前尝试: - )
此致
利安
答案 5 :(得分:0)
如果您在 web.config 的 system.web 部分同时拥有这两行:
<compilation debug="true" targetFramework="XXX"/>
<httpRuntime targetFramework="XXX"/>
您需要删除 httpRuntime 节点才能解决问题。
答案 6 :(得分:0)
我通过更改属性WebService的默认属性命名空间(“ tempuri.org”)在.NET中对其进行了修复。
答案 7 :(得分:0)
在将应用程序从fw 4.5代码库更新为fw 4.7.2代码库之后,在应用程序日志中看到4个服务器中的1个错误。重新启动应用程序池有助于解决此问题。