如何使dotnet webservice在字符串值上设置minOccurs =“1”

时间:2010-10-18 16:19:34

标签: .net web-services xsd wsdl asmx

我有一个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;
            }
        }
    }
}

我在我的webservice中返回一个A.A对象,它在服务描述中产生了这个片段

<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> 

自动生成的WSDL中从XSD中的minOccrus =“1”到minOccurs =“0”的更改导致系统另一端的机器感到悲伤。

我当然可以提供一个手工编辑的WSDL供他们使用,但我希望自动生成的WSDL能够满足他们的需求。

关于如何说服dotnet在其自动生成的WSDL中为字符串类型输出minOccurs =“1”而不添加nillable =“true”的任何建议?

3 个答案:

答案 0 :(得分:9)

参考

根据MSDN MinOccurs Attribute Binding Support,只有两种方法可以获得 MinOccurs = 1

  1. 没有默认值或附带布尔字段的值类型。

      

    结果:输出元素的minOccurs值设置为 1

  2. 将XmlElement属性的IsNullable属性设置为true的引用类型。

      

    结果:输出元素的minOccurs值设置为 1 。在元素中,nillable属性也设置为true。

  3. 类型字符串的属性(不幸的是)总是具有默认值

    string.Empty
    

    所以它不能有 null 默认值。这意味着我们无法满足第一个解决方案。为字符串生成 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's response,该线程声明该字段不用于传入的XML。因此,用户仍然可以发送无效的XML。

答案 1 :(得分:6)

我注意到以下几行:

为了将XML Schema复杂类型与非XML特定的类绑定,.NET Framework不提供与minOccurs或maxOccurs属性等效的直接编程语言。

从这里开始:http://msdn.microsoft.com/en-us/library/zds0b35c(v=vs.85).aspx

答案 2 :(得分:1)

根据this问题的答案,这是不可能的。 John Saunders说:

  

事实证明,未使用WSDL   验证传入的XML。它不会   无论你是否可以   指定minOccurs - 它不会   用于验证输入。