JSON को C # का उपयोग करके सर्वर पर कैसे पोस्ट करें?


269

यहां वह कोड है जो मैं उपयोग कर रहा हूं:

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

जब मैं इसे चला रहा हूं, तो मुझे हमेशा 500 आंतरिक सर्वर त्रुटि मिल रही है।

मैं क्या गलत कर रहा हूं?


1
सबसे पहले, सुनिश्चित करें कि आपके द्वारा पोस्ट किया जाने वाला डेटा वह है जो सर्वर को उम्मीद है।
LB

वास्तव में, ऐसा लगता है कि मैं अमान्य डेटा पोस्ट कर रहा था ...
Arsen Zahray

काम में आसानी के लिए आप अपने विजुअल स्टूडियो में भी json लाइब्रेरी जोड़ सकते हैं
Alireza Tabatabaeian

@ एर्सन - सर्वर विकृत डेटा के साथ क्रैश नहीं होना चाहिए। बग रिपोर्ट दर्ज करें।
jww

जवाबों:


396

जिस तरह से मैं यह कर रहा हूँ और काम कर रहा है:

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

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

मैंने इस कार्य को सरल तरीके से करने के लिए एक पुस्तकालय लिखा है, यह यहाँ है: https://github.com/ademargomes/JrRequest

आशा करता हूँ की ये काम करेगा।


3
मुझे लगता है कि json string line होनी चाहिए: string json = "{\" user \ ": \" test \ "," + "\" password \ ": \" bla \ "}; ऐसा लगता है कि आप
ड्रीम लेन

3
हमेशा "एप्लिकेशन / json" का उपयोग करें (जब तक कि किसी अन्य कारण से पाठ / json की आवश्यकता न हो उदाहरण के लिए: entwicklungsgedanken.de/2008/06/06/… )। श्रेय जाता है: stackoverflow.com/questions/477816/…
यानिव

34
मैंने सोचा होगा कि स्ट्रीमराइटर.फ्लश (); और streamWriter.Close (); आवश्यक नहीं है क्योंकि आप एक ब्लॉकिंग ब्लॉक के अंदर हैं। उपयोग करने वाले ब्लॉक के अंत में, स्ट्रीम लेखक वैसे भी बंद हो जाएगा।
रुचिरा

1
मैन्युअल रूप से JSON का निर्माण न करें। यह गलतियाँ करना आसान है जो JSON इंजेक्शन के लिए अनुमति देता है।
फ्लोरियन विंटर

5
@ user3772108 देखें stackoverflow.com/a/16380064/2279059 । एक JSON लाइब्रेरी का उपयोग करें, जैसे कि Newtonsoft JSON.Net, और किसी ऑब्जेक्ट से JSON स्ट्रिंग रेंडर करें, या क्रमांकन का उपयोग करें। मैं समझता हूं कि यह सरलता के लिए यहां छोड़ दिया गया था (हालांकि सादगी लाभ कम से कम है), लेकिन संरचित डेटा स्ट्रिंग्स (JSON, XML, ...) को प्रारूपण करना बहुत खतरनाक है, यहां तक ​​कि तुच्छ परिदृश्यों में भी ऐसा करना और लोगों को इस तरह के कोड को कॉपी करने के लिए प्रोत्साहित करना ।
फ्लोरियन विंटर

149

Ademar के समाधान का लाभ उठाकर सुधार किया जा सकता JavaScriptSerializerहै Serializeविधि JSON करने के लिए वस्तु की अंतर्निहित रूपांतरण प्रदान करने के लिए।

इसके अतिरिक्त, usingस्पष्ट रूप से कॉल करने Flushऔर छोड़ने के लिए स्टेटमेंट की डिफ़ॉल्ट कार्यक्षमता का लाभ उठाना संभव है 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();
}

1
इस और उपरोक्त कोड में क्या अंतर है, क्या मुझे कुछ याद आ रहा है?
JMK

16
यह जावास्क्रिप्ट का उपयोग करता है सीरियलाइज़ विधि हाथ से क्राफ्टिंग के बजाय वैध JSON बनाने के लिए।
सीन एंडरसन

नीचे जीन एफ का जवाब देखें - एक टिप्पणी होनी चाहिए। सामग्री प्रकार application/jsonसही है इसका ध्यान रखें।
लुकास

