पोस्ट पैरामीटर हमेशा शून्य होता है


197

WebAPI के लिए RC में अपग्रेड करने के बाद से मैं अपने WebAPI पर POST को कॉल करते समय कुछ वास्तविक अजीब मुद्दे पर हूं। मैं भी नए प्रोजेक्ट पर उत्पन्न मूल संस्करण पर वापस चला गया हूं। इसलिए:

public void Post(string value)
{
}

और फिडलर से कॉलिंग:

Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29

Body:
{
    "value": "test"
}

जब मैं डीबग करता हूं, तो स्ट्रिंग "मान" को कभी भी असाइन नहीं किया जाता है। यह हमेशा केवल NULL है। किसी को भी इस मुद्दे को होने?

(मैंने पहली बार इस मुद्दे को अधिक जटिल प्रकार के साथ देखा)

समस्या केवल ASP.NET MVC 4 तक ही सीमित नहीं है, वही समस्या RC स्थापना के बाद एक नए ASP.NET MVC 3 प्रोजेक्ट के लिए होती है


बस समस्या में जोड़ने के लिए - यह JSON के लिए अनन्य नहीं है, यह XML के साथ भी होता है।
इयानाथबोन

3
मैं इसके साथ दो दिनों के लिए बल्लेबाजी कर रहा हूं और इसके बारे में मेरे द्वारा खोजे जा सकने वाले हर लेख को पढ़ने के बाद, यह वेबसेंपेस्ट में JSON स्ट्रिंग को सही ढंग से प्रारूपित करने के समान सरल निकला: डेटा को दोहरे उद्धरण चिह्नों के साथ शुरू और समाप्त होना चाहिए और यदि आप तब अपने json डेटा भर में एकल उद्धरण का उपयोग करें यह सब अच्छा खेलता है।
गेनर

जवाबों:


101

चूंकि आपके पास केवल एक पैरामीटर है, आप इसे [FromBody]विशेषता के साथ सजाने की कोशिश कर सकते हैं , या एक संपत्ति के रूप में मूल्य के साथ डीटीओ को स्वीकार करने के लिए विधि बदल सकते हैं, जैसा कि मैंने यहां सुझाव दिया है: एमवीसी 4 आरसी वेबएपीआई पैरामीटर बाध्यकारी

अद्यतन: आधिकारिक ASP.NET साइट को आज एक उत्कृष्ट स्पष्टीकरण के साथ अपडेट किया गया: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 1

संक्षेप में, शरीर में एक सरल प्रकार भेजते समय, समान चिह्न (=) के साथ उपसर्ग किए गए मान को भेजें, जैसे:

=test


9
मैंने [FromBody] को एक चक्कर दिया लेकिन इसमें कोई बदलाव नहीं हुआ
ianrathbone

11
बस मूल्य दर्रा (यानी नहीं एक JSON वस्तु के रूप में) है और यह काम करना चाहिए, के अनुसार blogs.msdn.com/b/jmstall/archive/2012/04/16/...
जिम हार्टे

8
=जब तक मैंने जिम की सलाह का पालन नहीं किया, तब तक मेरे सामने एपेंड ने कभी भी मेरे लिए काम नहीं किया, (JSON ऑब्जेक्ट के रूप में नहीं) और यह काम किया। यह कुंजी है! मुझे वास्तव में पसंद नहीं है कि वेबपीआई कितना अच्छा है।
gititgo

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

6
धन्यवाद! पृथ्वी पर हमें कैसे पता होना चाहिए कि केवल एक पैरामीटर भेजते समय हमें पैरामीटर नाम को हटाना होगा? इस विचार के साथ कौन सा बर्डब्रेन आया?
जेनी ओ'रिली ने

104

मैं आज इस पर अपना सिर खुजला रहा हूं।

मेरा समाधान एक को बदलने के [FromBody]लिए है HttpRequestMessage, अनिवार्य रूप से HTTP स्टैक को स्थानांतरित करना।

मेरे मामले में मैं उस तार के पार डेटा भेज रहा हूं जो ज़िप्ड ज़िप है जो बाद में बेस 64 एलआईडी है। यह सब एक android app से।

मेरे वेब एंडपॉइंट के मूल हस्ताक्षर इस तरह दिखे (उपयोग करते हुए [FromBody]):

मेरा मूल समापन

इस मुद्दे के लिए मेरा फिक्स HttpRequestMessageमेरे समापन बिंदु के हस्ताक्षर के लिए उपयोग करने के लिए वापस करना था ।

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

