Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF request validation using XML

Tags:

c#

.net

wsdl

wcf

I have a WCF SOAP web service using .Net 4.0 framework. I am using contract first approach – i.e, service code is generated from hand written WSDL using WCSF Blue tool.

I have following requirement about the request message.

If the price is less than 100, there must not be a tax element, but if it's greater then 100, the tax element is required.

In XPath the expression will be as follows

//t:price[. < 100][not(following::t:tax)] or 
//t:price[. >=100][following::t:tax]

I can handle it in C# code of the service. But I would like to define the rule it in the WSDL itself using any XML technology. This will help the client know what is the business validation that the input message should meet. (That is the definition of the business rule and its implementation is in the WSDL itself; not other documentation is to be shared to the client.)

What is the best way to achieve it in WCF? Under which section in the WSDL I can define the XML validations so that it will be processed by WCF?

In the first two references given below, there is an approach mentioned about XPath and C# handlers (for Web Services Framework). Can't we do so in WCF? Can't C# read the XPath from WSDL? How to do it? Any references?

Note: I am okay to have C# handlers to execute; but the business logic for validation should be in XML

Reference

  1. Extend the ASP.NET WebMethod Framework with Business Rules Validation -by Aaron Skonnard and Dan Sullivan
  2. WS-Policy and WSE 2.0 Assertion Handlers – by Aaron Skonnard
  3. Hartmut's Box - The Four Tenets and XML Messaging with WCF
  4. Message validation with Schema in WCF
  5. XML validation with Schematron/XSD in C#
  6. Defining xml in an xsd where an attribute determines the possible contents
like image 981
LCJ Avatar asked Mar 16 '13 06:03

LCJ


2 Answers

I don't think you can do this in the WSDL itself, but you could insert a handler that performs validation before your user code is dispatched.

There's an Enterprise Library block that can handle this kind of validation, or of course you can roll your own and add it to the WCF stack.

like image 110
Dave Bending Avatar answered Oct 19 '22 22:10

Dave Bending


Start with a plain text description of the rules to people calling your service. Give each rule a tag so it can be referred to easily.

Write your validation rules in C# and call them in a message validation handler. You can still use XQuery / XPath syntax and configuration files to implement the rules, but it'll be an implementation detail. If some of the rules turn out to be cumbersome to define at this level, you can add those in code. If the business introduces a rules engine, you can make use of the engine. But this happens behind the interface of the service. If the rules change, the WSDL remains the same.

Have the validation give the tag of the rule that failed plus a crisp messages describing the failure. Give people integrating with your service access to a development environment where they can toy around with the contract.


On how to use XQuery style validation:

Schematron allows you to define rules in XML. A schema consists of phases, patterns, rules and assertions but basically one of your assertions would look like:

<assert id="NO-TAX-LOW-PRICE" test="price >= 100 or not(following::t:tax)">
    If the price is less than 100, there must not be a tax element
</assert>

Schematron provides a set of XSLT transforms that first transform your schematron schema with the business rules into another XSLT transform. This generated XSLT transform then transforms the XML input into a set of validation messages that describe its validity.


But the whole point is that there's many ways to do this, you could configure the assertions in a scripting language and use the script to validate the deserialized parameters.

if( order.price < 100 && order.tax ) {
    fail("NO-TAX-LOW-PRICE", 
        "If the price is less than 100, there must not be a tax element");
}

And you could change the implementation if you find out another one suits you better. It wouldn't change the wsdl nor the behavior of the service.

like image 23
flup Avatar answered Oct 19 '22 20:10

flup