2012-12-07 11 views
35

मैं क्लाइंट से ASP.NET MVC4 एप्लिकेशन में एक स्ट्रिंग को प्रेषित करने का प्रयास कर रहा हूं।पोस्ट स्ट्रिंग एएसपी.नेट वेब एपीआई एप्लीकेशन - रिटर्न शून्य

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:49032/api/test"); 
request.Credentials = new NetworkCredential("user", "pw"); 
request.Method = "POST"; 
string postData = "Short test..."; 
byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
request.ContentType = "application/x-www-form-urlencoded"; 
request.ContentLength = byteArray.Length; 

Stream dataStream = request.GetRequestStream(); 
dataStream.Write(byteArray, 0, byteArray.Length); 
dataStream.Close(); 

WebResponse response = request.GetResponse(); 
Console.WriteLine(((HttpWebResponse)response).StatusDescription); 
dataStream = response.GetResponseStream(); 

StreamReader reader = new StreamReader(dataStream); 
string responseFromServer = reader.ReadToEnd(); 
Console.WriteLine(responseFromServer); 
reader.Close(); 
dataStream.Close(); 
response.Close(); 
Console.ReadLine(); 

:

लेकिन मैं स्ट्रिंग (कंसोल आवेदन) संचारित करने के लिए स्ट्रिंग प्राप्त कर सकते हैं नहीं है, या तो यह रिक्त है या पोस्ट विधि नहीं पाया जा सकता है (404 त्रुटि)

क्लाइंट कोड ASP.NET वेब एपीआई नियंत्रक:

public class TestController : ApiController 
{ 
    [Authorize] 
    public String Post(byte[] value) 
    { 
     return value.Length.ToString(); 
    } 
} 

उस मामले मैं "पोस्ट" विधि कॉल करने में सक्षम हूँ में, लेकिन "मूल्य" NULL है। यदि मैं विधि हस्ताक्षर को (स्ट्रिंग मान) में बदलता हूं, तो इसे कभी नहीं कहा जाएगा।

यहां तक ​​कि "अधिकृत" सेटिंग के बिना भी "यह" एक ही अजीब व्यवहार है। -> तो उपयोगकर्ता प्रमाणीकरण के साथ इसका कोई लेना-देना नहीं है।

कोई विचार क्या मैं गलत कर रहा हूं? मैं किसी भी मदद के लिए आभारी हूं।

उत्तर

54

आप अपने वेब एपीआई नियंत्रक कार्रवाई पर कुछ [Authorize] विशेषता का इस्तेमाल किया है करने लगते हैं और मैं नहीं दिख रहा है कि यह कैसे अपने प्रश्न के लिए प्रासंगिक है।

तो, चलिए अभ्यास में आते हैं।

public class TestController : ApiController 
{ 
    public string Post([FromBody] string value) 
    { 
     return value; 
    } 
} 

और उस बात के लिए एक उपभोक्ता:

class Program 
{ 
    static void Main() 
    { 
     using (var client = new WebClient()) 
     { 
      client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; 
      var data = "=Short test..."; 
      var result = client.UploadString("http://localhost:52996/api/test", "POST", data); 
      Console.WriteLine(result); 
     } 
    } 
} 

आप निस्संदेह देखेंगे वेब एपीआई नियंत्रक के [FromBody] सजावट के साथ-साथ विशेषता के रूप में यहाँ एक एक छोटी सी वेब एपीआई नियंत्रक कैसा लग सकता है तरीका बताया गया है PO12 डेटा के = उपसर्ग क्लाइंट पक्ष ओम। अवधारणाओं को बेहतर ढंग से समझने के लिए मैं आपको how does the Web API does parameter binding पढ़ने की सलाह दूंगा।

जहां तक ​​[Authorize] विशेषता का संबंध है, इसका उपयोग आपके सर्वर पर केवल कुछ प्रमाणीकृत उपयोगकर्ताओं तक पहुंचने से बचाने के लिए किया जा सकता है। दरअसल यह बहुत स्पष्ट नहीं है कि आप यहां क्या हासिल करने की कोशिश कर रहे हैं। आपको इस तरीके से अपने प्रश्न में और स्पष्ट होना चाहिए था। क्या आप यह समझने की कोशिश कर रहे हैं कि एएसपी.नेट वेब एपीआई में पैरामीटर बाइंड कैसे काम करता है (कृपया यह आलेख पढ़ें जिसे मैंने लिंक किया है यदि यह आपका लक्ष्य है) या कुछ प्रमाणीकरण और/या प्राधिकरण करने का प्रयास कर रहे हैं?दूसरा अपने मामला है, तो आप following post है कि मैं इस विषय पर आप आरंभ करने के लिए दिलचस्प पर लिखा मिल सकती है।