फिर आप इस कोड की लाइन का उपयोग करके पोस्ट डेटा तक पहुंच प्राप्त कर सकते हैं:

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

यह काम करता है और आपको कच्चे अनछुए पोस्ट डेटा तक पहुंचने की अनुमति देता है। आपको अपने स्ट्रिंगर की शुरुआत में या सामग्री-प्रकार को बदलने के लिए फ़िडलर के साथ गड़बड़ करने की ज़रूरत नहीं है।

एक तरफ के रूप में, मैंने सबसे पहले उन उत्तरों में से एक का पालन करने की कोशिश की, जो सामग्री प्रकार को बदलने के लिए था: "सामग्री-प्रकार: अनुप्रयोग / x-www-form-urlencoded"। कच्चे डेटा के लिए यह बुरी सलाह है क्योंकि यह + अक्षर को स्ट्रिप्स करता है।

तो एक बेस 64 स्ट्रिंग जो इस तरह शुरू होती है: "MQ0AAB + LCAAAAAA" इस तरह समाप्त होती है "MQ0AAB LCAAAAAA"! जो आप चाहते हैं वह नहीं।

उपयोग करने HttpRequestMessageका एक और लाभ यह है कि आप अपने समापन बिंदु के भीतर से सभी http हेडर तक पहुँच प्राप्त करते हैं।


6
उत्कृष्ट समाधान ... मुझे इसे ढूंढने में 9 घंटे लगे, मेरे मुद्दे को हटाने के बाद मैंने [FromBody] स्ट्रिंग मान को हटा दिया और इसे HttpRequestMessage
Kev

1
एक जादू की तरह काम करता है! लेकिन क्या किसी वास्तविक वस्तु के वास्तविक पैरामीटर प्रकार का उपयोग करने का कोई तरीका नहीं है? उदाहरण के लिए, वेब एपीआई विधि के लिए ऑर्डर का प्रकार?
रॉन नुनी

7
बस एक साइड नोट, आप HttpRequestMessage requestविधि हस्ताक्षर की आवश्यकता नहीं है , क्योंकि आप हमेशा यह पहले से ही है। विधि बॉडी में इसे Requestऑब्जेक्ट पर एक्सेस किया जा सकता है । जैसेRequest.Content.ReadAsStringAsync().Result;
मोरवेल

आमतौर पर यह समस्या है क्योंकि आपकी JSON ऑब्जेक्ट गलत है। मैंने पाया है कि यह हमेशा होता है क्योंकि कंस्ट्रक्टर के पास एक अमान्य प्रकार होता है और Json नहीं जानता कि इसे कैसे रूपांतरित किया जाए 'लाइक ए गाइड टू स्ट्रिंग। इसलिए या तो कनवर्टर को सेटिंग्स के माध्यम से जोड़ें या एक खाली कंस्ट्रक्टर को जोड़ें और आपको इस तरह पुराने कोड में वापस जाने की आवश्यकता नहीं है।
निक टर्नर

सबसे आसान तरीका यह है कि ऑब्जेक्ट को स्ट्रिंग पर स्विच करें और फिर कोशिश करें और इसे रूपांतरित करें और आपको JSON त्रुटि दिखाई देगी। जांचें कि आप हेडर भी हैं।
निक टर्नर

71

मैंने अभी-अभी फिडलर का उपयोग किया है। समस्या यह थी कि मैंने निर्दिष्ट नहीं किया था Content-Type

Content-Typeअपने POST अनुरोध के लिए एक शीर्ष लेख सहित प्रयास करें ।

Content-Type: application/x-www-form-urlencoded

वैकल्पिक रूप से, नीचे दी गई टिप्पणियों के अनुसार, आपको JSON हेडर शामिल करना पड़ सकता है

Content-Type: application/json

11
मुझे एक समान समस्या थी, सिवाय इसके कि मुझे कंटेंट-टाइप सेट करने की आवश्यकता थी: एप्लीकेशन / json
dvallejo

2
जैसा कि पोस्ट में निर्दिष्ट किया गया है - मैंने पहले ही कंटेंट-टाइप: एप्लीकेशन / json
ianrathbone

2
आवेदन / x-www-form-urlencoded मेरे लिए काम नहीं किया, सामग्री-प्रकार: आवेदन / json किया।
लियांग

