petko_stankoski
petko_stankoski

Reputation: 10723

Patch API call in C# doesn't work, the same call works in swagger

I want to use an external API which has Swagger. In Swagger I am calling this url:

PATCH /rest/inventory/item/{id}

with parameters: X-Auth-Token, id and patchOperations which looks like this:

[
  {
    "op": "replace",
    "path": "price",
    "value": 6.2
  }
]

And when I call this method with those parameters, it works. I get success code 200 and afterwards when I call the GET method I see that the price of the item has been updated to 6.2.

Now I want to do this in C#. I am already calling some GET methods from the same API successfully. This is my code for the PATCH method:

var model = new Dictionary<string, object>
             {
                {"op", "replace"},
                {"path", "price"},
                {"value", 6}
             };

var blabla = await _httpProvider.PatchAsync($"https://{url}/server/rest/inventory/item/{id}", model, null, null, null, connection.Request.HeaderParameters);

public async Task<HttpResponseModel> PatchAsync<T>(string uri, T data, HttpClientHandler httpClientHandler = null, TimeSpan? timeout = null, string contentTypes = null, Dictionary<string, string> headerParameters = null)
    {
        using (var client = CreateHttpClient(httpClientHandler, timeout, contentTypes, headerParameters))
        {
            var requestContent = new StringContent(JsonConvert.SerializeObject(data));
            var response = await client.PatchAsync(new Uri(uri), requestContent);
            var result = new HttpResponseModel
            {
                Success = response.IsSuccessStatusCode,
                ResponseContent = await response.Content.ReadAsStringAsync(),
                ResponseTime = sw.Elapsed
            };

            return result;
        }
    }

Where is my mistake? I am getting error StatusCode: 500, ReasonPhrase: 'Server Error', Version: 1.1, Content: System.Net.Http.StreamContent

Upvotes: 0

Views: 482

Answers (1)

Chris Schaller
Chris Schaller

Reputation: 16757

The mistake is that you're not pasting the same content, not quite anyway.

Your PATCH example is an array of a objects that has 3 properties, in your example there is only 1 element in the array, but it is still an array. Your C# is serialized into single object.

It's subtle but your JSON that you are sending is actually:

{
    "op": "replace",
    "path": "price",
    "value": 6
}

So instead you need to send your dictionary or other object inside an array:

var model = new List<object> {
    {
        new Dictionary<string, object>
        {
            { "op", "replace"},
            {"path", "price"},
            {"value", 6}
        }
    };

Ideally, in c# you would create a class to represent this DTO (Data Transfer Object), it can work with anonymous types or with dictionaries (a Dictionary<string,object> serializes into a single JSON object) but the code gets harder to manage over time.

public class DTO
{
    public string op { get; set; }
    public string path { get; set; }
    public object value { get; set; }
}
...

var model = new List<DTO>
    {
        new DTO { 
          op = "replace",
          path = "price",
          value = 6
         }
    };

Upvotes: 2

Related Questions