2012-02-04 14 views
172

Oto kod używam:Jak wysłać JSON na serwer?

// create a request 
HttpWebRequest request = (HttpWebRequest) 
WebRequest.Create(url); request.KeepAlive = false; 
request.ProtocolVersion = HttpVersion.Version10; 
request.Method = "POST"; 


// turn our request string into a byte stream 
byte[] postBytes = Encoding.UTF8.GetBytes(json); 

// this is important - make sure you specify type this way 
request.ContentType = "application/json; charset=UTF-8"; 
request.Accept = "application/json"; 
request.ContentLength = postBytes.Length; 
request.CookieContainer = Cookies; 
request.UserAgent = currentUserAgent; 
Stream requestStream = request.GetRequestStream(); 

// now send it 
requestStream.Write(postBytes, 0, postBytes.Length); 
requestStream.Close(); 

// grab te response and print it out to the console along with the status code 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
string result; 
using (StreamReader rdr = new StreamReader(response.GetResponseStream())) 
{ 
    result = rdr.ReadToEnd(); 
} 

return result; 

Kiedy biegnę to, ja zawsze się 500 wewnętrzny błąd serwera.

Co robię źle?

+1

Najpierw upewnij się, że dane, które publikujesz, są tym, czego oczekuje serwer. –

+0

w rzeczywistości wygląda na to, że publikuję nieprawidłowe dane ... –

+0

Dla ułatwienia pracy możesz dodać bibliotekę [json] (http://www.json.net) do swojego studia wizualnego. –

Odpowiedz

262

Sposób, w jaki to zrobić i działa to:

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url"); 
httpWebRequest.ContentType = "application/json"; 
httpWebRequest.Method = "POST"; 

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) 
{ 
    string json = "{\"user\":\"test\"," + 
        "\"password\":\"bla\"}"; 

    streamWriter.Write(json); 
    streamWriter.Flush(); 
    streamWriter.Close(); 
} 

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) 
{ 
    var result = streamReader.ReadToEnd(); 
} 

pisałem bibliotekę wykonać to zadanie w prostszy sposób, to jest tutaj: https://github.com/ademargomes/JsonRequest

Nadzieję, że to pomaga.

+3

Myślę, że linia ciągów json powinna be: string json = "{\" user \ ": \" test \ "," + "\" password \ ": \" bla \ "}"; Wygląda na to, że brakuje ci \ –

+2

Zawsze używaj "application/json" (chyba, że ​​z jakiegoś innego powodu potrzebny jest tekst/json na przykład: http://www.entwicklungsgedanken.de/2008/06/06/problems-with -internet-explorer-and-applicationjson /). Creding idzie do: http://stackoverflow.com/questions/477816/what-is-the-correct-json-content-type. – Yaniv

+24

Myślałem, że streamWriter.Flush(); i streamWriter.Close(); nie jest konieczne, ponieważ znajdujesz się w bloku używanym. Pod koniec użycia bloku, program piszący strumień zostanie zamknięty. – Ruchira

109

Rozwiązanie Ademara można poprawić, stosując metodę Serialize, aby zapewnić niejawną konwersję obiektu na JSON.

Dodatkowo możliwe jest wykorzystanie domyślnej funkcji oświadczenia using w celu pominięcia jawnego wywoływania Flush i Close.

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url"); 
httpWebRequest.ContentType = "application/json"; 
httpWebRequest.Method = "POST"; 

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) 
{ 
    string json = new JavaScriptSerializer().Serialize(new 
       { 
        user = "Foo", 
        password = "Baz" 
       }); 

    streamWriter.Write(json); 
} 

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) 
{ 
    var result = streamReader.ReadToEnd(); 
} 
+0

Jaka jest różnica między tym a powyższym kodem, czy czegoś brakuje? – JMK

+8

Ta metoda Serialize JavaScriptSerializer służy do tworzenia prawidłowego JSON zamiast ręcznego tworzenia. –

+0

Zobacz odpowiedź Jean F poniżej - powinien być komentarzem. Uważaj, aby treść typu 'application/json' była poprawna. – Lucas

10

Jeśli trzeba zadzwonić jest asynchronicznie następnie użyć

var request = HttpWebRequest.Create("http://www.maplegraphservices.com/tokkri/webservices/updateProfile.php?oldEmailID=" + App.currentUser.email) as HttpWebRequest; 
      request.Method = "POST"; 
      request.ContentType = "text/json"; 
      request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request); 