1
सामग्री-प्रकार के बावजूद, यदि आपके पास केवल एक पैरामीटर है, तो आपको अनुरोध के शरीर में पैरामीटर नाम के बिना केवल मूल्य भेजना होगा। तो id = 13 काम नहीं करेगा। आपको अकेले 13 भेजने की आवश्यकता है। जिम का जवाब देखें।
जेनी ओ'रिली ने

मुझे इसका उपयोग करना था contentType: "application/x-www-form-urlencoded; charset=UTF-8", एक पूर्ण उदाहरण के लिए संपूर्ण Cient और Server
RyBolt

57

मैं इस समस्या में भी भाग गया हूं, और इसी तरह मैंने अपनी समस्या को हल किया है

वेबपी कोड:

public void Post([FromBody] dynamic data)
{
    string value = data.value;
    /* do stuff */
}

क्लाइंट कोड:

$.post( "webapi/address", { value: "some value" } );

1
यदि क्लाइंट JSON भेज रहा है तो यह काम करता है। अगर मैं एक साधारण मान भेज रहा हूँ जैसे कि स्ट्रिंग some value, तो dataअशक्त है।
ब्रायनस्टी

आसान, अपने ग्राहक कोड को बदलने के लिए एक जेएस वस्तु वापस भेजें।
जॉर्ज


यदि आप json भेज रहे हैं, तो var json = JsonConvert.SerializeObject (data);
दवलोजो

41

मैं उपयोग कर रहा था Postmanऔर मैं एक ही गलती कर रहा था .. valueस्ट्रिंग के बजाय जसन ऑब्जेक्ट के रूप में गुजर रहा है

{
    "value": "test"
}

स्पष्ट रूप से ऊपर वाला गलत है जब एपीआई पैरामीटर टाइप स्ट्रिंग का है।

तो, बस एपीआई बॉडी में डबल कोट्स में स्ट्रिंग पास करें:

"test"

2
यह मेरा मुद्दा था, और सवाल का वास्तविक समाधान होने की संभावना है। JSON-एन्कोडेड स्ट्रिंग में उद्धरण हैं
Kyle W

1
मैंने पोस्टमैन पर भी इस मुद्दे का सामना किया। यह पता चला है कि मैंने गलत तरीके से बॉडी के लिए "रॉ" के बजाय "फॉर्म-डेटा" चुना, जब कंटेंट-टाइप को एप्लिकेशन या जेनसन सेट किया गया। आप एस्पनेट गिथब के मुद्दों पर zzyykk123456 के स्क्रीनशॉट का उल्लेख कर सकते हैं: github.com/aspnet/Home/issues/2202
चुन लिन

इसने मेरे लिए काम किया। Swagger (swashbuckle) का उपयोग करके मुझे सामग्री प्रकार: एप्लिकेशन / json सेट करना होगा और दोहरे उद्धरण चिह्नों का उपयोग करना होगा।
जॉन हेनकेल

1
वास्तव में मेरा मुद्दा लेकिन मुझे यह ध्यान रखना है कि अजाक्स अनुरोध में आपको 'डेटा: JSON.stringify ("YourString") करना चाहिए
अमीर होसैन अहमदी

1
@AmirHosseinAhmadi मैंने अभी-अभी अजाक्स पर इसका सामना किया है और देखा कि वास्तव में उपयोग करने से JSON.stringifyमेरे होने का कारण बन रहा था । डेटा फ़ील्ड को स्ट्रिंग मान पर सेट करने के बाद (जो कि एक json स्ट्रिंग है) यह काम किया। [frombody]null
Nexaspx

19

डेटा मॉडल के रूप में सेवा करने के लिए एक वर्ग बनाने का प्रयास करें, फिर अपने डेटा मॉडल वर्ग के गुणों से मेल खाने वाले गुणों के साथ एक JSON ऑब्जेक्ट भेजें। (नोट: मैंने इसका परीक्षण किया है और यह नवीनतम MVC 4 RC 2012 के साथ काम करता है जिसे मैंने अभी डाउनलोड किया है)।

public HttpResponseMessage Post(ValueModel model)
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, "Value Recieved: " + model.Value);
}

public class ValueModel
{
    public string Value { get; set; }
}

नीचे JSON ऑब्जेक्ट HTTP-POST बॉडी में भेजा गया है, सामग्री-प्रकार अनुप्रयोग / json है

