How to issue PUT HttpWebRequest

2019-08-11 10:52发布

问题:

I'm trying to integrate with an API that requires a PUT to update data:

Here's an example from them using curl:

curl --request PUT \
     --user-agent "Your Client Name/1.0" \
     --header "Content-Type: application/xml" \
     --data-binary '<order><status_id>10</status_id></order>' \
     https://www.example.com/api/v2/orders/101

However, I'd need to use JSON (they support that as well) using .NET MVC 3. Any idea on how I can do that?

I use the code below for GET successfully:

Order obj = Call<Order>(url, "GET");

    private T Call<T>(string url, string methodType) where T : class {
        T result;
        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        request.Method = methodType;
        request.Accept = "application/json";
        request.ContentType = "application/json";

        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
            JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
            string jsonData = reader.ReadToEnd();
            result = (T)jsSerializer.Deserialize<T>(jsonData);
        }

        return result;
    }

However, can I issue a PUT using a similar method?

Order obj = Call<Order>(url, "PUT");

If so, where do I put the data that's required in "data-binary"?

回答1:

Well, here's a possible point of origin - untested; written straight into the browser; not production code; assumes that the PUT call both sends and receives the same object type (which is probably not the case)...

The main addition is that you need to supply the request's ContentLength, and you need to write the serialized JSON object to the request stream, which you'll get by calling HttpWebRequest::GetRequestStream(). It's the same approach as when POSTing.

private T Call<T>(string url, string methodType, T data) where T: class
{
    T result;

    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    request.Method = methodType;
    request.ContentType = "application/json";
    request.Accept = "application/json";

    if (methodType == "PUT" || methodType == "POST")
    {
       JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
       string jsonData = jsSerializer.Serialize(data);

       byte[] arrData = Encoding.UTF8.GetBytes(jsonData);
       request.ContentLength = arrData.Length;

       using (Stream dataStream = request.GetRequestStream())
       {
          dataStream.Write(arrData, 0, arrData.Length);
       }
    }

    // Note: You may not need to parse any response content,
    // or it may be a different class
    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        using (StreamReader reader 
                          = new StreamReader(response.GetResponseStream()))
        {
            JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
            string jsonData = reader.ReadToEnd();
            result = (T)jsSerializer.Deserialize<T>(jsonData);
        }
    }
    return result;
}