और यदि सामग्री से मैंने लिंक किया है, तो आप मेरे जैसे हैं और खुद से कहें, डब्ल्यूटीएफ मैन, मुझे बस एक सर्वर साइड एंडपॉइंट पर एक स्ट्रिंग पोस्ट करना है और मुझे यह सब करने की ज़रूरत है ? बिल्कुल नहीं। फिर चेकआउट ServiceStack। वेब एपीआई के साथ तुलना करने के लिए आपके पास एक अच्छा आधार होगा। मैं नहीं पता है माइक्रोसॉफ्ट पर दोस्तों जब वेब एपीआई को डिजाइन करने के बारे में क्या सोच रहे थे, लेकिन पर आते हैं, गंभीरता से, हम अपने HTML के लिए अलग आधार नियंत्रक होना चाहिए (लगता है उस्तरा) और बाकी सामान? यह गंभीर नहीं हो सकता है।

+1

बहुत रोचक, अगर मैं आपके ग्राहक कोड का उपयोग करता हूं, तो यह काम करता है। यह var डेटा = "= ..." के साथ काम करता है; अगर मैं "=" को हटा देता हूं तो यह काम नहीं करता है। – user1011394

+1

@ user1011394, हाँ, यह एक डब्ल्यूटीएफ है! चेकआउट [सर्विसस्टैक] (http://www.servicestack.net/)। तुम ईसे प्यार करने लगो गे। –

+0

बहुत धन्यवाद डारिन। यह वास्तव में भारी है ... – user1011394

3

मैं इस कोड का उपयोग HttpRequests पोस्ट करने के लिए करता हूं।

/// <summary> 
     /// Post this message. 
     /// </summary> 
     /// <param name="url">URL of the document.</param> 
     /// <param name="bytes">The bytes.</param> 
     public T Post<T>(string url, byte[] bytes) 
    { 
     T item; 
     var request = WritePost(url, bytes); 

     using (var response = request.GetResponse() as HttpWebResponse) 
     { 
      item = DeserializeResponse<T>(response); 
      response.Close(); 
     } 

     return item; 
    } 

    /// <summary> 
    /// Writes the post. 
    /// </summary> 
    /// <param name="url">The URL.</param> 
    /// <param name="bytes">The bytes.</param> 
    /// <returns></returns> 
    private static HttpWebRequest WritePost(string url, byte[] bytes) 
    { 
     ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; 

     HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url); 
     Stream stream = null; 
     try 
     { 
      request.Headers.Clear(); 
      request.PreAuthenticate = true; 
      request.Connection = null; 
      request.Expect = null; 
      request.KeepAlive = false; 
      request.ContentLength = bytes.Length; 
      request.Timeout = -1; 
      request.Method = "POST"; 
      stream = request.GetRequestStream(); 
      stream.Write(bytes, 0, bytes.Length); 
     } 
     catch (Exception e) 
     { 
      GetErrorResponse(url, e); 
     } 
     finally 
     { 
      if (stream != null) 
      { 
       stream.Flush(); 
       stream.Close(); 
      } 
     } 
     return request; 
    } 

अपने कोड के संबंध में, यह content.Type (request.ContentType = "application/x-www-form-urlencoded";)

अद्यतन

मेरा मानना ​​है कि समस्या यह है कि आप मान प्राप्त करने के लिए कोशिश कर रहे हैं के साथ निहित है बिना प्रयास करें। जब आप पोस्ट करते हैं और स्ट्रीम के माध्यम से बाइट भेजते हैं, तो उन्हें पैरामीटर के रूप में कार्रवाई में नहीं भेजा जाएगा। आपको सर्वर पर स्ट्रीम के माध्यम से बाइट्स को पुनर्प्राप्त करने की आवश्यकता होगी।

सर्वर पर, बाइट्स को स्ट्रीम से प्राप्त करने का प्रयास करें। निम्नलिखित कोड मैं उपयोग करता हूं।

 /// <summary> Gets the body. </summary> 
    /// <returns> The body. </returns> 
    protected byte[] GetBytes() 
    { 
     byte[] bytes; 
     using (var binaryReader = new BinaryReader(Request.InputStream)) 
     { 
      bytes = binaryReader.ReadBytes(Request.ContentLength); 
     } 

     return bytes; 
    } 
+1

हाय चक, आपके उत्तर के लिए धन्यवाद। मैं इसे करने की कोशिश की। लेकिन परिणाम मेरे कोड के समान है। सर्वर की तरफ "पोस्ट" विधि निष्पादित की जाती है, लेकिन मान शून्य है। – user1011394

+1

सर्वर पक्ष पर इनपुटस्ट्रीम को पुनर्प्राप्त करने के लिए आपका सुझाव भी मेरे लिए काम नहीं करता है ... क्या हमारे पास बाइट [] की बजाय केवल एक स्ट्रिंग पुनर्प्राप्त करने के लिए कोई अन्य संभावनाएं हैं - मुझे बस इतना ही चाहिए? – user1011394

+1

मुझे यकीन नहीं है कि और क्या सुझाव देना है।उपर्युक्त कोड, वह कोड है जिसे हम प्राप्त करने का प्रयास कर रहे हैं जो आप पूरा करने का प्रयास कर रहे हैं। –

32

