Dot-Net

全域屬性“http://www.w3.org/XML/1998/namespace:lang”已被聲明

  • December 13, 2018

我有一個奇怪的問題,我有一個 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)

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

你的問題正是它所說的:你得到了兩次定義的特定屬性。這可能是由於 .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仍然存在,但它會一直表現出來……這就是為什麼我懷疑你的情況是這個錯誤……

引用自:https://stackoverflow.com/questions/10871182