{ "value": "In MVC4 Beta you could map to simple types like string, but testing with RC 2012 I have only been able to map to DataModels and only JSON (application/json) and url-encoded (application/x-www-form-urlencoded body formats have worked. XML is not working for some reason" }

मेरा मानना ​​है कि आपको डेटा मॉडल वर्ग बनाने का कारण यह है क्योंकि सरल मानों को यूआरएल मापदंडों से माना जाता है, और एक एकल जटिल मान को शरीर से माना जाता है। उनके पास विशेषताएँ [FromBody]और [FromUrl]विशेषताएँ हैं, लेकिन फिर [FromBody] string valueभी मेरे लिए काम नहीं किया। लगता है जैसे वे अभी भी बहुत से कीड़े काम कर रहे हैं इसलिए मुझे यकीन है कि यह भविष्य में बदल जाएगा।

संपादित करें: शरीर में काम करने के लिए XML मिला। डिफ़ॉल्ट XML धारावाहिक को XmlSerializer के बजाय DataContractSerializer में बदल दिया गया था। निम्न लाइन को मेरे Global.asax फ़ाइल में डालकर इस समस्या ( संदर्भ ) को ठीक कर दिया है

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

यह मेरे लिए अनुरोध के साथ काम करता है। कांटेंट टाइप = "एप्लिकेशन / जसन; चारसेट = यूटीएफ -8";
अरविंद करमार

15

कुछ कोशिशों के बाद, मुझे लगता है कि डिफ़ॉल्ट व्यवहार सही है और हैक करने के लिए कुछ भी नहीं है।

एकमात्र चाल यह है: यदि आपकी पोस्ट विधि तर्क stringनीचे की तरह है, तो आपको शरीर में दोहरे उद्धरण के साथ एक सादा स्ट्रिंग भेजना चाहिए (जब अजाक्स या पोस्टमैन का उपयोग करते हुए), जैसे;

//send "{\"a\":1}" in body to me, note the outer double quotes
[HttpPost("api1")]
public String PostMethod1([FromBody]string value)
{
    return "received " + value; //  "received {\"a\":1}"
}

अन्यथा यदि आप बाहरी दोहरे उद्धरणों के बिना पोस्ट बॉडी में एक जॉन्स स्ट्रिंग भेजते हैं और आंतरिक उद्धरणों से बच जाते हैं, तो इसे मॉडल वर्ग (तर्क प्रकार) में पार्स करने में सक्षम होना चाहिए, उदाहरण के लिए,{"a":1, "b":2}

public class MyPoco{
    public int a;
    public int b;
}

//send {"a":1, "b":2} in body to me
[HttpPost("api2")]
public String PostMethod2([FromBody]MyPoco value)
{
    return "received " + value.ToString();  //"received your_namespace+MyPoco"
}

11

मैं अब कुछ मिनटों के लिए इस समस्या का हल ढूंढ रहा था, इसलिए मैं अपना समाधान साझा करूँगा।

यदि आप एक मॉडल पोस्ट करते हैं तो आपके मॉडल को एक खाली / डिफ़ॉल्ट निर्माणकर्ता की आवश्यकता होती है, अन्यथा मॉडल को स्पष्ट रूप से नहीं बनाया जा सकता है। रिफैक्टरिंग करते समय सावधान रहें। ;)


Refactoring वास्तव में मुझे यहाँ क्या है, टिप के लिए धन्यवाद!
एलन

10

