全域屬性“http://www.w3.org/XML/1998/namespace:lang”已被聲明
我有一個奇怪的問題,我有一個 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仍然存在,但它會一直表現出來……這就是為什麼我懷疑你的情況是這個錯誤……