OperationContractAttribute Class
Indicates that a method defines an operation that is part of a service
contract in a Windows Communication Foundation (WCF) application.
[AttributeUsageAttribute(AttributeTargets.Method)]
public sealed class OperationContractAttribute : Attribute
The OperationContractAttribute type exposes the
following members.
|
Name
|
Description
|
|
|
Maps a set of names to a corresponding set of dispatch
identifiers. (Inherited from Attribute.)
|
|
|
Retrieves the type information for an object, which can be
used to get the type information for an interface. (Inherited from Attribute.)
|
|
|
Retrieves the number of type information interfaces that
an object provides (either 0 or 1). (Inherited from Attribute.)
|
|
|
Provides access to properties and methods exposed by an
object. (Inherited from Attribute.)
|
Apply the OperationContractAttribute to a method
to indicate that the method implements a service operation as part of a service
contract (specified by a ServiceContractAttribute
attribute).
Use the OperationContractAttribute properties to
control the structure of the operation and the values expressed in metadata:
·
The Action
property specifies the action that uniquely identifies this operation. WCF
dispatches request messages to methods based on their action.
·
The AsyncPattern
property indicates that the operation is implemented or can be called
asynchronously using a Begin/End method pair.
·
The IsOneWay
property indicates that the operation only consists of a single input message.
The operation has no associated output message.
·
The IsInitiating
property specifies whether this operation can be the initial operation in a
session.
·
The IsTerminating
property specifies whether WCF attempts to terminate the current session after
the operation completes.
·
The ProtectionLevel
property specifies the message-level security that an operation requires at run
time.
·
The ReplyAction
property specifies the action of the reply message for the operation.
The OperationContractAttribute attribute
declares that a method is an operation in a service contract. Only methods
attributed with the OperationContractAttribute are
exposed as service operations. A service contract without any methods marked
with the OperationContractAttribute exposes no
operations.
The AsyncPattern
property indicates that a pair of Begin<methodName> and End<methodName> methods form a single operation
implemented asynchronously (whether on the client or the service). The ability
of a service to implement operations asynchronously is a service implementation
detail and is not exposed in metadata (such as Web Services Description
Language (WSDL)).
Similarly, clients can choose to invoke operations asynchronously
independent of how the service method is implemented. Calling service
operations asynchronously in the client is recommended when a service method
takes some time but must return information directly to the client. For
details, see AsyncPattern.
The IsOneWay
property indicates that a method does not return any value at all, including an
empty underlying response message. This type of method is useful for
notifications or event-style communication. Methods of this kind cannot return
a reply message so the method's declaration must return void.
Important
|
When programmatically retrieving the information store in this attribute,
use the ContractDescription
class instead of reflection. |
Note
|
If the IsOneWay
property is set to false, (the default), even
methods that return void are two-way methods at the
underlying message level. In this case, the infrastructure creates and sends
an empty message to indicate to the caller that the method has returned.
Using this approach enables the application and the infrastructure to send error
information (such as a SOAP fault) back to the client. Setting IsOneWay
to true is the only way to prevent the creation and
dispatch of a reply message. For more information, see One-Way Services. |
The Action
and ReplyAction
properties can be used not only to modify the default action of SOAP messages
but also to create handlers for unrecognized messages or to disable adding
actions for direct message programming. Use the IsInitiating
property to prevent clients from calling a particular service operation prior
to other operations. Use the IsTerminating
property to have WCF close the channel after clients call a particular service
operation. For more information, see Using Sessions.
The ProtectionLevel
property enables you to specify on the operation contract whether the operation
messages are signed, encrypted, or signed and encrypted. If a binding cannot
provide the security level required by the contract, an exception is thrown at
run time. For more information, see ProtectionLevel
and Understanding
Protection Level.
The following code example shows a simple service contract with one
operation.
C#
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.ServiceModel;
using System.Text;
namespace Microsoft.WCF.Documentation
{
[ServiceContract(Namespace="Microsoft.WCF.Documentation")]
public interface ISampleService{
// This operation specifies an explicit protection level requirement.
[OperationContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)]
string SampleMethod(string msg);
}
class SampleService : ISampleService
{
#region ISampleService Members
public string SampleMethod(string msg)
{
Console.WriteLine("Called with: {0}", msg);
return "The service greets you: " + msg;
}
#endregion
}
}
The following example is a service that implements an implicit service
contract that specifies three operations. Two of the operations are two-way
operations, which return underlying response messages to the caller no matter
what the return value is. The third operation receives a call, an underlying
inbound message, but returns no underlying response message.
C#
[ServiceContractAttribute]
public class OneAndTwoWay
{
// The client waits until a response message appears.
[OperationContractAttribute]
public int MethodOne (int x, out int y)
{
y = 34;
return 0;
}
// The client waits until an empty response message appears.
[OperationContractAttribute]
public void MethodTwo (int x)
{
return;
}
// The client returns as soon as an outbound message
// is dispatched to the service; no response
// message is generated or sent from the service.
[OperationContractAttribute(IsOneWay=true)]
public void MethodThree (int x)
{
return;
}
}
Unwrapped Messages
This sample demonstrates unwrapped messages. By default, the message body is
formatted such that the parameters to a service operation are wrapped. The
following sample shows an Add request message to the ICalculator service in wrapped mode.
<s:Envelope
xmlns:s=http://www.w3.org/2003/05/soap-envelope
xmlns:a="http://schemas.xmlsoap.org/ws/2005/08/addressing">
<s:Header>
…
</s:Header>
<s:Body>
<Add xmlns="http://Microsoft.ServiceModel.Samples">
<n1>100</n1>
<n2>15.99</n2>
</Add>
</s:Body>
</s:Envelope>
The <Add> element in the message body wraps
the n1 and n2 parameters. In
contrast, the following sample shows the equivalent message in the unwrapped
mode.
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://schemas.xmlsoap.org/ws/2005/08/addressing">
<s:Header>
….
</s:Header>
<s:Body>
<n1 xmlns="http://Microsoft.ServiceModel.Samples">100</n1>
<n2 xmlns="http://Microsoft.ServiceModel.Samples">15.99</n2>
</s:Body>
</s:Envelope>
</MessageLogTraceRecord>
The unwrapped message does not wrap the n1 and n2 parameters in a containing element, they are direct
children of the soap body element.
Note
|
The setup procedure and build instructions for this sample are located at
the end of this topic.
|
In this sample, an unwrapped message is created by applying the MessageContractAttribute
to the service operation parameter type and return value type as shown in the
following sample code.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
ResponseMessage Add(RequestMessage request);
[OperationContract]
ResponseMessage Subtract(RequestMessage request);
[OperationContract]
ResponseMessage Multiply(RequestMessage request);
[OperationContract]
ResponseMessage Divide(RequestMessage request);
}
//setting IsWrapped to false means the n1 and n2
//members will be direct children of the soap body element
[MessageContract(IsWrapped = false)]
public class RequestMessage
{
[MessageBodyMember]
private double n1;
[MessageBodyMember]
private double n2;
//…
}
//setting IsWrapped to false means the result
//member will be a direct child of the soap body element
[MessageContract(IsWrapped = false)]
public class ResponseMessage
{
[MessageBodyMember]
private double result;
//…
}
To allow you to see the messages being sent and received, this sample uses
tracing. In addition, the WSHttpBinding
has been configured without security, to reduce the number of messages it logs.
The resulting trace log (c:\logs\Message.log) can be viewed by using the Service
Trace Viewer Tool (SvcTraceViewer.exe). To view message contents, select Messages in both the left and the right panes of the Service
Trace Viewer tool. Trace logs in this sample are configured to be generated
into the C:\LOGS folder. Create this folder before running the sample and give
the user Network Service write permissions for this directory.