2012-03-25 21 views
12

Utworzono metodę wykorzystującą nowe funkcje WebAPI w MVC4 i działającą na platformie Azure. Ta metoda wymaga opublikowania prostego obiektu LoginModel, który składa się z nazwy użytkownika i hasła. Tak, mam zamiar dalej to zabezpieczenie raz ja ominąć tej prędkości guz :-) Sposób następnie reaguje z obiektu w formacie JSON:Wywołanie metod WebAPI MVC4 z klienta C# Metro UI przy użyciu PostAsync, HttpClient & Json

enter image description here

mogę skutecznie wywołać tej metody przy użyciu Skrzypek, pod warunkiem, że I włącz "Content-Type: application/json" do nagłówków żądania. Zwraca przy 200 i mogę iść do Fiddler Inspektora i wyświetlić obiekt odpowiedzi JSON dobrze:

enter image description here

Ja jednak mają problemy wywołanie tej samej metody z app MetroUI w Windows8 przy użyciu C#/XAML. Zacząłem grać z HttpClient i nowymi koncepcjami Async w języku C# i bez względu na to, jak sformatowałem wywołania Post (nawet gdy wyraźnie wołam, że chcę, aby Content-Type był "application/json") Fiddler zwraca błąd 500 i stwierdza, że ​​próba polegała na użyciu Content-Type: "text/html". Wierzę, że jest to korzeń problemu:

enter image description here

Próbowałem wszystkiego wyobrażalne, aby dodawać do tej metody i odzyskać obiekt JSON, tu jest moja najnowsza próba:

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(); 
     }); 

powoduje to błąd z 500 Content-Type ustawiony na "text/html"

Tu była kolejna próba, która również nie powiodło się:

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(); 

Czy ktoś może wskazać mi właściwy kierunek?

prostu próbowałem kodu następujące dzięki radom 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(); 

To pokazuje teraz „application/json” w moim nagłówka żądania, ale nadal pokazuje „text/html” w sesji internetowej:

enter image description here

Odpowiedz

22

Spróbuj ustawić 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(); 
+0

Dzięki Nemesv. Po prostu próbowałem tego i nadal nie jestem w stanie uzyskać błędu 500, ale zauważam, że w Fiddler Header pokazuje, że używa "application/json" - jednak sesja webowa dla rekordu pokazuje "text/html" Będę załączyć uchwyt ekranu. – CodeAbundance

+1

FYI: zobacz aktualizacje u dołu mojego pierwotnego wpisu. I dziękuję za pomoc! – CodeAbundance

+0

FYI: Myślę, że to jest sposób w jaki ustawiam parametry w nagłówku treści. Zatrzymałem kod i przeszedłem przez obiekt HttpContent po ustawieniu wartości StringContent i nie mogłem znaleźć elementów Nazwa użytkownika lub Hasło. Czy znasz lepszą metodę publikowania tego w WebAPI? Ciągle się nad tym zastanawiam ... – CodeAbundance

6

Istnieje kilka brakujących spróbuj to działa.

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; 
} 
+0

To jest lepsze, serializowanie obiektu przy pomocy JSON.Net, zamiast ręcznego budowania słownika JsonObject (który jest niepotrzebnym kodem i pękłby w momencie zmiany encji). W RTM można również użyć konstruktora StringContent do określenia typu nośnika i kodowania, np. UTF8, np. var content = new StringContent (json, Encoding.UTF8, "application/json"). –

+1

tak, dziękuję za pracę dla mnie .. – andy

Powiązane problemy