यह मेरे लिए काम किया:

  1. प्रत्येक विशेषता के लिए एक संपत्ति के साथ एक सी # डीटीओ क्लास बनाएं, जिसे आप jQuery / Ajax से पास करना चाहते हैं

    public class EntityData
    {
        public string Attr1 { get; set; }
        public string Attr2 { get; set; }
    }
  2. वेब एपीआई विधि को परिभाषित करें:

    [HttpPost()]
    public JObject AddNewEntity([FromBody] EntityData entityData)
    {
  3. इस तरह से वेब एप को कॉल करें:

    var entityData = {
        "attr1": "value1",
        "attr2": "value2"
    };
    
    $.ajax({
        type: "POST",
        url: "/api/YOURCONTROLLER/addnewentity",
        async: true,
        cache: false,
        data: JSON.stringify(entityData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            ...
        }
    });

इसे पोस्ट करने के लिए धन्यवाद, मैंने कई नमूने आज़माए लेकिन यह मेरे लिए काम कर गया!
सतबीर

10

उन लोगों के लिए जो स्वैगर या पोस्टमैन के साथ एक ही समस्या रखते हैं जैसे मैंने किया था, यदि आप एक पोस्ट में स्ट्रिंग के रूप में एक साधारण विशेषता पास कर रहे हैं, यहां तक ​​कि "ContentType" निर्दिष्ट के साथ, आप अभी भी एक शून्य मान प्राप्त करने जा रहे हैं।

बस पासिंग:

MyValue

नियंत्रक के रूप में अशक्त हो जाएगा।

लेकिन अगर आप पास होते हैं:

"MyValue"

मान सही मिलेगा।

उद्धरणों ने यहां अंतर पैदा किया। बेशक, यह केवल स्वैगर और पोस्टमैन के लिए है। उदाहरण के लिए, कोणीय का उपयोग करने वाले एक फ्रंटेंड ऐप में इसे फ्रेमवर्क द्वारा स्वचालित रूप से हल किया जाना चाहिए।


6

मेरे पास एक ही मुद्दा था और पाया गया कि सामग्री प्रकार को "एप्लिकेशन / जसन" में बदलने से समस्या ठीक नहीं हुई। हालाँकि "एप्लिकेशन / जसन; चारसेट = utf-8" ने काम किया।


Yup, Web API charset = utf-8 के बिना डिस्क्राइब नहीं करेगा। blog.codenamed.nl/2015/05/12/…
सैम रुएबी

4

मेरे पास एक समान मुद्दा था जहां मेरे वेब एपीआई विधि के लिए अनुरोध ऑब्जेक्ट हमेशा शून्य था। मैंने देखा कि चूंकि कंट्रोलर एक्शन नाम "गेट" के साथ उपसर्ग किया गया था, इसलिए वेब एपीआई ने इसे POST के बजाय HTTP GET के रूप में माना। नियंत्रक क्रिया का नाम बदलने के बाद, यह अब इच्छित के रूप में काम करता है।


3

कोणीय के साथ, मैं इस प्रारूप में डेटा पास करने में सक्षम था:

 data: '=' + JSON.stringify({ u: $scope.usrname1, p: $scope.pwd1 }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }

और वेब एपीआई कंट्रोलर में:

    [HttpPost]
    public Hashtable Post([FromBody]string jsonString)
    {
        IDictionary<string, string> data = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonString);
        string username = data["u"];
        string pwd = data["p"];
   ......

वैकल्पिक रूप से, मैं इस तरह से JSON डेटा भी पोस्ट कर सकता हूं:

    data: { PaintingId: 1, Title: "Animal show", Price: 10.50 } 

और, नियंत्रक में, इस तरह एक वर्ग प्रकार स्वीकार करें:

    [HttpPost]
    public string POST(Models.PostModel pm)
    {

     ....
    }

किसी भी तरह से काम करता है, अगर आपके पास एपीआई में एक स्थापित सार्वजनिक वर्ग है तो JSON पोस्ट करें, अन्यथा '=' + JSON.stringify ({..: ..., ..: ...}) पोस्ट करें


3

मेरे मामले में समस्या यह थी कि पैरामीटर एक स्ट्रिंग था और एक ऑब्जेक्ट नहीं था, मैंने पैरामीटर को बदल कर Newsoft.Json का नाम दिया और यह काम करता है।


2

रेखा जोड़ना

        ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

protected void Application_Start()Global.asax.cs में फ़ंक्शन के अंत तक ASP.NET MVC3 में मेरे लिए इसी तरह की समस्या तय की गई।


मदद के लिए धन्यवाद, लेकिन दुर्भाग्य से यह मदद नहीं की। मैं वैसे भी समय के लिए लाइन रखूंगा क्योंकि यह वैसे भी मदद कर सकता है!
इयानाथबोन

एक्सएमएल
ianrathbone

2

यदि आप अपने Xml फ़ॉर्मेटर या JSON फ़ॉर्मैटर के लिए DataContractSerializer का उपयोग कर रहे हैं , तो आपको इससे छुटकारा पाने की आवश्यकता है। मेरी WebApiConfig फ़ाइल में यह था:

public static void Register(HttpConfiguration config)
{
     config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional }
     );    

     var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
     jsonFormatter.UseDataContractJsonSerializer = true;
}

बस मैं टिप्पणी करता हूं jsonFormatter.UseDataContractJsonSerializer = true; और मेरा इनपुट पैरामीटर अब शून्य नहीं है। मुझे एक सुराग देने के लिए 'डेस्परटेर' का धन्यवाद।


