2011-07-27 19 views
5

Tôi đang sử dụng ngăn xếp WCF WebApi (Xem trước 4) qua NuGet (phiên bản pkg 0.3.0) và dường như không thể tìm ra cách "POST POCO" bằng cách sử dụng HttpClient.Cách POST một POCO với HttpFient của WCF WebApi

Do sau:

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 
... 

Khi phương pháp Post được gọi, tôi nhận được ngoại lệ sau đây:

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) 
... 

này đang sử dụng gói NuGet 0.3.0.

Tôi đã thử thêm <Serializable()> và thậm chí <DataContract()> đến MyInfo, nhưng điều đó không giúp ích gì. Tôi chỉ làm điều gì đó sai?

Tôi đã tìm thấy this post tại đây trên StackOverflow nơi có vẻ như ai đó đang làm điều gì đó tương tự như những gì tôi đã làm ở trên. Tôi thậm chí đã sao chép công việc của anh ấy (đoán rằng đối tượng Machine của anh ta là một POCO đơn giản như là MyInfo của tôi) và chạy vào cùng một ngoại lệ "không thể tuần tự hóa".

Trả lời

5

Tôi đã tự mình tìm ra vấn đề. Tôi đã bỏ lỡ loại phương tiện truyền thông. Tôi đã thay đổi phương thức Post để trông giống như:

và nó bắt đầu hoạt động. Tôi đoán nó có lý. Vì lý do nào đó, tôi nghĩ rằng có một số loại phương tiện truyền thông mặc định ưu tiên được xây dựng sẵn để bạn không phải đi ra khỏi con đường của bạn để xác định loại phương tiện truyền thông mỗi lần. Có lẽ có, nhưng tôi vẫn làm điều gì đó sai?

Cập nhật:

vấn đề ban đầu của tôi thực sự không có gì để làm với các loại phương tiện truyền thông, mặc dù điều đó thực sự đã sửa chữa/workaround vấn đề. Vấn đề dường như xảy ra khi MyInfo được lồng vào bên trong của một Module như thế này.

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 

Khi MyInfo chuyển bên ngoài của Module, lỗi không còn xảy ra. Nó cũng đáng chú ý rằng trong khi loại phương tiện truyền thông không còn cần thiết để ngăn chặn ngoại lệ, việc thiếu nó dẫn đến không có tiêu đề Content-Type, có thể không bay phía máy chủ vì máy chủ có thể không biết cách deserialize nội dung thư. Trong trường hợp của tôi, tôi cần rời khỏi loại phương tiện để yêu cầu sẽ bao gồm tiêu đề Content-Type: application/xml vì mục đích của máy chủ.

+0

Thay vì mã hóa cứng trong "văn bản/xml", tôi đã sử dụng XmlMediaTypeFormatter.DefaultMediaType.MediaType (là "application/xml" - một loại phương tiện "tốt hơn" dù sao đi nữa). Vẫn muốn biết nếu tôi có thể tránh làm điều này và chỉ rơi trở lại trên một số mặc định lành mạnh. – ckittel