WCF Service Wsdl Error: operation references a message element that has already been exported - wcf

We have a WCF service that has two operations (Operation1 and Operation2) with the same message contract. When you access the Wsdl (Get/Http) we get this error:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
contract: Xxxxx ---->
System.InvalidOperationException: The Xxxx.IServiceInterface.Operation1 operation
references a message element [http://schemas.somecompany.com/namespace/version/:MessageContract] that has already been exported from the Xxxx.IServiceInterface.Operation2 operation.
You can change the name of one of the operations by changing the method name or using the Name property of OperationContractAttribute. Alternatively, you can control the element name in greater detail using the MessageContract programming model.
Seems to me that reusing the same message for different service operations should be possible. I understand the resolution that is given in the error, but we want to have the same message for a number of different operations.
Thoughts?
More Info: We implement an event pub/sub mechanism. Event subscribers declare a service operation with the event type they want to handle and wrap that in a generic message contract class. This generic message class uses the message code attributes to use the event-publisher xml names - which is a single message structure. All event subscribers are registered in UDDI and the pub/sub mechanism use those endpoints to push events to the subscribers. Registration of service operations in UDDI detect the specific event-namespace to register those service operations as event handlers (and not req/response operations).

This error can occur if you have copy - pasted operation1, then changed the name to operation2, but not changed the DataContract attribute to match the new name.

Related

WCF Custom Message implementation

In the context of a WCF project, I need to handle in the same way xml and non-xml messages (eg. Standard SOAP, WS-Attachments, etc..). The normal flow of WCF creates a Message object which can handle an Xml message, this is done by the encoder, so if one wants to handle different messages, it's needed to implement different kind of message-handling...
My needs is to create a message derivation class, which represent the concept of "received message" but not "handled" in the form of special data handling, but , about real data-handling, deferred in a secondary step.
so in the catch-all service I will get a Message messageObject as parameter, so the signature of the service will be Message Accept(Message messageObject)
Any idea?
thanks in advance
There is only single base Message type in WCF. This is a core type which is used by WCF infrastructure. The type is abstract so generally you can create your custom implementation but in such case you will probably have to replace some WCF channels to correctly use your new type.
If you need to transport message in custom format you are probably not looking for replacing Message type but either replacing encoder, serializer or both.

Approach to pass validation result, on failure, from WCF service (with EF4 data processing) to MVC3 client

I implement a ASP.NET MVC3 application, where data is accessed through WCF services.
The WCF service uses EF4.1 for data access with DBContext and POCO classes for entities.
I can annotate the properties with data validations attributes on the server side, and also I can implement custom validation by defining either custom validation attributes (derived from ValidationAttribute), or by implementing IValidatableObject ).
But I have a problem: if validation fails, what is the best approaoch to pass validation error info from WCF to client, and then use it in MCV3 client?
As I understand with WCF, every data exchanged between client and WC service should be part of the data contract, and should not use exceptions as ways of passing meaningful information between server and client (like throwing a ValidationException with extra properties set for Validation failure info).
Also in WCF who uses EF I call dbContext.SaveData(), but if data is not valid, it throws exception, which I don't want.
So:
how can I call validation explicitly in EF and make sure either the object is valid and I can call SaveData(), or the object is invalid and I can collect somehow validation failure information to pass to client.
Haw can I pass this validation failure information back to client, as part of data contract, and not an an exception.
Thanks
You can use two approaches:
Use standard response data contract for success and fault contract with FaultException<YourFaultContract> for validation failure. Typed fault exceptions are way to define "expected" exceptions - it is just another data contract passed in SOAP Fault describing some failure.
Create response data contract which contains something like result code, response data, failure message etc. and use this data contract for both success and failure. I don't like this approach but it is easier to use in some ESB where faults are processed in special way.

Writing a data contract to the SOAP envelope headers for an outgoing FaultException?

