简体   繁体   中英

How to POST an Object to Web API from .NET 3.5 WebClient or WebRequest

I'm attempting to create a .NET 3.5 client library to connect to a Web API endpoint. In 4.0, 4.5, it's fairly straightforward:

Dim mediaType = New MediaTypeHeaderValue("application/json")
Dim jsonFormatter = New JsonMediaTypeFormatter()
Dim client As New HttpClient
client.BaseAddress = New System.Uri(_url)
Dim content As HttpContent = New ObjectContent(Of MyObject)(Me.MyObject, jsonFormatter)
Dim resp As HttpResponseMessage = client.PostAsync("api/Post/", content).Result

If resp.IsSuccessStatusCode Then
  With HttpContext.Current.Response
     SetHeaders(HttpContext.Current.Response, Me.MyObject.Type)
     .BinaryWrite(resp.Content.ReadAsByteArrayAsync().Result)
     .Flush()
     .Close()
     .End()
  End With
Else
 _isSuccess = False
End If

I'm sending MyObject via ObjectContent through the HttpClient via the HttpContent class. The API endpoint accepts it as:

Public Function Post(obj As MyObject) As HttpResponseMessage
            Dim x As New MyObjectHandler(obj)
            Dim result As New HttpResponseMessage
            result.Content = New StreamContent(x.GetStream)
            Return result
End Function

When I POST to this, my object is intact with all variables in the correct layout. In the .NET 3.5 manner I've attempted to use, this isn't the case. The POST gets to the function and begins to step through, but the object is not filled with any values whatsoever. Here's my test code to attempt the traversal using .NET 3.5 WebClient:

Dim client As New WebClient
client.Headers(HttpRequestHeader.ContentType) = "application/json"
client.BaseAddress = New System.Uri(_url).ToString
Dim json As String = NewtonSoft.Json.JsonConvert.SerializeObject(Me.MyObject)

Dim result = client.UploadData("api/Post/", Encoding.UTF8.GetBytes(json))

What is the correct way to do this in order to get a WebClient example to push the object to the API endpoint? Do I need to create a special endpoint just for a 3.5 client?

You should be able to use the JSON.Net serializer to serialize the objects just fine.

The JsonMediaTypeFormatter uses the following settings, not sure if those might change the shape of the payload:

  return new JsonSerializerSettings()
        {
            MissingMemberHandling = MissingMemberHandling.Ignore,
            TypeNameHandling = TypeNameHandling.None
        };

If all else fails, write a .net 4 client, POST the endpoint and use fiddler to compare the payload with what is sent using .net 3.5 client. I am guessing it is just a client side configuration issue.

Have you tried to just using the HttpClient NuGet package?

See: http://www.nuget.org/packages/HttpClient

Per this page , there is probably some extra HTTP goo being transmitted using WebClient :

If you are used to using WebClient or HttpWebRequest then it is worth noting that HttpClient differs in some interesting ways – here's how to think about an HttpClient:

  1. An HttpClient instance is the place to configure extensions, set default headers, cancel outstanding requests and more.
  2. You can issue as many requests as you like through a single HttpClient instance.
  3. HttpClients are not tied to particular HTTP server or host; you can submit any HTTP request using the same HttpClient instance.
  4. You can derive from HttpClient to create specialized clients for particular sites or patterns
  5. HttpClient uses the new Task-oriented pattern for handling asynchronous requests making it dramatically easier to manage and coordinate multiple outstanding requests.

Finally, I would use Fiddler to compare between your .NET 4.x solution and 3.5.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM