2011-12-14 12 views
16

मैं ऐसी समस्या को डीबग करने का प्रयास कर रहा हूं जहां रेल JSON पोस्ट डेटा को डीकोड नहीं कर रहा है।रेल JSON अनुरोध पोस्ट पैरामीटर में सही ढंग से पार्स नहीं किया गया है

सर्वर लॉग दिखाने:

2011-12-14T06:44:44+00:00 app[web.2]: Started POST 
2011-12-14T06:44:44+00:00 app[web.2]: Processing by PostsController#create as */* 
2011-12-14T06:44:44+00:00 app[web.2]: Parameters: {"{\"athlete_id\":\"\",\"known_as\":\"abc\",\"email\":\"[email protected]\",\"result\":\"112233\",\"rx\":false,\"mods\":\"thkjth\",\"notes\":\"\"}"=>nil, "affiliate_id"=>"testaffiliate", "wod_id"=>"12345"} 

ध्यान दें कि JSON स्ट्रिंग पार्स नहीं किया जा रहा है - रेल, हैश में एक महत्वपूर्ण के रूप में यह बताए है एक नहीं के बराबर मूल्य की ओर इशारा करते। क्या इससे पहले कि मैं पहले_फिल्टर लिखने से पहले किसी के पास कोई विचार है जो JSON.parse सभी पैराम्स कुंजी की कोशिश करता है?

मुझे नहीं लगता कि यह प्रासंगिक है क्योंकि मैं डेटा भेज रहा हूं और प्राप्त कर रहा हूं, लेकिन यह समस्या आईई से एक कोर अनुरोध के दौरान होती है (XDomainRequest का उपयोग करके)।

उत्तर

9
before_filter :fix_ie_params, only: [:create, :update] 

पतला लिए:

def fix_ie_params 
    if request.format == '*/*' 
    # try to JSON decode in case of IE XDR 
    begin 

     params.merge! ActiveSupport::JSON.decode(request.body.string) 

    rescue Exception=>e 
     # todo: log exception 
    end 
    end 
end 

लिए यूनिकॉर्न और Phusion यात्री:

def fix_ie_params 
    if request.format == '*/*' 
    # try to JSON decode in case of IE XDR 
    begin 

     request.body.rewind 
     params.merge! ActiveSupport::JSON.decode(request.body.read) 

    rescue Exception=>e 
     # todo: log exception 
    end 
    end 
end 
+0

मैंने पाया कि यह (यूनिकॉर्न पर) मैं अनुरोध के शरीर को एक कुंजी के रूप में पैराम में शामिल करता हूं: '{'theBodyOfRequest' => nil,: controller => उपयोगकर्ता,: action => 'update'} 'के आधार पर आपके उपयोग के मामले में यह समस्याएं पैदा कर सकता है। चूंकि यह पहला पैरामीटर है, इसलिए मैंने इसे हटाने के लिए 'params.shift' जोड़ा। – Peter

+0

@ कॉलिन, हाँ - मैं जिस डेटा को पोस्ट कर रहा था वह मूल रूप से JSON '{: foo =>" bar "}' (जिसे भेजने के लिए स्ट्रिंग किया गया था) था ताकि नियंत्रक पर पैराम जैसा दिख सके: '{" {\ "foo \" => \ "बार \"} => शून्य, "नियंत्रक" => "उपयोगकर्ता" ...} ' – Peter

+0

@ पीटर, जो कि प्रश्न में वर्णित मूल समस्या की तरह लगता है, है ना? क्या आप निश्चित हैं कि आपका फ़िल्टर चलाया जा रहा है? – colllin

16

आप सामग्री-प्रकार शीर्षलेख को "एप्लिकेशन/जेसन" पर सेट करके इसे प्राप्त कर सकते हैं। आप नियंत्रक को यह बता सकते हैं कि स्वीकृति हेडर सेट के साथ "एप्लिकेशन/जेसन" पर वापस आने की क्या अपेक्षा है।

दोनों हेडर के साथ निम्न आदेश:

curl -d '{ "company": { "name": "acme", "address": "123 Carrot Street" } }' http://0.0.0.0:3000/mysite --header "Accept: application/json" --header "Content-Type: application/json" 

लॉग में यह उत्पन्न करता है:

curl -d '{ "company": { "name": "acme", "address": "123 Carrot Street" } }' http://0.0.0.0:3000/mysite --header "Accept: application/json" 

इन उत्पन्न करता है:

Started POST "/mysite" for 127.0.0.1 at 2012-01-11 16:09:48 -0800 
    Processing by MyController#create as JSON 
    Parameters: {"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "wassup"=>{"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "controller"=>"wassup", "action"=>"create"}} 
Completed 200 OK in 5ms (Views: 2.0ms | ActiveRecord: 0.0ms) 

स्वीकार हेडर के साथ यह आदेश लॉग:

Started POST "/mysite" for 127.0.0.1 at 2012-01-11 16:07:26 -0800 
    Processing by MyController#create as JSON 
    Parameters: {"{ \"company\": { \"name\": \"acme\", \"address\": \"123 Carrot Street\" } }"=>nil} 
Completed 200 OK in 7ms (Views: 5.0ms | ActiveRecord: 0.0ms) 

और अंत में Content-Type हैडर के साथ इस आदेश:

Started POST "/mysite" for 127.0.0.1 at 2012-01-11 16:08:11 -0800 
    Processing by MyController#create as */* 
    Parameters: {"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "wassup"=>{"company"=>{"name"=>"acme", "address"=>"123 Carrot Street"}, "controller"=>"wassup", "action"=>"create"}} 
Completed 200 OK in 4ms (Views: 2.0ms | ActiveRecord: 0.0ms) 

सूचना पार्स मापदंडों और प्रसंस्करण संदेश प्रत्येक के साथ परिवर्तन आसानी से:

curl -d '{ "company": { "name": "acme", "address": "123 Carrot Street" } }' http://0.0.0.0:3000/mysite --header "Content-Type: application/json" 

इन लॉग उत्पन्न करता है हेडर प्रकार।

+3

धन्यवाद आपके उत्तर के लिए इतना! दुर्भाग्यवश, XDomainRequest के साथ मेरे पास हेडर पर नियंत्रण नहीं है। (इस आलेख में आइटम 3 और 4 देखें (http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx)।) तो मैं लगता है कि यह शायद सही जवाब है, लेकिन मेरी समस्या को हल नहीं करता है। क्या आपको पता है कि नियंत्रक को यह बताने का कोई तरीका है कि सब कुछ एक JSON अनुरोध है? या कम से कम डिफ़ॉल्ट सामग्री-प्रकार JSON पर सेट करें? – colllin

+1

जेसन को params_parser.rb में पैराम्स सदस्य (रेल 3.1 में) में पार्स किया जाता है जिसमें एक्शनडिस्चैच :: पैराम्सपार्स होता है और यह मिडलवेयर का एक टुकड़ा है। आप मिडलवेयर का एक और टुकड़ा जोड़ सकते हैं जो आने वाले अनुरोध प्रकार का अनुमान लगाता है और इसे उचित रूप से सेट करता है। हालांकि, यदि आप ऐसा करने जा रहे हैं तो आप अपने विशेष कोड के लिए नियंत्रक में कुछ तर्क डाल सकते हैं और शेष मिडलवेयर स्टैक को बदल नहीं सकते हैं। – Grant

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