2

Я пытаюсь выполнить запрос PUT к методу веб-API с использованием HttpClient. Почти идентичный запрос POST работает так, как ожидалось, но запрос PUT приводит к ошибке 400 (неудачный запрос). Я не уверен, что я делаю неправильно.Результаты запроса PUT в 400 Bad Request

Вот мой веб-код контроллера API:

public HttpResponseMessage Post(object val) 
{ 
    Debug.WriteLine(val.ToString()); 
    return new HttpResponseMessage(HttpStatusCode.OK); 
} 

public HttpResponseMessage Put(int id, object val) 
{ 
    Debug.WriteLine(id.ToString(), val.ToString()); 
    return new HttpResponseMessage(HttpStatusCode.OK); 
} 

А потом вот код на стороне клиента, который пытается вызвать эти методы. Запрос POST выглядит следующим образом:

var client = new HttpClient(); 
var content = log.ToJsonContent(); 
var address = new Uri(_webApiBaseAddress + "logs"); 

client.PostAsync(address, content).ContinueWith(requestTask => 
    { 
     requestTask.Result.EnsureSuccessStatusCode(); 
    }); 

И запрос PUT, что не работает, выглядит так:

var client = new HttpClient(); 
var content = log.ToJsonContent(); 
var address = new Uri(_webApiBaseAddress + "logs/" + jobId); 

client.PutAsync(address, content).ContinueWith(requestTask => 
    { 
     requestTask.Result.EnsureSuccessStatusCode(); 
    }); 

Как вы можете видеть, я лишен функциональности вниз, как голый, как я может получить его, и я все равно получаю ошибку с запросом PUT каждый раз.

Кстати, я могу успешно выполнить запрос PUT с помощью клиента RestSharp. Этот код успешно вызывает метод API:

var client = new RestClient(_webApiBaseAddress); 
var request = new RestRequest("logs/{id}", Method.PUT); 
request.AddUrlSegment("id", jobId.ToString()); 
request.AddObject(log); 
client.Execute(request); 

Проблема с делать это таким образом, что любой объект, я прохожу в использовании AddObject только заканчивает тем, что строка, когда он попадает в метод контроллера. Если я передаю int, я хочу получить int. HttpClient делает это с помощью метода POST, поэтому я хотел использовать его, но PUT выдает ошибку. Таким образом, я застрял в двух полуработающих решениях, которые, к сожалению, не доходят до полного решения. Я был бы признателен за обратную связь по любому шаблону, чтобы заставить это работать.

Edit: Поскольку это было упомянуто ниже, вот мой метод .ToJsonContent() расширения:

public static StringContent ToJsonContent(this object obj) 
{ 
    var converter = new IsoDateTimeConverter(); 
    converter.DateTimeStyles = DateTimeStyles.AdjustToUniversal; 
    var json = JsonConvert.SerializeObject(obj, converter); 
    var content = new StringContent(json, Encoding.UTF8, "application/json"); 
    return content; 
} 
+0

человек у меня такая же проблема –

ответ

4

ли ToJsonContent функциональности, что вы написали? Если это так, возможно, стоит посмотреть, чтобы убедиться, что вы поставляете правильный Content-Type и генерируете правильный формат JSON. Для устранения JSON является проблемой, которую вы могли бы сделать тест вроде этого:

var client = new HttpClient(); 
var content = new StringContent(
    @"{""message"": ""this is a log message"" }", 
    Encoding.UTF8, 
    "application/json"); 

var address = new Uri(_webApiBaseAddress + "logs/" + jobId); 

client.PutAsync(address, content).ContinueWith(task => 
{ 
    task.Result.EnsureSuccessStatusCode(); 
}); 

Noice Я поставляю application/json в качестве параметра. Я знаю, что веб-API делает сумасшедшие вещи, если он не знает, какой тип медиафайлов имеет ваш запрос. Тот факт, что ваш тест RestClient делает, заставил меня думать, что отправленный JSON недействителен.

Вторая часть, которая может вам помочь, заключается в том, что если вы тестируете это в виде консольного приложения, которое потенциально может закрыться до того, как асинхронный вызов действительно будет инициализирован и отправлен, вы не получите ответ. Вы можете проверить это, просто положив .Wait() после ContinueWith, но я подозреваю, что если вы действительно получите ответ на 400, это не так.

+0

Да, это метод расширения, который я написал. Он делает именно то, что у вас есть, но строка json генерируется с помощью 'JsonConvert.SerializeObject' вместо стробированной строки. Я решил, что это проблема, потому что метод POST работает правильно, и я использую тот же метод расширения, чтобы преобразовать данные, которые были переданы ему. –

+0

ОК. Я могу сделать PutAsync, как это успешно, на моем собственном веб-API. Если вы можете посмотреть свой запрос через Fiddler или какой-либо другой метод, вы должны взглянуть на него.Возможно, даже возьмите этот запрос и передайте его через композитора Фиддлера, чтобы отправить запрос вручную, чтобы убедиться, что вы получаете то, что ожидаете. Если это все еще не работает, я думаю, вам нужно будет взглянуть на свой веб-API, чтобы увидеть, есть ли там проблема, которая вернет ваш плохой запрос. –