【问题标题】:How to make a dotnet webservice set minOccurs="1" on a string value如何在字符串值上设置 dotnet webservice set minOccurs="1"
【发布时间】:2010-10-18 16:19:34
【问题描述】:

我有一个 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 服务中返回了一个 A.A 对象,它在服务描述中生成了这个 sn-p

<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" 的任何建议?

【问题讨论】:

  • 如果你在这里偶然发现相反的情况 (minOccurs=0),请参阅 social.msdn.microsoft.com/Forums/en-US/… -- 你添加一个被忽略的属性 [XmlIgnore]public bool {{TheProperty}}Specified { get; set; } 并在设置 'TheProperty' 时设置它。

标签: .net web-services xsd wsdl asmx


【解决方案1】:

参考文献

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

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

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

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

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

string 类型的属性(不幸的是)始终具有默认值

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。

【讨论】:

  • 您不需要 IsNullable 属性集吗?将其设置为 true 或 false 会得到什么?
  • 就我而言,更坏的消息不是问题,因为我并没有试图依赖框架来验证 XML 的那部分,只是试图阻止人们查看WSDL 一直用“为什么你的 minOccurs 错误”的问题来纠缠我。
  • Simon - 我担心最终用户也会看到错误的信息。我唯一的全自动解决方案是使用批处理文件或 exe 对 xsd 进行后处理,以更正 minOccurs 值。我有我自己的属性附加到我的类中的属性,所以一个 exe 可以关闭它。 @JohnSaunders - 我不确定您是要澄清我的回答还是要提出解决方案。属性属性中的“IsNullable”术语解决了“minOccurs”问题,但通过添加“isNullable”会导致另一个问题;西蒙在原始问题的结尾指出了这一点。
【解决方案2】:

我注意到下面一行:

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

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

【讨论】:

  • ...这有点糟糕:(
【解决方案3】:

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

原来没有使用WSDL 验证传入的 XML。它不会 不管你能不能 指定 minOccurs - 它不会是 用于验证输入。

【讨论】:

  • 我实际上并没有尝试使用 WSDL 来验证输入,我想说的是可以保证输出可能包含字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多