简体   繁体   English

Web服务设计以及如何捕获在C#.net中发送到Web服务调用的原始XML,以便可以针对XSD对其进行验证?

[英]Webservices Design and How can I capture the raw XML sent to a webservice call in C# .net so that I can validate it against an XSD?

I have created a C# .net 2.0 webservice. 我创建了一个C#.net 2.0 Web服务。 I need to capture the raw XML sent from the client and validate it against an XSD and return any errors to the client. 我需要捕获从客户端发送的原始XML,并针对XSD对其进行验证,并将所有错误返回给客户端。 The webservice will allow the client to upload a list of widgets to our system. 该网络服务将允许客户端将小部件列表上传到我们的系统。

The following is some background info: 以下是一些背景信息:

I created an XSD to model a "Widget", which is a complex object. 我创建了一个XSD来建模“ Widget”,这是一个复杂的对象。 It looks something like this: 看起来像这样:

<xs:element name="WidgetList">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Widget" maxOccurs="unbounded" type="WidgetType" />
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:complexType name="WidgetType">
    <xs:sequence maxOccurs="1" minOccurs="1">
        <xs:element name="Seller" type="AccountType" maxOccurs="1" minOccurs="1" />
        <xs:element name="Buyer" type="AccountType" maxOccurs="1" minOccurs="1" />
    </xs:sequence>
    <xs:attribute name="Market" type="MarketType" use="required" />
</xs:complexType>
<!-- etc... -->

Then, I used XSD.exe to generate classes from the xsd. 然后,我使用XSD.exe从xsd生成类。
The Classes that are created are WidgetList, Widget, Seller, Buyer, etc. 创建的类是WidgetList,Widget,卖方,买方等。

Next, I created a webservice method to take the Upload. 接下来,我创建了一个webservice方法来进行上传。 It looks like so: 看起来像这样:

[WebMethod]
[SoapHeader("SecurityAuthenticationHeader", Direction = SoapHeaderDirection.In)]
public string UploadWidgets(WidgetList wl)
{
    //Need to validate the XML against the XSD here.

    //Code to import...
}

Two questions: 两个问题:

  1. Is there a way that I can validate the raw XML sent from the client against my original XSD? 有没有一种方法可以针对原始XSD验证从客户端发送的原始XML?
  2. Is there anything wrong with the way I have created this service? 我创建此服务的方式有什么问题吗?

UPDATE: 更新:
The reason I need to do this is that even though the XSD says fields are required or minOccurs=1 , it seems that those properties are not required in the WSDL (Not really sure why). 我需要这样做的原因是,即使XSD说字段是必填字段或minOccurs = 1 ,似乎WSDL中也不需要这些属性(不确定为什么)。

This is what part of the WSDL looks like (removed unnecessary parts for brevity): 这就是WSDL的一部分(为简洁起见,删除了不必要的部分):

<s:schema elementFormDefault="qualified" targetNamespace="http://www.clearpar.com/XMLSchema">
  <s:element name="lt">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="unbounded" name="LoanTrade" type="s1:LoanTradeType" /> 
      </s:sequence>
     </s:complexType>
   </s:element>
<s:complexType name="LoanTradeType">
  <s:sequence>
    <s:element minOccurs="0" maxOccurs="1" name="Seller" type="s1:AccountType" /> 
    <s:element minOccurs="0" maxOccurs="1" name="Buyer" type="s1:AccountType" /> 
  </s:sequence>
  <s:attribute name="Market" type="s1:MarketType" use="required" /> 
</s:complexType>
<s:complexType name="AccountType">
  <s:attribute name="Name" type="s:string" /> 
  <s:attribute name="ClientSystemID" type="s:string" /> 
</s:complexType>

I don't think that there's a simple way to do this. 我认为没有简单的方法可以做到这一点。

There is an MSDN article on implementing a SoapExtension to perform schema validation. MSDN上一篇有关实现SoapExtension来执行模式验证的文章。 This is the route I took, with a few enhancements. 这是我采用的方法,并做了一些改进。

It's unfortunate that there is no automatic mechanism to validate against the WSDL, especially since the service inherently knows the schema already. 不幸的是,没有针对WSDL进行验证的自动机制,尤其是因为该服务已经固有地知道该模式。 I would be interested to know if this situation has changed in WCF: I'm porting my services now and would love it if they've solved this problem more elegantly. 我想知道WCF中的这种情况是否已改变:我现在正在移植我的服务,如果他们能更优雅地解决此问题,我会喜欢的。

Since you need more strict control over your WSDL, I recommend writing it manually, and generate both your service contract interface/data/messages and client proxies from a single WSDL contract. 由于需要对WSDL进行更严格的控制,因此我建议手动编写它,并从单个WSDL合同生成服务合同接口/数据/消息和客户端代理。 There is a great project on CodePlex, WCSF.blue , that can help you do contract-first service development. CodePlex上有一个很棒的项目WCSF.blue ,可以帮助您进行合同优先的服务开发。

For question 1: the only way that I know to validate the incoming message is to create SOAP Extension that validates the incoming message against the expected schema. 对于问题1:我知道的验证传入消息的唯一方法是创建SOAP Extension,以根据预期的模式验证传入消息。 The reason is that the .NET plumbing deserializes the incoming XML into an object before entering your WebMethod. 原因是.NET管道将输入的XML反序列化为对象,然后再进入WebMethod。 If there is an issue with the incoming XML then your Web Method will never be entered and a SOAP Fault will be returned to the client. 如果传入的XML存在问题,则将永远不会输入您的Web方法,并且SOAP错误将返回给客户端。 Another issue is that perhaps the deserializer does not deserialize "properly". 另一个问题是解串器可能不会“适当地”反序列化。 Read the XML Schema Validation article for more information. 阅读XML模式验证文章 ,了解更多信息。

In terms of question 2: your approach is correct for contract first development using (asmx) web services. 关于问题2:您的方法对于使用(asmx)Web服务进行合同优先开发是正确的。 My question back to you is why not use WCF to expose a web service instead of the older ASMX technology. 我的问题是,为什么不使用WCF而不是较旧的ASMX技术来公开Web服务。 WCF supports schema validation as well . WCF也支持架构验证

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM