I'm using the WCF WebApi stack (Preview 4) via NuGet (pkg version 0.3.0) and cannot seem to figure out how to "POST a POCO" using HttpClient
.
Given the following:
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
...
When the Post
method is called, I get the following exception:
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)
...
This is using the NuGet 0.3.0 package.
I've tried adding <Serializable()>
and even <DataContract()>
to MyInfo
, but that didn't help. Am I just doing something wrong?
I found this post here on StackOverflow where it looks like someone is doing something similar to what I did above. I've even duplicated his work (guessing that his Machine
object was a simple POCO like my MyInfo
is) and ran into the same "cannot serialize" exception.
I ended up finding the problem myself. I was missing the media type. I changed the Post
method to look like:
Using client as New HttpClient(baseUri)
Using response = client.Post(requestUri, New ObjectContent(Of MyInfo)(value, "text/xml"))
' Do stuff
End Using
End Using
and it started working. I guess that makes sense. For some reason, I thought that there was some sort of default media type precedence built-in so that you didn't have to go out of your way to specify the media type each time. Maybe there is, but I'm still doing something wrong?
Update:
My original problem actually had nothing to do with the media type, even though that actually did fix/workaround the problem. The problem seems to happen when MyInfo
is nested inside of a Module
like this.
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
Once MyInfo
moved outside of the Module
, the error no longer happens. It's also worth noting that while the media type is no longer required to prevent the exception, the lack of it results in no Content-Type
header, which may not fly server-side as the server may not know how to deserialize the message body. In my case, I needed to leave the media type in so that the request would include a Content-Type: application/xml
header for the server's sake.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With