POSTING JSON na adres URL przez WebClient w C #

87

Mam kod JavaScript, który muszę przekonwertować na C #. Mój kod JavaScript wysyła kod JSON do utworzonej usługi internetowej. Ten kod JavaScript działa dobrze i wygląda następująco:

var vm = { k: "1", a: "2", c: "3", v: "4" };
$.ajax({
  url: "http://www.mysite.com/1.0/service/action",
  type: "POST",
  data: JSON.stringify(vm),
  contentType: "application/json;charset=utf-8",
  success: action_Succeeded,
  error: action_Failed
});

function action_Succeeded(r) {
  console.log(r);
}

function log_Failed(r1, r2, r3) {
  alert("fail");
}

Próbuję dowiedzieć się, jak przekonwertować to na C #. Moja aplikacja korzysta z platformy .NET 2.0. Z tego, co wiem, muszę zrobić coś takiego:

using (WebClient client = new WebClient())
{
  string json = "?";
  client.UploadString("http://www.mysite.com/1.0/service/action", json);
}

Trochę utknąłem w tym momencie. Nie jestem pewien, jak jsonpowinno wyglądać. Nie jestem pewien, czy muszę ustawić typ zawartości. Jeśli tak, nie wiem, jak to zrobić. Widziałem też UploadData. Nie jestem więc pewien, czy używam właściwej metody. W pewnym sensie moim problemem jest serializacja moich danych.

Czy ktoś może mi powiedzieć, czego tu brakuje?

Dziękuję Ci!

Eels Fan
źródło

Odpowiedzi:

70

Potrzebujesz serializatora json, aby przeanalizować zawartość, prawdopodobnie już ją masz, jako pierwsze pytanie, jak złożyć żądanie, może to być pomysł:

var baseAddress = "http://www.example.com/1.0/service/action";

var http = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
http.Accept = "application/json";
http.ContentType = "application/json";
http.Method = "POST";

string parsedContent = <<PUT HERE YOUR JSON PARSED CONTENT>>;
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(parsedContent);

Stream newStream = http.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();

var response = http.GetResponse();

var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();

mam nadzieję, że to pomoże,

Jorge Alvarado
źródło
1
jak powinno wyglądać „parsedContent”? Niestety w tym scenariuszu muszę ręcznie utworzyć mój kod JSON. Dziękuję Ci.
Eels Fan
Czy może po prostu wyglądać jak JSON? Czy też muszę wykonać jakieś specjalne kodowanie, do czego zmierzam.
Eels Fan
@EelsFan zwykle nie stanowi problemu z wyborem dowolnego parsera JSON, zawsze możesz JSON.Net do parsowania obiektu .net do JSON, ale z mojego doświadczenia wynika, że ​​niektóre usługi w chmurze miały inną wersję parsera JSON i musiałem zrobić kilka poprawki. Czy to, co jest najlepsze dla Twojego scenariusza, ta dyskusja może pomóc też zobaczyć jakieś problemy bez oprogramowanie Json.NET stackoverflow.com/questions/9573119/...
Jorge Alvarado
5
Dlaczego używasz ASCIIEncoding, a nie UTF8? Zobacz stackoverflow.com/a/9254967/109392 .
awe
2
+1 Najpierw próbowałem używać czegoś podobnego do OP WebClienti nie udało mi się to. Potem wypróbowałem to rozwiązanie i zadziałało jak urok. Używałem UTF8Encodingzamiast ASCIIEncodingstworzyć tablicę bajtów, dlatego nie widzę powodu, aby używać ASCII, co zmniejsza dostępne znaki w sposób, który jest nie do zaakceptowania. ASCII ma tylko 127 znaków w zestawie znaków.
awe
197

Na to pytanie już udzielono odpowiedzi, ale myślę, że znalazłem rozwiązanie, które jest prostsze i bardziej odpowiednie do tytułu pytania, oto jest:

var cli = new WebClient();
cli.Headers[HttpRequestHeader.ContentType] = "application/json";
string response = cli.UploadString("http://some/address", "{some:\"json data\"}");
sarh
źródło
1
I aby twój json był „czytelny”: (w vb.net) Dim json = <JSON> {"field1": "value1", "status": "pending", "objField": {"field2": true} } </JSON> .ToString
foxontherock
Ale co z wstawianiem parametrów do tego ciągu JSON?
Tali B.
74

Poniższy przykład ilustruje sposób POST a JSON za pośrednictwem metody WebClient.UploadString :

var vm = new { k = "1", a = "2", c = "3", v=  "4" };
using (var client = new WebClient())
{
   var dataString = JsonConvert.SerializeObject(vm);
   client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
   client.UploadString(new Uri("http://www.contoso.com/1.0/service/action"), "POST", dataString);
}

Wymagania wstępne: biblioteka Json.NET

Vadim Gremyachev
źródło
4
Myślę, że powinno to być UploadStringAsync, jeśli używasz ukończonego zdarzenia.
Sam Mackrill
Możesz pominąć POSTargument, ponieważ UploadStringniejawnie używa tej metody jako domyślnej. Ponadto możesz chcieć dodać, client.Headers.Add(HttpRequestHeader.Accept, "application/json");jeśli spodziewasz się JSONzwrotu.
jimasun
Czy WebClient faktycznie implementuje IDisposable? Pracuję w .NET Framework 4.7.1 kilka lat później i nie widzę tego.
bulgotanie
2
@bubbleking Kliknąłem F12 na WebClient i zobaczyłem, że jest to komponent i komponent implementuje IDisposablepublic class WebClient : Component public class Component : MarshalByRefObject, IComponent, IDisposable
Lars Persson