private void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
     // End the stream request operation 

     Stream postStream = request.EndGetRequestStream(asynchronousResult); 


     // Create the post data 
     string postData = JsonConvert.SerializeObject(edit).ToString(); 

     byte[] byteArray = Encoding.UTF8.GetBytes(postData); 


     postStream.Write(byteArray, 0, byteArray.Length); 
     postStream.Close(); 

     //Start the web request 
     request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request); 
    } 

    void GetResponceStreamCallback(IAsyncResult callbackResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState; 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult); 
     using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream())) 
     { 
      string result = httpWebStreamReader.ReadToEnd(); 
      stat.Text = result; 
     } 

    } 
+2

Dziękujemy za opublikowanie tego rozwiązania Vivek. W naszym scenariuszu wypróbowaliśmy inne rozwiązanie w tym poście i zakończyliśmy obserwowanie wyjątków System.Threading w naszej aplikacji, z powodu tego, co zakładam, że synchroniczne posty blokują wątki. Twój kod rozwiązał nasz problem. –

26

dalszego słupka Seana, nie jest konieczne, aby zagnieździć się przy użyciu instrukcji. Przez using na StreamWriter będzie zaczerwieniona i zamknięta na końcu bloku, więc nie trzeba jawnie wywołać Flush() i Close() metody:

var request = (HttpWebRequest)WebRequest.Create("http://url"); 
request.ContentType = "application/json"; 
request.Method = "POST"; 

using (var streamWriter = new StreamWriter(request.GetRequestStream())) 
{ 
    string json = new JavaScriptSerializer().Serialize(new 
       { 
        user = "Foo", 
        password = "Baz" 
       }); 

    streamWriter.Write(json); 
} 

var response = (HttpWebResponse)request.GetResponse(); 
using (var streamReader = new StreamReader(response.GetResponseStream())) 
{ 
     var result = streamReader.ReadToEnd(); 
} 
4

This option nie wspomina:

using (var client = new HttpClient()) 
{ 
    client.BaseAddress = new Uri("http://localhost:9000/"); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

    var foo = new User 
    { 
     user = "Foo", 
     password = "Baz" 
    } 

    await client.PostAsJsonAsync("users/add", foo); 
} 
+1

Ta opcja nie jest już dostępna od .Net 4.5.2. zobacz tutaj http://stackoverflow.com/a/40525794/2161568 –

4

Niedawno wpadł znacznie prostszy sposób, aby umieścić JSON, z dodatkowym etapem konwersji z modelu w moim app. Zauważ, że musisz wykonać model [JsonObject] dla kontrolera, aby uzyskać wartości i wykonać konwersję.

Zapytanie:

var model = new MyModel(); 

using (var client = new HttpClient()) 
{ 
    var uri = new Uri("XXXXXXXXX"); 
    var json = new JavaScriptSerializer().Serialize(model); 
    var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); 
    var response = await Client.PutAsync(uri,stringContent).Result; 
    ... 
    ... 
    } 

Model:

[JsonObject] 
[Serializable] 
public class MyModel 
{ 
    public Decimal Value { get; set; } 
    public string Project { get; set; } 
    public string FilePath { get; set; } 
    public string FileName { get; set; } 
} 

strona serwera:

[HttpPut]  
public async Task<HttpResponseMessage> PutApi([FromBody]MyModel model) 
{ 
    ... 
    ... 
} 
1

var data = Encoding.ASCII.GetBytes(json);

byte[] postBytes = Encoding.UTF8.GetBytes(json);

Zastosowanie ASCII zamiast UFT8

+0

brzmi jak bardzo zły pomysł, czy czegoś brakuje? – CyberFox

2

Niektóre różne i czyste sposobem osiągnięcia tego celu jest za pomocą HttpClient tak:

public async Task<HttpResponseMessage> PostResult(string url, ResultObject resultObject) 
{ 
    using (var client = new HttpClient()) 
    { 
     HttpResponseMessage response = new HttpResponseMessage(); 
     try 
     { 
      response = await client.PostAsJsonAsync(url, resultObject); 
     } 
     catch (Exception ex) 
     { 
      throw ex 
     } 
     return response; 
    } 
} 
+2

Przydatne, jednak 'PostAsJsonAsync' nie jest już dostępna od .NET 4.5.2. Zamiast tego użyj 'PostAsync'. Więcej [tutaj] (https://stackoverflow.com/a/34594919/4461141) –

0

końcu powołać w trybie synchronizacji poprzez uwzględnienie .Result

HttpResponseMessage response = null; 
try 
{ 
    using (var client = new HttpClient()) 
    { 
     response = client.PostAsync(
     "http://localhost:8000/....", 
     new StringContent(myJson,Encoding.UTF8,"application/json")).Result; 
    if (response.IsSuccessStatusCode) 
     { 
      MessageBox.Show("OK");    
     } 
     else 
     { 
      MessageBox.Show("NOK"); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    MessageBox.Show("ERROR"); 
} 
Powiązane problemy