@ सीनियनसन मेरे पास "दूरस्थ सर्वर से कनेक्ट करने में असमर्थ" त्रुटि है।
राल्फगैब

3
@LuzanBaral आपको सिर्फ एक विधानसभा की आवश्यकता है: System.Web.Extensions
नॉर्बैक्ट

60

HttpClientप्रकार की तुलना में एक नए कार्यान्वयन है WebClientऔर HttpWebRequest

आप बस निम्नलिखित पंक्तियों का उपयोग कर सकते हैं।

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

यहां छवि विवरण दर्ज करें

जब आपको HttpClientएक से अधिक बार आवश्यकता हो, तो यह केवल एक उदाहरण बनाने और इसे पुन: उपयोग करने या नए का उपयोग करने के लिए अनुशंसित है HttpClientFactory


5
HttpClient पर थोड़ा ध्यान दें, आम सहमति यह है कि आपको इसे निपटाना नहीं चाहिए। यहां तक ​​कि यह वस्तु को थ्रेडिसेप्‍लीफाई करता है, थ्रेड-सेफ है और इसका पुन: उपयोग किया जाना है। stackoverflow.com/questions/15705092/…
जीन एफ।

1
@JeanF। हे इनपुट के लिए धन्यवाद। जैसा कि मैंने पहले ही उल्लेख किया है कि आपको केवल एक उदाहरण बनाना चाहिए या इसका उपयोग करना चाहिए HttpClientFactory। मैंने लिंक किए गए अंक में सभी उत्तर नहीं पढ़े, लेकिन मुझे लगता है कि इसे अपडेट करने की आवश्यकता है क्योंकि यह कारखाने का उल्लेख नहीं करता है।
NtFreX

33

शॉन के पोस्ट के आगे, यह कथन का उपयोग करने के लिए आवश्यक नहीं है। usingStreamWriter द्वारा इसे फ्लश किया जाएगा और ब्लॉक के अंत में बंद कर दिया जाएगा, ताकि स्पष्ट रूप से Flush()और 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();
}

1
अब यह उत्तर और सीन एंडरसन का उत्तर बिल्कुल वैसा ही है, जैसा कि सीन ने अपने पोस्ट को संपादित किया है।
फ़ैज़ा

अरे यह तो बहुत अच्छा है। धन्यवाद। लेकिन अगर हमारे पास हमारे बच्चे पर बाल नोड्स हैं तो हम डेटा कैसे पारित करेंगे?
user2728409

1
धारावाहिक बनाने वाला बाल नोड्स को जसन में संभाल सकता है - आपको बस इसे एक वैध जसन ऑब्जेक्ट प्रदान करना होगा।
डेविड क्लार्क

14

यदि आपको कॉल करने की आवश्यकता है तो एसिंक्रोनस रूप से उपयोग करें

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

    }

3
इस समाधान को पोस्ट करने के लिए धन्यवाद विवेक। हमारे परिदृश्य में हमने इस पोस्ट में एक और समाधान की कोशिश की, और सिस्टम को देखकर घाव हो गया। हमारे आवेदन में अपवादों के कारण, जो मुझे लगता है कि थ्रेड्स को अवरुद्ध करने वाले तुल्यकालिक पद थे। आपके कोड ने हमारी समस्या हल कर दी।
केन पामर

ध्यान दें कि संभवतः आपको बाइट में परिवर्तित नहीं होना है। आपको ऐसा करने में सक्षम होना चाहिए postStream.Write(postData);- और एपीआई के आधार पर request.ContentType = "application/json";इसके बजाय उपयोग करना पड़ सकता है text/json
vapcguy


11

मैं हाल ही में एक JSON पोस्ट करने के लिए बहुत सरल तरीके से आया था, मेरे ऐप में एक मॉडल से परिवर्तित करने का अतिरिक्त चरण। ध्यान दें कि मूल्यों को प्राप्त करने और रूपांतरण करने के लिए आपको अपने नियंत्रक के लिए मॉडल [JsonObject] बनाना होगा।

निवेदन:

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

नमूना:

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

सर्वर साइड:

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

6

इस विकल्प का उल्लेख नहीं किया गया है:

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

