How to create message body with object in WCF?
-
24 เมษายน 2555 15:00
Im having hard time to create proper Message body. I have a class derived from IErrorHandler which creates Message upon any exception. I'm trying to create the Message body same as the return parameter of the operation. Meaning the client should not see it as exception but it should get a proper response back instead of Fault.
But im getting the following error
Error in deserializing body of reply message for operation 'ImportNewOrder'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'ImportNewOrderResponse' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'Response' and namespace 'http://schemas.datacontract.org/2004/07/IntegrationService.Domain.Contracts'
Here is my code
public class ValidationAwareErrorHandler : IErrorHandler { public ValidationAwareErrorHandler() { } public bool HandleError(Exception error) { return true; } public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { fault = Message.CreateMessage(version, null, new Response() { StatusCode = 1, StatusMessage = error.Message }); } }[DataContract] public class Response { [DataMember] public int StatusCode { get; set; } [DataMember] public string StatusMessage { get; set; } } [OperationContract] public Response ImportNewOrder(OrderRequest request) { // Do some business implemention // and return Response object with Sucess // if any error occurrs, im hoping it will get handle by IErrorHandle Response res = new Response(); res.StatusCode = 0; res.StatusMessage = "SUCCESS"; return res; }
- แก้ไขโดย lax4u 24 เมษายน 2555 15:01
ตอบทั้งหมด
-
26 เมษายน 2555 6:19ผู้ดูแล
Try setting Name attribute to 'ImportNewOrder' for the OperationContract and setting the Namespace attribute to 'http://tempuri.org/' for the ServiceContract.
[ServiceContract(Namespace="http://tempuri.org/")] public interface IServiceContract { [OperationContract(Name = "ImportNewOrder")] Response ImportNewOrder(OrderRequest request); }Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework
-
26 เมษายน 2555 15:32
That didnt solve my issue.
and after doing some reaserch i found its the way WCF framework serializes the response when return object has [DataContract] attribute.
Below is the response XML generated by WCF framework when it serializes the Response object. Notice the XML element name, its not same as the name of the return object. The first element inside the <body> is MethodName+"Response" and the next element is MethodName+"Result". Dont know why serializer do this instead of using just return object's name
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header /> <s:Body> <ImportNewOrderResponse xmlns="http://IntegrationService/ImportOrder"> <ImportNewOrderResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <StatusCode>1</StatusCode> <StatusMessage>ERROR</StatusMessage> </ImportNewOrderResult> </ImportNewOrderResponse> </s:Body>
Below is the XML generated by WCF when i create response object in IErrorHandler ( see my code above). and since this XML doesnt match with the expected XML, the WCF framework throws communication error
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header /> <s:Body> <ResponseDTO xmlns="http://IntegrationService/ImportOrder" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <StatusCode>1</StatusCode> <StatusMessage>ERROR</StatusMessage> </ResponseDTO> </s:Body> </s:Envelope>
I found that if i use [MessageContract] instead of [DataContract] WCF framework will keep the XML element name same as return object name.