Cómo publicar JSON en el servidor?

Aquí está el código que estoy usando:

// 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; 

Cuando estoy ejecutando esto, siempre obtengo un error interno de 500 servidores.

¿Qué estoy haciendo mal?

La forma en que lo hago y estoy trabajando es:

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

Escribí una biblioteca para realizar esta tarea de una manera más simple, está aquí: https://github.com/ademargomes/JsonRequest

Espero eso ayude.

La solución de Ademar se puede mejorar aprovechando el método Serialize JavaScriptSerializer para proporcionar una conversión implícita del objeto a JSON.

Además, es posible aprovechar la funcionalidad predeterminada de la instrucción using para omitir el llamado explícito de Flush and 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(); } 

Además de la publicación de Sean, no es necesario anidar las declaraciones de uso. Al using StreamWriter, se purgará y se cerrará al final del bloque, por lo que no es necesario llamar explícitamente a los métodos Flush() y Close() :

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

Cuide el tipo de contenido que está usando:

 application/json 

Fuentes:

RFC4627

Otra publicación

Si necesita llamar de forma asíncrona, utilice

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

Hace poco se me ocurrió una forma mucho más sencilla de publicar un JSON, con el paso adicional de convertir un modelo en mi aplicación. Tenga en cuenta que debe crear el modelo [JsonObject] para que su controlador obtenga los valores y realice la conversión.

Solicitud:

  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; ... ... } 

Modelo:

 [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; } } 

Lado del servidor:

 [HttpPut] public async Task PutApi([FromBody]MyModel model) { ... ... } 

El tipo HttpClient es una implementación más nueva que el WebClient y HttpWebRequest .

Simplemente puede usar las siguientes líneas.

 string myJson = "{'Username': 'myusername','Password':'pass'}"; using (var client = new HttpClient()) { var response = await client.PostAsync( "http://yourUrl", new StringContent(myJson, Encoding.UTF8, "application/json")); } 

enter image description here

Cuando necesite su HttpClient más de una vez, se recomienda crear solo una instancia y reutilizarla o utilizar la nueva HttpClientFactory.

Esta opción no se menciona:

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

Una forma diferente y limpia de lograr esto es mediante el uso de HttpClient de esta manera:

 public async Task 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; } } 

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

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

Use ASCII en lugar de UFT8

Finalmente invoqué en modo sincronización incluyendo el .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"); }