I am in a bit of a pickle with a current project. We have an integration partner who is refusing to conform to contract, and they are expecting a fault contract with custom headers, rather than the WSDL-defined message contract that includes the same headers and a contractually valid message body. It is not a problem to send a SOAP fault with WCF, as one can simply throw FaultException. The real bind is the requirement that the fault contain custom headers. I was able to serialize a custom header by using the OperationContext, however it does not serialize the way our integration partner requires.
Using OperationContext.Current.OutgoingMessageHeaders, it is possible to create a custom MessageHeader<T> that contains the object you wish to include in the header...it can be a POCO, DataContract, or MessageContract. When using a message contract, namespaces seem to get ignored, and the serialized message has a bunch of invalid xmlns= attributes on each member of the message, which is also a problem. Once a MessageHeader is created, calling the .GetUntypedHeader(name, namespace) method will generate a MessageHeader that can be added to the OperationContext's OutgoingMessageHeaders. The problem is that you can't add an object to the headers directly...they apparently must always be wrapped, since the GetUntypedHeader method requires a wrapper element name and namespace.
The required header is as follows:
<SOAP-ENV:Header>
<imsx_syncResponseHeaderInfo xmlns="http://www.imsglobal.org/services/lti/xsd/CoreOutcomesService_bv1p0">
<imsx_version>UNUSED</imsx_version>
<imsx_messageIdentifier>12345678-abcd-1234-ef00-1234567890ab</imsx_messageIdentifier>
<imsx_statusInfo>
<imsx_codeMajor>failure</imsx_codeMajor>
<imsx_severity>error</imsx_severity>
<imsx_messageRefIdentifier>12345</imsx_messageRefIdentifier>
<imsx_description>yadda yadda some error message here</imsx_description>
<imsx_codeMinor>
<imsx_codeMinorField>
<imsx_codeMinorFieldName>SomeCodeName</imsx_codeMinorFieldName>
<imsx_codeMinorFieldValue>somecode</imsx_codeMinorFieldValue>
</imsx_codeMinorField>
</imsx_codeMinor>
</imsx_statusInfo>
</imsx_syncResponseHeaderInfo>
</SOAP-ENV:Header>
If it was not for the fact that the header, imsx_syncResponsHeaderInfo, has three child elements, we would probably be in business. However, it is impossible to create a message header directly that wraps three separate objects, and when using a MessageContract with IsWrapped=false, every direct child element of the imsx_syncResponseHeaderInfo element gets serialized with an xmlns attribute that defines an incorrect namespace (it seems to take the TNS of the service contract). That makes the header invalid according to the contractual schema, and the consumer cannot deserialize it.
Is there some way to add a MessageContract to the outgoing message headers of a WCF-delivered SOAP Fault, without requiring that it be wrapped, and such that the child elements to not get serialized each with their own xmlns attribute containing the TNS of the service contract?
As noted above:
The issue was actually due to how a business partner was deserializing our message contents. They did not want to take responsibility for the issue at the time, and the burden fell on my team and I. We finally managed to get them to fix their own issue, so we never actually had to solve the problem.

FaultException handling in BizTalk

The FaultContract from my WCF service doesn't have a datacontract members; thus when the service is consumed in BizTalk, the generated schema doesn't show up any members. How do I handle in BizTalk?
While consuming this WCF service from a .NET client, the implementation provides the exception along with Class library ( of data objects) and I catch the fault of that exception type.
I am not sure if this is possible. But to get it to work biztalk must have access to the dll with your data objects. You could try referencing the dll from your biztalk project.
If you are consuming the service from an orchestration you could try the following steps:
Add an XSD representation of your
FaultContract to the project and use
this as message type on your fault
operation.
Add an exception handler block to
the orchestration using this fault
operation as message type
On your two-way WCF SendPort go to
the Messages tab and then on
'Inbound BizTalk Message Body'
change the radio button to Path.
On 'Body path expression' add
something like this:
/* [namespace-uri()='http://myservice.namespace/'] | /* [local-name()='Fault'] /* [local-name()='Detail']/*
These two xpaths separated by a '|' will make the adapter depending on what it receives publish either the correct service reply or the content of the details node which is where the WCF FaultContract is placed. This will allow the disassembler to work when trying to identify the message.
A side effect of this is that you will have a problem catching SOAP-faults in the orchestration but this is solved by creating a schema representation of a SOAP-fault (http://schemas.datacontract.org/2004/07/System.ServiceModel#ExceptionDetail) and use that as a second fault operation.
I have found issue. Our web service return fault XML in lower case. So correct XPath is
/*[local-name()='Fault']/*[local-name()='detail']/*

MsmqIntegrationBinding Serialization with Unknown Message Body Types

I'm looking to use the MsmqIntegrationBinding to integrate with a legacy queue which has a serialized object as the message body. Has anyone come up with a way to obtain the "metadata" of the message body and create a service side class to use within the service?
For example, if I put in a serialized Product object from System A and my service needs to consume it, how do I provide MsmqMessage the type if I do not have the Product class on my side? I was thinking of reading off a message in a separate program, deserializing, and then emitting via the code dom. Ideas?
I wholeheartedly recommend against attempting to emit the deserialized type at runtime in the message destination. Either work with the XML at the destination to obtain the data you desire, or build data contracts that both the source and destination can adhere to.
Hmm... in WCF, you can define service methods which take (and optionally return) an untyped Message type. This seems to fit your bill quite nicely.
Other than with strongly typed messages, you'll have to do all the putting together of the message on the client and the taking apart on the server by means of reading the raw XML - but that seems to be what you're looking for, right?
Find more information and samples here:
WCF - Handling Generic Messages
How to pass a generic object through WCF
Untyped messages on WCF
Untyped messages have some restrictions, e.g. you can only read them once on the server, but you should be able to manage your scenario with this, I think.
Marc