वेब एपीआई बहुत अच्छी तरह से काम करता है अगर आप तथ्य यह है कि आप HTTP का उपयोग कर रहे स्वीकार करते हैं। यह तब होता है जब आप नाटक करने की कोशिश करना शुरू करते हैं कि आप तार पर वस्तुओं को भेज रहे हैं कि यह गन्दा हो जाना शुरू हो जाता है।

public class TextController : ApiController 
    { 
     public HttpResponseMessage Post(HttpRequestMessage request) { 

      var someText = request.Content.ReadAsStringAsync().Result; 
      return new HttpResponseMessage() {Content = new StringContent(someText)}; 

     } 

    } 

इस नियंत्रक एक HTTP अनुरोध संभाल लेंगे, एक स्ट्रिंग पेलोड से बाहर पढ़ सकते हैं और कि स्ट्रिंग वापस लौटने।

आप HttpClient का उपयोग StringContent का एक उदाहरण पारित करके यह कॉल करने के लिए कर सकते हैं। स्ट्रिंगकंटेंट मीडिया प्रकार के रूप में डिफ़ॉल्ट रूप से टेक्स्ट/सादे का उपयोग करेगा। आप वास्तव में क्या पारित करने की कोशिश कर रहे हैं।

[Fact] 
    public void PostAString() 
    { 

     var client = new HttpClient(); 

     var content = new StringContent("Some text"); 
     var response = client.PostAsync("http://oak:9999/api/text", content).Result; 

     Assert.Equal("Some text",response.Content.ReadAsStringAsync().Result); 

    } 
+0

+1 - मुझे वेब एपीआई पसंद है। मैंने अभी हाल ही में 'HttpResponseMessage' के बारे में सीखा है और आप सामग्री-बातचीत और क्रमबद्धता को मैन्युअल रूप से छोड़कर प्रतिक्रिया कैसे बना सकते हैं। मैं सोच रहा था कि ऐसा कुछ था जो मैं अनुरोध के लिए कर सकता था। लो और देखो यहाँ है! –

+2

"इस तथ्य को स्वीकार करें कि आप HTTP का उपयोग कर रहे हैं" इसे प्यार करें। :) –

+1

यह सबसे अच्छा जवाब है, क्योंकि क्लाइंट को पोस्ट स्ट्रिंग के साथ अजीब कुछ भी करने की आवश्यकता नहीं है। – StuartQ

3

डैरल बिल्कुल उसकी प्रतिक्रिया के साथ है। जोड़ने के लिए एक बात है कि कारण है कि एक शरीर की तरह "हैलो" एक भी टोकन युक्त करने के लिए बाध्य करने का प्रयास कर रहा है।

है कि यह काफी यूआरएल रूप इनकोडिंग डेटा नहीं है।

=hello 

यह एक खाली नाम और की "हैलो" मूल्य के साथ एक एकल कुंजी मान युग्म का URL प्रपत्र एन्कोडिंग हो जाता है: जोड़ने "=" इस तरह सामने रखकर।

POST /api/sample HTTP/1.1 
Content-Type: application/json; charset=utf-8 
Host: host:8080 
Content-Length: 7 

"Hello" 

HttpClient का उपयोग करके आप यह कर सकते हैं इस प्रकार है::

HttpClient client = new HttpClient(); 
HttpResponseMessage response = await client.PostAsJsonAsync(_baseAddress + "api/json", "Hello"); 
string result = await response.Content.ReadAsStringAsync(); 
Console.WriteLine(result); 

हेनरिक

+0

यह मेरे लिए काम नहीं करता है, मेरे पैरामीटर के साथ समाप्त हो गया है। फॉर्म डेटा विधि के साथ जाना था। वास्तव में हैकी लगता है:/ –

2

वेबएपीआई लिए

हालांकि, एक बेहतर समाधान जब एक स्ट्रिंग अपलोड करने आवेदन/json उपयोग करने के लिए है , यहां उनके विशेष [FromBody] बाध्यकारी के बिना शरीर के पाठ को पुनर्प्राप्त करने के लिए कोड है।

public class YourController : ApiController 
{ 
    [HttpPost] 
    public HttpResponseMessage Post() 
    { 
     string bodyText = this.Request.Content.ReadAsStringAsync().Result; 
     //more code here... 
    } 
} 
2

मैं इस समस्या को पूरा करता हूं, और यह आलेख ढूंढता हूं। http://www.jasonwatmore.com/post/2014/04/18/Post-a-simple-string-value-from-AngularJS-to-NET-Web-API.aspx

समाधान मैंने पाया बस अपने js में डबल उद्धरण में स्ट्रिंग मान रैप करने के लिए था पोस्ट एक आकर्षण की तरह

काम करता है! एफवाईआई

+1

यह मेरे लिए काम करता है, लेकिन "क्यों" के लिए लेख पर शीर्ष टिप्पणी की जांच करें। संक्षेप में, यदि आप AngularJS का उपयोग कर रहे हैं तो 'JSON.stringify (value) 'बेहतर है। – Chris

संबंधित मुद्दे