【问题标题】:Validate SOAP against XSD Schema?针对 XSD 架构验证 SOAP?
【发布时间】:2010-12-08 20:16:54
【问题描述】:

我有一个基于 XSD 架构的 SOAP Web 服务(该架构生成了用作 Web 服务方法的输入参数的类),如下所示:

public class CMService : WebService
{
    [WebMethod(Description = "Submit trades")]
    public bool SubmitTrades(List<TradesTrade> trades)
    {
        // Validation, if true, return true, else, return false;
        return true;
    }
}

如何验证是否已针对架构传入(在这种情况下,架构类是 TradesTrades)?

谢谢。

【问题讨论】:

    标签: .net soap xsd asmx xsd-validation


    【解决方案1】:

    这样做并不容易,而且可能不值得。

    请考虑,如果发送到您的服务的 XML 与架构不匹配,那么它将无法正确反序列化。如果它足够糟糕,你的服务操作甚至不会被调用。

    也就是说,如果您真的需要这样做,那么您应该查看SoapExtension 类的示例。我建议您首先让示例按原样工作。然后,我建议你创建一个新版本的示例,并让它做你想做的事情。

    您想要修改 WriteInput 和/或 WriteOutput 方法,以使用其中一种可用方法验证您的 XML,可能通过配置 XmlReader 来进行验证并从输入流中读取;并配置 XmlWrite 以写入输出流;然后运行一个循环来读取输入并写入输出。

    【讨论】:

      【解决方案2】:

      我已手动验证字段:)

      【讨论】:

        【解决方案3】:

        我在之前的项目中使用过XML beans(xml 绑定框架)。我们创建了 xml 模式,然后从模式中生成了 xml beans 对象。这些 XML beans 对象有很多方便的方法来检查 xml 的有效性以及作为 XML 的一部分传入的值。

        如果您对 XML bean 有任何特殊问题,请告诉我。

        【讨论】:

        • 但没有指定。对不起,这是一个错误。我得看看班级说它的.Net。
        【解决方案4】:

        我自己也遇到过同样的问题,答案是无需手动验证所有字段就可以做到这一点(这很容易出错,而且既然你已经有了架构,你也可以使用它) .

        See this a article on the topic.

        基本上,要遵循的过程是首先将原始 Request.InputStream 读入 XmlDocument,然后将架构和验证应用于其中的 SOAP 主体。

        [WebMethod(Description = "Echo Soap Request")]
        public XmlDocument EchoSoapRequest(int input)
        {
          // Initialize soap request XML
          XmlDocument xmlSoapRequest = new XmlDocument();
          XmlDocument xmlSoapRequestBody = new XmlDocument();
        
          // Get raw request body
          HttpContext httpContext = HttpContext.Current;
          Stream receiveStream = httpContext.Request.InputStream
        
          // Move to begining of input stream and read
          receiveStream.Position = 0;
          using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
          {
            // Load into XML document
            xmlSoapRequest.Load(readStream);
          }
        
          // Now we have the original request, strip out the request body
          foreach (XmlNode node in xmlSoapRequest.DocumentElement.ChildNodes)
          {
             if (node.NodeType == XmlNodeType.Element && node.LocalName == "Body" && node.FirstChild != null)
             {
                xmlSoapRequestBody.LoadXml(node.FirstChild.InnerXml);
             }
          }
        
          // Validate vs Schema
          xmlSoapRequestBody.Schemas.Add("http://contoso.com", httpContext.Server.MapPath("MySchema.xsd"))
          xmlSoapRequestBody.Validate(new ValidationHandler(MyValidationMethod));
        }
        

        【讨论】:

        • @Steven:我的代码有很多问题。首先,如果SOAP:Body 元素有多个子元素怎么办?其次,如果有一个名为Body 的元素位于不同的命名空间中怎么办?您会将其误认为是 SOAP:Body 元素。此外,通过重新解析内部 XML 来创建 xmlSoapRequestBody 对我来说毫无意义——您已经有了一个 XmlNode,那么为什么不使用它呢?考虑XmlReader.Create(new XmlNodeReader(node.FirstChild), new XmlReaderSettings{validation settings set})
        • 虽然您的观点在理论上是可行的,但您之前似乎没有使用过多的 Soap 或 Schema 验证。 1)在Soap中,你的方法是元素的唯一子元素,2)它的soap,Body元素包含soap消息,虽然理论上可能在两个命名空间中有不同的Body元素,但这不会发生事实上。 3) 架构适用于 XmlDocument 项,而不适用于 XmlNodes。这段代码有效,它适用于 99.9% 的情况,这对我来说已经足够了。
        • @Steven:我的 SOAP 体验非常错误,顺便说一句,我的第一个 ASMX 服务使用 SoapExtension 验证了传入和传出的 XML。 OBTW,当输入message 有多个部分时,SOAP 消息是什么样的?
        • 请举个例子,你说的是边缘情况下的边缘情况。
        • 通过 XMLSpy:&lt;wsdl:message name="NewMessageRequest"&gt;&lt;wsdl:part name="parameter" type="xs:string"/&gt;&lt;wsdl:part name="parameter2" type="xs:int"/&gt;&lt;/wsdl:message&gt;。请求:&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;SOAP-ENV:Body&gt;&lt;parameter xsi:type="xsd:string"&gt;String&lt;/parameter&gt;&lt;parameter2 xsi:type="xsd:int"&gt;0&lt;/parameter2&gt;&lt;/SOAP-ENV:Body&gt;&lt;/SOAP-ENV:Envelope&gt;
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-29
        • 2010-11-15
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 1970-01-01
        相关资源
        最近更新 更多