2
.Net 4.5.2 के बाद से यह विकल्प उपलब्ध नहीं है। यहाँ देख stackoverflow.com/a/40525794/2161568
Downhillski

उपरोक्त टिप्पणी के अनुसार डाउनवोट - चूंकि यह उपलब्ध नहीं है, संभवतः उत्तर को हटा देना चाहिए।
नोवाडेव जूल 3'18

1
Thats इस जवाब को कम करने का एक अच्छा कारण नहीं है क्योंकि हर कोई .net के नवीनतम संस्करणों का उपयोग नहीं करता है और इसलिए यह एक मान्य उत्तर है।
एलिसन

4

इसे प्राप्त करने के लिए कुछ अलग और साफ तरीका इस तरह HttpClient का उपयोग करके है:

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

4
मददगार, हालाँकि PostAsJsonAsync.NET 4.5.2 के बाद से उपलब्ध नहीं है। PostAsyncइसके बजाय उपयोग करें । यहाँ
Zachary Keener

HttpClient आमतौर पर usingइस तरह के एक बयान में इस्तेमाल नहीं किया जाना चाहिए
p3tch

मुझे लगता है कि यह IDisposableएक कारण के लिए इंटरफ़ेस को लागू करता है
डिम डारोन

4

चेतावनी! इस विषय पर मेरा बहुत मजबूत दृष्टिकोण है।

.NET के मौजूदा वेब क्लाइंट डेवलपर के अनुकूल नहीं हैं! WebRequest & WebClient "एक डेवलपर को निराश कैसे करें" के प्रमुख उदाहरण हैं। वे क्रियात्मक और जटिल हैं जिनके साथ काम करना है; जब आप सब करना चाहते हैं तो C # में एक सरल पोस्ट अनुरोध है। HttpClient इन मुद्दों को संबोधित करने में किसी तरह जाता है, लेकिन यह अभी भी कम है। शीर्ष पर Microsoft का दस्तावेज़ खराब है ... वास्तव में बुरा है; जब तक आप पृष्ठों और तकनीकी ब्लर के पृष्ठों के माध्यम से झारना नहीं चाहते।

बचाव के लिए खुला-स्रोत। विकल्प के रूप में तीन उत्कृष्ट ओपन-सोर्स, फ्री नूगेट लाइब्रेरी हैं। राम - राम! इन सभी को अच्छी तरह से समर्थित, प्रलेखित और हां, आसान - सुधार ... सुपर आसान - के साथ काम करना है।

  • ServiceStack.Text - तेज, हल्का और लचीला।
  • RestSharp - सरल रीस्ट और HTTP एपीआई क्लाइंट
  • Flurl - एक धाराप्रवाह, पोर्टेबल, परीक्षण योग्य HTTP क्लाइंट लाइब्रेरी

वहाँ उन दोनों के बीच ज्यादा नहीं है, लेकिन मैं ServiceStack.Text मामूली बढ़त दे देंगे ...

  • गिथुब सितारे लगभग समान हैं।
  • खुले मुद्दे और महत्वपूर्ण बात यह है कि किसी भी मुद्दे को कितनी जल्दी बंद कर दिया? ServiceStack सबसे तेज़ समस्या समाधान और खुले मुद्दों के लिए यहां पुरस्कार लेता है।
  • प्रलेखन? सभी के पास महान दस्तावेज हैं; हालाँकि, ServiceStack इसे अगले स्तर पर ले जाता है और प्रलेखन के लिए इसे 'गोल्डन स्टैंडर्ड' के लिए जाना जाता है।

ठीक है - तो JSON में एक पोस्ट अनुरोध ServiceStack.Text के भीतर कैसा दिखता है?

var response = "http://example.org/login"
    .PostJsonToUrl(new Login { Username="admin", Password="mypassword" });

यह कोड की एक पंक्ति है। संक्षिप्त और आसान! .NET के Http लाइब्रेरी में ऊपर की तुलना करें।


3

मैं अंत में .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");
}

1

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

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

UFT8 के बजाय ASCII का उपयोग करें


2
बहुत बुरा विचार लगता है, क्या मुझे कुछ याद आ रहा है?
साइबरफॉक्स

JSON में UTF8 वर्ण हो सकते हैं, यह एक भयानक विचार की तरह लगता है।
एड्रियन स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.