2

यदि आप अपने भेजे हुए JSON के बारे में सुनिश्चित हैं तो आपको अपने एपीआई को ध्यान से देखना चाहिए:

  1. इंस्टॉल Microsoft.AspNet.WebApi.Tracingपैकेज
  2. विधि के अंदर वर्ग config.EnableSystemDiagnosticsTracing();में जोड़ें ।WebApiConfigRegister

अब डिबग आउटपुट को देखें और आप संभवतः एक अमान्य पाएंगे ModelState लॉग प्रविष्टि ।

यदि ModelStateअमान्य है तो आपको इसका वास्तविक कारण मिल सकता है Errors:

कोई भी इस तरह के अपवाद का अनुमान नहीं लगा सकता है:

Could not load file or assembly 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

तुमने मेरी जान बचाई। मॉडल के रूप में अशक्त होना और पैकेज स्थापित करने के बाद, पाया गया कि मेरा JSON सही प्रारूप में नहीं है।
खिजर इकबाल

2

मेरे पास पैरामीटर के रूप में अशक्त होने का एक ही मुद्दा था, लेकिन यह बड़ी वस्तुओं से संबंधित था। यह समस्या आईआईएस अधिकतम लंबाई से संबंधित थी। इसे web.config में कॉन्फ़िगर किया जा सकता है।

  <system.web>
    <httpRuntime targetFramework="4.7" maxRequestLength="1073741824" />
  </system.web>

मुझे आश्चर्य है कि वेब एपीआई ने त्रुटि को क्यों दबाया और मेरे एपीआई को अशक्त वस्तुएं भेजता है। मुझे Microsoft.AspNet.WebApi.Tracing का उपयोग करने में त्रुटि मिली।



1

मुझे पता है कि यह इस सवाल का जवाब नहीं है, लेकिन मैं अपनी समस्या का हल खोजते समय इसके पार आया।

मेरे मामले में, जटिल प्रकार बाध्य नहीं किया जा रहा था, लेकिन मैं एक पोस्ट नहीं कर रहा था, मैं जीईआर कर रहा था, जो कि मापदंडों को सीमित कर रहा था। समाधान [FromUri] को arg में जोड़ने का था:

public class MyController : ApiController
{
    public IEnumerable<MyModel> Get([FromUri] MyComplexType input)
    {
        // input is not null as long as [FromUri] is present in the method arg
    }
}

ऐसा इसलिए है क्योंकि GET का उपयोग करते समय अनुरोध के मुख्य भाग को अनदेखा कर दिया जाता है (और कभी-कभी त्रुटि का कारण बनता है)। कारण यह है कि अब काम करता है b / c आप अब क्वेरी स्ट्रिंग पर
पैरामेट्स

1

मुझे फ़िडलर में भी यही समस्या थी। मेरे पास पहले से Content-Type: application/json; charset=utf-8या Content-Type: application/jsonअनुरोध हैडर में था।

मेरा अनुरोध शरीर भी एक सादा तार था, और फिडलर में मैंने लिखा था {'controller':'ctrl'}:। यह मेरे POST विधि में स्ट्रिंग पैरामीटर बना null

फिक्स : उद्धरण चिह्नों का उपयोग करना याद रखें, जिससे एक स्ट्रिंग का संकेत मिलता है। यानी मैंने इसे लिखकर तय किया "{'controller':'ctrl'}"। (नोट: JSON लिखते समय, या तो apostrophes का उपयोग करना सुनिश्चित करें या इस तरह उद्धरण चिह्नों से बचें:) "{\"controller\":\"ctrl\"}"


मुझे पोस्टमैन में भी यही काम करना था। जब मैं स्प्रिंग सेवाओं को कॉल करता हूं, तो मुझे ऐसा करने की आवश्यकता नहीं है। .Net की तरफ एक समस्या की तरह लगता है।
मैल्कम रॉबर्ट्स

1

सबसे सरल तरीका जो मैंने साधारण JSON वस्तु से निपटने के लिए पाया है जो कि मैं MVC 6 में पास करता हूं, न्यूटन सॉफ्ट के जैसे पोस्ट पैरामीटर का प्रकार प्राप्त कर रहा है।

public ActionResult Test2([FromBody] jObject str)
{
        return Json(new { message = "Test1 Returned: "+ str }); ;
}

