Вызов методов MVC4 WebAPI из C # Metro UI Client с использованием PostAsync, HttpClient & Json - PullRequest
12 голосов
/ 25 марта 2012

Я создал метод, используя новые функции WebAPI в MVC4, и он работает в Azure. Метод требует, чтобы вы опубликовали простой объект LoginModel, который состоит из имени пользователя и пароля. Да, я планирую закрепить это дальше, как только преодолею этот скачок скорости :-) Затем метод отвечает объектом в формате Json:

enter image description here

Я могу успешно вызвать этот метод, используя Fiddler, при условии, что я включил «Content-Type: application / json» в заголовки запроса. Возвращается с 200, и я могу зайти в Fiddler Inspector и просмотреть объект отклика Json просто отлично:

enter image description here

Однако у меня возникают проблемы при вызове этого же метода из приложения MetroUI в Windows8 с использованием C # / XAML. Я начал играть с HttpClient и новыми концепциями Async в C #, и независимо от того, как я отформатировал свои вызовы Post (даже когда явно указывал, что я хочу, чтобы Content-Type был "application / json"), Fiddler возвращается с ошибкой 500 и заявляет, что при попытке использовался Content-Type: "text / html". Я считаю, что это корень проблемы:

enter image description here

Я перепробовал все мыслимое, чтобы опубликовать этот метод и вернуть объект Json, вот моя последняя попытка:

HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        HttpContent content = new StringContent(@"{ ""Username"": """ + Username.Text + @", ""Password"": """ + Password.Text + @"""}");

        client.PostAsync("http://myapi.com/authentication", content).ContinueWith(result =>
        {
            var response = result.Result;

            response.EnsureSuccessStatusCode();
        });

Это приводит к ошибке 500 с Content-Type, установленным в "text / html"

Вот еще одна попытка, которая также не удалась:

HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.PostAsync("http://myapi.com/authentication", new StringContent(@"{ ""Username"": """ + Username.Text + @", ""Password"": """ + Password.Text + @"""}", Encoding.UTF8, "application/json"));
string statusCode = response.StatusCode.ToString();

Кто-нибудь может указать мне правильное направление?

Только что попробовал следующий код благодаря совету Nemesv:

HttpClient httpClient = new HttpClient();
        HttpContent content = new StringContent(@"{ ""Username"": """ + Username.Text + @", ""Password"": """ + Password.Text + @"""}");
        content.Headers.ContentType = new MediaTypeHeaderValue("application/json");


        HttpResponseMessage response = await httpClient.PostAsync("http://webapi.com/authentication", content);

        string statusCode = response.StatusCode.ToString();
        response.EnsureSuccessStatusCode();

Теперь он показывает «application / json» в заголовке моего запроса, но все еще показывает «text / html» в веб-сессии:

enter image description here

Ответы [ 2 ]

22 голосов
/ 25 марта 2012

Попробуйте установить Headers.ContentType:

HttpClient httpClient = new HttpClient();
HttpContent content = new StringContent(@"{ ""Username"": """ + "etc." + @"""}");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = 
    await httpClient.PostAsync("http://myapi.com/authentication", content);
string statusCode = response.StatusCode.ToString();
6 голосов
/ 26 сентября 2012

Не хватает какой-то попытки, это работает.

UserLoginModel user = new UserLoginModel { Login = "username", Password = "password" };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(user);
HttpContent content = new StringContent(json);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:1066/api/");
HttpResponseMessage response = client.PostAsync("Authenticate", content).Result;

if (response.IsSuccessStatusCode)
{
  var result = response.Content.ReadAsAsync<ResultModel>().Result;
}
else
{
  return string.Empty;
}
...