Search code examples
c#wcfwscf

WCF service one-way method with fault message


I wanted to create a one-way method for wcf service. Everything is ok unless I want to return fault message - if any.

I am using wscf blue code generator for wsdl and contract files.

In wsdl operation element I have only 'Input' and 'Fault' child elements. When I run the service i got the information that cannot declare fault message in one-way communication and .. one of the solutions is to set one-way to false .. what I did and well it works ok. If error occurs I get the message.

However I am wondering if I broke the web service/wsdl creation rules ... Because from wsdl service schema generator creates for me one-way communication (set to 'true') and other in other programming languages' generators would probably do the same ...

So Is it correct what i Did? How can I change wsdl so that the generator could create the code appropriately?

If in theory I cannot use fault in one-way communication then Do I need extra structure on response to return any error?

Thanks!


Solution

  • It's true that one-way operations can't return faults to clients. If you want to generate a void not one-way service operation in WCF you will have to add an empty output element for that operation in your WSDL contract.

    The .NET based WSDL parsers (such as WSCF.blue and svcutil) will generate one-way service operations for <wsdl:operation> elements that don't have a corresponding <wsdl:output> element.

    For example this WSDL operation is one-way:

    <wsdl:definitions>
        <wsdl:portType>
            ... 
            <wsdl:operation name="Foo">
               <wsdl:input message="tns:FooRequest" />
            </wsdl:operation>
        </wsdl:portType>
    </wsdl:definitions>
    

    On the other hand, defining an operation with an empty <wsdl:output> element (i.e an XSD type containing an empty sequence) will be mapped to a void not one-way method in .NET, which can optionally contain a fault declaration:

    <wsdl:definitions>
        <wsdl:portType>
            ... 
            <wsdl:operation name="Foo">
               <wsdl:input message="tns:FooRequest" />
               <wsdl:output message="tns:FooResponse" />
               <wsdl:fault message="tns:FooFault" />
            </wsdl:operation>
        </wsdl:portType>
    </wsdl:definitions>
    

    where the <tns:FooResponse> type is simply defined as:

    <xs:element name="FooResponse">
        <xs:complexType>
            <xs:sequence/>
        </xs:complexType>
    </xs:element>