टेस्ट ( [FromBody] object body, [FromHeader(Name="Content-Type")] string bodyMediaType) bodyMediaType == "application.json"जोबजेक्ट के लिए बॉडी की कास्टिंग करने से पहले बेहतर काम कर सकता है, अल्टरनेटिव्स के लिए एक अवसर प्रदान करता है।
व्लाह नोव

1

मेरे लिए सबसे अच्छा समाधान नीचे के रूप में पूर्ण HTTP जा रहा है:

[Route("api/open")]
[HttpPost]
public async Task<string> open(HttpRequestMessage request)
{
    var json = await request.Content.ReadAsStringAsync();
    JavaScriptSerializer jss = new JavaScriptSerializer();            
    WS_OpenSession param = jss.Deserialize<WS_OpenSession>(json);
    return param.sessionid;
}

और फिर स्ट्रिंग को उस वस्तु से अलग करना जो आप पोस्ट बॉडी में अपेक्षा करते हैं। मेरे लिए, WS_OpenSession एक वर्ग है जिसमें सेशन, उपयोगकर्ता और कुंजी शामिल हैं।

आप वहां से परम ऑब्जेक्ट का उपयोग कर सकते हैं और इसके गुणों तक पहुंच सकते हैं।

बहुत प्रभावी है।

मैंने कहा कि इस यूआरएल से sourced:

http://bizcoder.com/posting-raw-json-to-web-api


1

जटिल प्रकारों के लिए, वेब एपीआई मीडिया-प्रकार के फॉर्मैटर का उपयोग करके, संदेश निकाय से मान को पढ़ने की कोशिश करता है।

कृपया जांच लें कि क्या आपको कोई मिला है [Serializable] अपने मॉडल वर्ग को सजाने की विशेषता ।

यह देखने के लिए कि क्या यह काम करता है, विशेषता को हटा दें। इसने मेरे लिए काम किया।


1

मुझे पार्टी में थोड़ी देर हो गई है, लेकिन कोई भी व्यक्ति जो एक NULL मान से ठोकर खाता है, एक नियंत्रक का उपयोग करते समय बस आपके पोस्ट अनुरोध के सामने "=" जोड़ देता है।

नियंत्रक ने एक NULL मान भी पास किया जब मैंने एप्लिकेशन / json सामग्री-प्रकार का उपयोग किया। नीचे "एप्लिकेशन / x-www-form-urlencoded" सामग्री-प्रकार नोट करें। एपीआई से रिटर्न प्रकार हालांकि "एप्लिकेशन / जसन" है।

 public static string HttpPostRequest(string url, Dictionary<string, string> postParameters)
    {
        string postData = "=";

        foreach (string key in postParameters.Keys)
        {
            postData += HttpUtility.UrlEncode(key) + "="
                  + HttpUtility.UrlEncode(postParameters[key]) + ",";
        }

        HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        myHttpWebRequest.Method = "POST";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);

        myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
        myHttpWebRequest.ContentLength = data.Length;

        Stream requestStream = myHttpWebRequest.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        Stream responseStream = myHttpWebResponse.GetResponseStream();

        StreamReader myStreamReader = new StreamReader(responseStream, System.Text.Encoding.Default);

        string pageContent = myStreamReader.ReadToEnd();

        myStreamReader.Close();
        responseStream.Close();

        myHttpWebResponse.Close();

        return pageContent;
    }

1

इससे कोई फर्क नहीं पड़ता कि आप किस प्रकार का मूल्य पोस्ट करना चाहते हैं, बस इसे उद्धरण चिह्नों के भीतर संलग्न करें, इसे स्ट्रिंग के रूप में प्राप्त करने के लिए। जटिल प्रकारों के लिए नहीं।

जावास्क्रिप्ट:

    var myData = null, url = 'api/' + 'Named/' + 'NamedMethod';

    myData = 7;

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = "some sentence";

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = { name: 'person name', age: 21 };

    $http.post(url, "'" + JSON.stringify(myData) + "'")
         .then(function (response) { console.log(response.data); });

    $http.post(url, "'" + angular.toJson(myData) + "'")
         .then(function (response) { console.log(response.data); });

सी#:

    public class NamedController : ApiController
    {
        [HttpPost]
        public int NamedMethod([FromBody] string value)
        {
            return value == null ? 1 : 0;
        }
    }

1

यदि आप [FromBody] एनोटेशन डालते हैं और आपके पास अपनी विधि के लिए एक पैरामीटर के रूप में एक Dto ऑब्जेक्ट है और अभी भी डेटा प्राप्त करने में सक्षम नहीं है, तो अपने DTO के गुणों और फ़ील्ड्स को देखना प्रारंभ करें।

