Dot-Net

如何在字元串值上設置 dotnet webservice set minOccurs=‘1’

  • February 19, 2014

我有一個 XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://a.com/a.xsd"
    targetNamespace="http://a.com/a.xsd"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">
   <xs:element name="A">
       <xs:complexType>
           <xs:sequence>
               <xs:element name="Item"  minOccurs="1" maxOccurs="1">
                   <xs:simpleType>
                       <xs:restriction base="xs:string">
                           <xs:minLength value="1"/>                                       
                           <xs:whiteSpace value="collapse"/>
                       </xs:restriction>
                   </xs:simpleType>
               </xs:element>
           </xs:sequence>
       </xs:complexType>
   </xs:element>
</xs:schema>

我已使用 XSD.exe v2.0.50727.3615 將其轉換為 C# 類,生成程式碼如下

namespace A {
   using System.Xml.Serialization;
   /// <remarks/>
   [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
   [System.SerializableAttribute()]
   [System.Diagnostics.DebuggerStepThroughAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://a.com/a.xsd")]
   [System.Xml.Serialization.XmlRootAttribute(Namespace="http://a.com/a.xsd", IsNullable=false)]
   public partial class A {
       private string itemField;
       /// <remarks/>
       public string Item {
           get {
               return this.itemField;
           }
           set {
               this.itemField = value;
           }
       }
   }
}

我在我的 web 服務中返回一個 AA 對象,它在服務描述中生成這個片段

<s:schema elementFormDefault="qualified" targetNamespace="http://a.com/a.xsd"> 
 <s:element name="Test2Result"> 
   <s:complexType> 
     <s:sequence> 
       <s:element minOccurs="0" maxOccurs="1" name="Item" type="s:string" /> 
     </s:sequence> 
   </s:complexType> 
 </s:element> 
</s:schema> 

從 XSD 中的 minOccrus=“1” 到自動生成的 WSDL 中的 minOccurs=“0” 的變化正在給系統另一端的機器帶來麻煩。

我當然可以提供一個手動編輯的 WSDL 供他們使用,但我希望自動生成的 WSDL 能夠滿足他們的需要。

關於如何說服 dotnet 在其自動生成的 WSDL 中為字元串類型輸出 minOccurs=“1” 而不添加 nillable=“true” 的任何建議?

我注意到以下行:

對於將 XML Schema 複雜類型與非特定於 XML 的類綁定,.NET Framework 不提供與 minOccurs 或 maxOccurs 屬性等效的直接程式語言。

從這裡: http: //msdn.microsoft.com/en-us/library/zds0b35c (v=vs.85).aspx

參考

根據 MSDN MinOccurs Attribute Binding Support,只有兩種方法可以獲得MinOccurs = 1

  1. 沒有預設值或附帶布爾欄位的值類型。

結果:輸出元素的 minOccurs 值設置為1

  1. XmlElement 特性的 IsNullable 屬性設置為 true 的引用類型。

結果:輸出元素的 minOccurs 值設置為1。在元素中,nillable 屬性也設置為 true。

字元串類型的屬性(不幸的是)總是有一個預設值

string.Empty

所以它永遠不能有一個的預設值。這意味著我們永遠無法滿足第一個解決方案。為字元串生成MinOccurs=1的唯一方法是使元素可以為

C#

[XmlElementAttribute(IsNullable = true)]
public string Item { ... }

VB

<XmlElement(IsNullable:=True)>
Public Item As String

解決方案

唯一真正的解決方案是手動編輯 XSD… boo xsd.exe。

更多壞消息

即使有可能,Nick DeVore 在另一個執行緒中連結到John Sounder 的響應,該執行緒聲明該欄位不用於傳入的 XML。所以使用者仍然有可能發送無效的 XML。

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