2011-07-27 11 views
5

Estoy usando la pila WCF WebApi (Vista previa 4) a través de NuGet (versión de paquete 0.3.0) y no puedo encontrar la manera de "PUBLICAR un POCO" usando HttpClient.Cómo PUBLICAR un POCO con WCtt WebApi's HttpClient

Teniendo en cuenta lo siguiente:

Public Class MyInfo 
    Public Property MyDate As DateTime 
    Public Property MyId As Guid 
End Class 

... 
Dim value = New MyInfo With {.MyDate = Today, .MyId = Guid.NewGuid()} 

Using client as New HttpClient(baseUri) 
    Using response = client.Post(requestUri, New ObjectContent(Of MyInfo)(value)) 
     ' Do stuff 
    End Using 
End Using 
... 

Cuando se llama al método Post, me sale el siguiente excepción:

The 'XmlSerializer' serializer cannot serialize the type 'MyInfo'. 

at Microsoft.ApplicationServer.Http.XmlMediaTypeFormatter.GetSerializerForType(Type type) 
at Microsoft.ApplicationServer.Http.XmlMediaTypeFormatter.OnWriteToStream(Type type, Object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext context) 
at Microsoft.ApplicationServer.Http.MediaTypeFormatter.WriteToStream(Type type, Object instance, Stream stream, HttpContentHeaders contentHeaders, TransportContext context) 
at Microsoft.ApplicationServer.Http.ObjectContent.WriteToStreamInternal(Stream stream, TransportContext context) 
at Microsoft.ApplicationServer.Http.ObjectContent.SerializeToStream(Stream stream, TransportContext context) 
at System.Net.Http.HttpContent.LoadIntoBuffer(Int32 maxBufferSize) 
at System.Net.Http.HttpClientChannel.PrepareWebRequestForContentUpload(HttpWebRequest webRequest, HttpRequestMessage request) 
at System.Net.Http.HttpClientChannel.CreateAndPrepareWebRequest(HttpRequestMessage request) 
at System.Net.Http.HttpClientChannel.Send(HttpRequestMessage request, CancellationToken cancellationToken) 
at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) 
at System.Net.Http.HttpClient.Send(HttpRequestMessage request) 
at System.Net.Http.HttpClient.Post(Uri requestUri, HttpContent content) 
at System.Net.Http.HttpClient.Post(String requestUri, HttpContent content) 
... 

Esto es usando el paquete NuGet 0.3.0.

He intentado agregar <Serializable()> e incluso <DataContract()> a MyInfo, pero eso no ayudó. ¿Estoy haciendo algo mal?

Encontré this post aquí en StackOverflow donde parece que alguien está haciendo algo similar a lo que hice anteriormente. Incluso he duplicado su trabajo (adivinando que su objeto Machine era un POCO simple como mi MyInfo) y encontré la misma excepción "no puedo serializar".

Respuesta

5

Terminé encontrando el problema yo mismo. Me faltaba el tipo de medios. He cambiado el método de Post para parecerse a:

Using client as New HttpClient(baseUri) 
    Using response = client.Post(requestUri, New ObjectContent(Of MyInfo)(value, "text/xml")) 
     ' Do stuff 
    End Using 
End Using 

y comenzó a trabajar. Supongo que eso tiene sentido. Por alguna razón, pensé que había algún tipo de precedente de tipo de medios predeterminado, de modo que no tuviera que hacer todo lo posible para especificar el tipo de medio cada vez. Tal vez hay, pero todavía estoy haciendo algo mal?

Actualización:

Mi problema original en realidad no tenía nada que ver con el tipo de medio, a pesar de que en realidad se soluciona/solución del problema. El problema parece ocurrir cuando MyInfo está anidado dentro de un Module de esta manera.

Module Module1 

    Sub Main() 
     Dim value = New MyInfo With {.MyDate = Today, .MyId = Guid.NewGuid()} 
     Dim payload As HttpContent = New ObjectContent(Of MyInfo)(value) 

     Using client as New HttpClient(baseUri) 
      Using response = client.Post(requestUri, New ObjectContent(Of MyInfo)(value)) 
       ' Do stuff 
      End Using 
     End Using 
    End Sub 

    Public Class MyInfo 
     Public Property MyDate As DateTime 
     Public Property MyId As Guid 
    End Class 

End Module 

Una vez MyInfo se trasladó fuera de la Module, el error ya no sucede. También vale la pena señalar que, aunque el tipo de medio ya no es necesario para evitar la excepción, la falta de ello no da como resultado un encabezado Content-Type, que puede no volar desde el servidor ya que el servidor puede no saber cómo deserializar el cuerpo del mensaje. En mi caso, tenía que dejar el tipo de medio para que la solicitud incluyera un encabezado Content-Type: application/xml por el bien del servidor.

+0

En lugar de una codificación difícil en "text/xml" terminé usando XmlMediaTypeFormatter.DefaultMediaType.MediaType (que de todos modos es "application/xml" - un tipo de medios "mejor"). Todavía me gustaría saber si podría evitar hacer esto y simplemente recurrir a algunos valores predeterminados. – ckittel