मुझे यही समस्या थी, जहां मेरा डीटीओ अशक्त आ रहा था। मैंने पाया कि कारण यह था कि गुणों में से एक एक ऐसी वस्तु की ओर इशारा कर रहा था जिसे क्रमबद्ध नहीं किया जा सकता है :( जिसके कारण मीडिया-फ़ॉर्मेटर डेटा को पार्स करने में विफल रहता है। इस प्रकार ऑब्जेक्ट हमेशा शून्य था। आशा है कि यह दूसरों की भी मदद करता है।


1

अपने डेटा प्रकारों की दोबारा जांच करें। डॉटनेट मॉडल बाइंडर एक फ्लोट को पूर्णांक में परिवर्तित नहीं करेगा (और मैं अन्य संबंधित अवधारणाओं को मान रहा हूं)। यह पूरे मॉडल को अस्वीकार कर दिया जाएगा।

यदि आपके पास इस तरह से json है:

{
    "shoeSize": 10.5
}

लेकिन आपका सी # मॉडल इस तरह दिखता है:

class Shoe{
    public int shoeSize;
}

मॉडल बाइंडर मॉडल को अस्वीकार कर देगा और आप अशक्त हो जाएंगे।


1

मुझे इस पर बहुत देर हो चुकी है, लेकिन इसी तरह के मुद्दे थे और यहाँ बहुत सारे जवाबों से गुजरने के एक दिन के बाद और यहाँ पृष्ठभूमि पाने के लिए मैंने एक वेब एपीआई 2 में एक या एक से अधिक मापदंडों को पास करने का सबसे आसान / हल्का समाधान ढूंढा है। इस प्रकार है:

यह मानता है कि आप वेब API कंट्रोलर / एक्शन को सही राउटिंग के साथ सेटअप करना जानते हैं, यदि इसे देखें: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-वेब-api / ट्यूटोरियल-अपने-पहले वेब-api

पहले कंट्रोलर एक्शन, इस समाधान के लिए न्यूटनसॉफ्ट.जॉन लाइब्रेरी की भी आवश्यकता है।

[HttpPost]
public string PostProcessData([FromBody]string parameters) {
    if (!String.IsNullOrEmpty(parameters)) {
        JObject json = JObject.Parse(parameters);

        // Code logic below
        // Can access params via json["paramName"].ToString();
    }
    return "";
}

ग्राहक पक्ष jQuery का उपयोग कर

var dataToSend = JSON.stringify({ param1: "value1", param2: "value2"...});
$.post('/Web_API_URI', { '': dataToSend }).done(function (data) {
     console.debug(data); // returned data from Web API
 });

मुझे जो महत्वपूर्ण मुद्दा मिला वह यह सुनिश्चित कर रहा था कि आप केवल एक ही समग्र पैरामीटर को वेब एपीआई पर वापस भेज सकते हैं और यह सुनिश्चित कर सकते हैं कि इसका कोई नाम ही नहीं है, { '': dataToSend }अन्यथा आपका मूल्य सर्वर की ओर से शून्य हो जाएगा।

इसके साथ आप JSON संरचना में वेब एपीआई के लिए एक या कई मापदंडों को भेज सकते हैं और आपको जटिल डेटा को संभालने के लिए किसी भी अतिरिक्त ऑब्जेक्ट्स सर्वर की घोषणा करने की आवश्यकता नहीं है। जोबजेक्ट आपको समय-समय पर अपने मापदंडों को बदलने की आसान स्केलेबिलिटी की अनुमति देने में पारित सभी मापदंडों पर गतिशील रूप से पुनरावृत्ति करने की अनुमति देता है। उम्मीद है कि किसी को मेरी तरह संघर्ष कर रहा था कि मदद करता है।


0

WebAPI में शरीर में एकल पैरामीटर को सही करना इस कोड को काम करता है $.post(url, { '': productId }

और इसे कार्रवाई में पकड़ रहा है [HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)

कुंजी जादू शब्द 'मूल्य' का उपयोग करना है। यह इंट, या कुछ आदिम प्रकार भी हो सकता है। कोई बात नहीं सामग्री-प्रकार या शीर्षलेख सुधार मेस यह है कि यह कोड mvc पोस्ट एक्शन में काम नहीं करता है।

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