Проблемы с WCF REST при десериализации XElement

#.net #wcf #datacontractserializer #wcf-rest

#.net #wcf #datacontractserializer #wcf-rest

Вопрос:

У меня есть служба WCF REST, которая обрабатывает сообщение, получая XML-файл и возвращая другой. На данный момент другие методы, которые получают XML-файл, работают нормально.

Похоже, что DataContractSerializer не может десериализовать текст XML в XElement, хотя мне удалось сделать это с помощью DataContractSerializer непосредственно на PoC:

 static void Main(string[] args)
{
    var stream = File.Open("afile.xml", FileMode.Open); // afile.xml has the same contect as the request below
    var serial = new System.Runtime.Serialization.DataContractSerializer(typeof(XElement));
    var obj = serial.ReadObject(stream); //obj is a XElement instance
}
 

Проблема, когда я пытаюсь ОТПРАВИТЬ XML-файл в свою службу REST, заключается в следующем исключении:

 <Exception>
  <ExceptionType>System.Runtime.Serialization.SerializationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
  <Message>Unable to deserialize XML body with root name 'documento' and root namespace 'http://uri.org' (for operation 'Publicar' and contract ('IDocumentos',  'http://tempuri.org/')) using DataContractSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.</Message>
  <StackTrace>
    at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.ReadObject(Message message)
    at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
    at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
    at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
    at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpcamp;amp;amp; rpc)
    at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpcamp;amp;amp; rpc)
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpcamp;amp;amp; rpc)
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpcamp;amp;amp; rpc)
    at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
    at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
    at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
    at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
    at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
    at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
    at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
    at System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
    at System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
    at System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
    at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
    at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
    at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
    at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
    at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
    at System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
    at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
    at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
    at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
  </StackTrace>
  <ExceptionString>System.Runtime.Serialization.SerializationException: Unable to deserialize XML body with root name 'documento' and root namespace 'http://uri.org' (for operation 'Publicar' and contract ('IDocumentos',  'http://tempuri.org/')) using DataContractSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.</ExceptionString>
</Exception>
 

Контракт:

 [ServiceContract]
public interface IDocumentos
{
    [OperationContract]
    [WebInvoke(UriTemplate = "", Method = "POST", 
        RequestFormat = WebMessageFormat.Xml, 
        ResponseFormat = WebMessageFormat.Xml, 
        BodyStyle = WebMessageBodyStyle.Bare)]
    XElement Publicar(XElement documento);
}
 

И запрос, отправляемый через Fiddler:

 POST http://integracao/documentos/ HTTP/1.1
User-Agent: Fiddler
Host: integracao
Content-Length: 46
Content-Type: text/xml

<documento></documento>
 

Маршруты добавляются в Application_Start, создавая ServiceHostFactory и используя его для добавления маршрутов в RouteTable.

Я проверил другие вопросы, но, похоже, ни один из них не был затронут подобным образом.

Заранее спасибо!

Комментарии:

1. Неважно, я обнаружил, что служба, которую я пытался выполнить, была опубликована со старой версией, в параметрах которой не было XElement, вместо этого это был класс, поэтому он все равно не будет работать. Прошу прощения за пустую трату времени, которую это могло вызвать!

2. пожалуйста, отправьте этот комментарий в качестве ответа и примите его, чтобы людям было проще пропустить этот вопрос.

3. Да, я пытался, но в то время я не мог, ПОЭТОМУ сказал мне подождать 6 часов. Теперь они прошли, спасибо за напоминание.

Ответ №1:

Неважно, я обнаружил, что служба, которую я пытался выполнить, была опубликована со старой версией, в параметрах которой не было XElement, вместо этого это был класс, поэтому он все равно не будет работать.

Прошу прощения за пустую трату времени, которую это могло вызвать!