Περισσότερα
Πώς να περάσετε δεδομένα json POST στη μέθοδο Web API ως αντικείμενο;
Η εφαρμογή ASP.NET MVC4 Web API ορίζει τη μέθοδο post για την αποθήκευση του πελάτη. Ο πελάτης περνάει σε μορφή json στο σώμα της αίτησης POST. Η παράμετρος Customer στη μέθοδο post περιέχει μηδενικές τιμές για τις ιδιότητες.
Πώς να το διορθώσετε αυτό, ώστε τα δεδομένα της αποστολής να περάσουν ως αντικείμενο πελάτη ?
Εάν είναι δυνατόν, θα πρέπει να χρησιμοποιηθεί Content-Type: application/x-www-form-urlencoded, δεδομένου ότι δεν ξέρω πώς να το αλλάξω στη μέθοδο javascript που δημοσιεύει τη φόρμα.
Controller:
public class CustomersController : ApiController {
public object Post([FromBody] Customer customer)
{
return Request.CreateResponse(HttpStatusCode.OK,
new
{
customer = customer
});
}
}
}
public class Customer
{
public string company_name { get; set; }
public string contact_name { get; set; }
}
Αίτημα:
POST http://localhost:52216/api/customers HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
{"contact_name":"sdfsd","company_name":"ssssd"}
292
3
EDIT : 31/10/2017
Ο ίδιος κώδικας/προσέγγιση θα λειτουργήσει και για το Asp.Net Core 2.0. Η σημαντική διαφορά είναι, Στο asp.net core, τόσο οι ελεγκτές web api όσο και οι ελεγκτές Mvc συγχωνεύονται μαζί σε ένα ενιαίο μοντέλο ελεγκτή. Έτσι, ο τύπος επιστροφής σας μπορεί να είναι
IActionResult
ή μία από τις υλοποιήσεις του (π.χ.OkObjectResult
).Χρήση
Πρέπει να χρησιμοποιήσετε τη μέθοδο
JSON.stringify
για να το μετατρέψετε σε συμβολοσειρά JSON όταν το στέλνετε,Και το model binder θα δεσμεύσει τα δεδομένα json στο αντικείμενο της κλάσης σας.
Ο παρακάτω κώδικας θα λειτουργήσει μια χαρά (δοκιμασμένος)
Αποτέλεσμα
Η ιδιότητα
contentType
δηλώνει στο διακομιστή ότι στέλνουμε τα δεδομένα σε μορφή JSON. Εφόσον στείλαμε μια δομή δεδομένων JSON, η σύνδεση μοντέλου θα γίνει σωστά.Αν επιθεωρήσετε τις επικεφαλίδες του αιτήματος ajax's, μπορείτε να δείτε ότι η τιμή
Content-Type
έχει οριστεί ωςapplication/json
.Εάν δεν καθορίσετε ρητά το contentType, θα χρησιμοποιηθεί ο προεπιλεγμένος τύπος περιεχομένου που είναι
application/x-www-form-urlencoded;
Επεξεργασία τον Νοέμβριο 2015 για να αντιμετωπιστούν άλλα πιθανά ζητήματα που τέθηκαν στα σχόλια
Δημοσίευση σύνθετου αντικειμένου
Ας πούμε ότι έχετε μια σύνθετη κλάση μοντέλου προβολής ως παράμετρο της μεθόδου δράσης web api όπως αυτή
και το τελικό σημείο του web api σας είναι όπως
*Το ASP.NET MVC 6 είναι η τελευταία σταθερή έκδοση και στο MVC6, τόσο οι ελεγκτές Web api όσο και οι ελεγκτές MVC κληρονομούν από την κλάση βάσης
Microsoft.AspNet.Mvc.Controller
.Για να στείλετε δεδομένα στη μέθοδο από την πλευρά του πελάτη, ο παρακάτω κώδικας θα πρέπει να λειτουργεί κανονικά
Η δέσμευση μοντέλου λειτουργεί για ορισμένες ιδιότητες, αλλά όχι για όλες ! Γιατί;
Εάν δεν διακοσμήσετε την παράμετρο της μεθόδου web api με την ιδιότητα
[FromBody]
Και στέλνετε το μοντέλο (ακατέργαστο αντικείμενο javascript, όχι σε μορφή JSON) χωρίς να καθορίσετε την τιμή της ιδιότητας contentType
Η δέσμευση μοντέλου θα λειτουργήσει για τις επίπεδες ιδιότητες του μοντέλου, όχι για τις ιδιότητες όπου ο τύπος είναι σύνθετος/άλλος τύπος. Στην περίπτωσή μας, οι ιδιότητες
Id
καιName
θα δεσμευτούν σωστά στην παράμετροm
, αλλά η ιδιότηταTags
θα είναι μια κενή λίστα.Το ίδιο πρόβλημα θα εμφανιστεί αν χρησιμοποιείτε τη σύντομη έκδοση,
$.post
η οποία θα χρησιμοποιήσει το προεπιλεγμένο Content-Type κατά την αποστολή της αίτησης.Η εργασία με POST στο webapi μπορεί να είναι δύσκολη! Θα ήθελα να προσθέσω στην ήδη σωστή απάντηση ..
Θα επικεντρωθούμε ειδικά στο POST, καθώς η αντιμετώπιση του GET είναι τετριμμένη. Δεν νομίζω ότι πολλοί θα έψαχναν για την επίλυση ενός προβλήματος με το GET με το webapis. Εν πάση περιπτώσει...
Εάν η ερώτησή σας είναι - Σε MVC Web Api, πώς να - - Χρησιμοποιήστε προσαρμοσμένα ονόματα μεθόδων δράσης εκτός από τα γενικά ρήματα HTTP; - Να εκτελείτε πολλαπλές δημοσιεύσεις; - Να δημοσιεύετε πολλαπλούς απλούς τύπους; - Δημοσίευση σύνθετων τύπων μέσω jQuery;
Τότε οι παρακάτω λύσεις μπορεί να σας βοηθήσουν:
Πρώτον, για να χρησιμοποιήσετε Προσαρμοσμένες Μεθόδους δράσης στο Web API, προσθέστε μια διαδρομή web api ως εξής:
Και στη συνέχεια μπορείτε να δημιουργήσετε μεθόδους δράσης όπως:
Τώρα, πυροδοτήστε την ακόλουθη jQuery από την κονσόλα του προγράμματος περιήγησης
Δεύτερον, για να εκτελέσετε πολλαπλές δημοσιεύσεις, Είναι απλό, δημιουργήστε πολλαπλές μεθόδους δράσης και διακοσμήστε με το χαρακτηριστικό [HttpPost]. Χρησιμοποιήστε το [ActionName("MyAction")] για να εκχωρήσετε προσαρμοσμένα ονόματα κ.λπ. Θα αναφερθούμε στην jQuery στο τέταρτο σημείο παρακάτω.
Τρίτο, Πρώτα απ' όλα, η αποστολή πολλαπλών ΣΥΜΠΛΗΡΩΜΑΤΙΚΩΝ τύπων σε μία μόνο ενέργεια δεν είναι δυνατή. Επιπλέον, υπάρχει μια ειδική μορφή για την ανάρτηση ακόμη και ενός απλού τύπου (εκτός από το πέρασμα της παραμέτρου στο query string ή στο στυλ REST). Αυτό ήταν το σημείο που με έκανε να χτυπάω το κεφάλι μου με Rest Clients (όπως το Fiddler και το Chrome's Advanced REST client extension) και να κυνηγάω στο διαδίκτυο για σχεδόν 5 ώρες, όταν τελικά, το ακόλουθο URL αποδείχθηκε ότι βοήθησε. Θα παραθέσω το σχετικό περιεχόμενο γιατί ο σύνδεσμος μπορεί να αποδειχθεί νεκρός!
ΥΓ: Παρατηρήσατε την ιδιαίτερη σύνταξη;
http://forums.asp.net/t/1883467.aspx?The+received+value+is+null+when+I+try+to+Post+to+my+Web+Api
Τέλος πάντων, ας ξεπεράσουμε αυτή την ιστορία. Συνεχίζουμε:
Τέταρτον, η δημοσίευση σύνθετων τύπων μέσω της jQuery, φυσικά, η $.ajax() θα έρθει αμέσως στο ρόλο:
Ας πούμε ότι η μέθοδος action δέχεται ένα αντικείμενο Person το οποίο έχει ένα id και ένα όνομα. Έτσι, από javascript:
Και η ενέργεια θα μοιάζει με:
Όλα τα παραπάνω λειτούργησαν για μένα!! Στην υγειά μας!
Μόλις έπαιζα με αυτό και ανακάλυψα ένα μάλλον περίεργο αποτέλεσμα. Ας πούμε ότι έχετε δημόσιες ιδιότητες στην κλάση σας σε C# ως εξής:
τότε θα πρέπει να κάνετε το κόλπο JSON.stringify όπως προτείνει ο Shyju και να το καλέσετε ως εξής:
Ωστόσο, αν ορίσετε getters και setters στην κλάση σας ως εξής:
τότε μπορείτε να την καλέσετε πολύ πιο απλά:
Αυτό χρησιμοποιεί την επικεφαλίδα HTTP:
Δεν είμαι απόλυτα σίγουρος τι συμβαίνει εδώ, αλλά μοιάζει με σφάλμα (χαρακτηριστικό;) στο πλαίσιο. Πιθανότατα οι διαφορετικές μέθοδοι δέσμευσης καλούν διαφορετικούς "προσαρμογείς", και ενώ ο προσαρμογέας για application/json λειτουργεί με δημόσιες ιδιότητες, αυτός για δεδομένα κωδικοποιημένα με φόρμα δεν το κάνει'όχι.
Ωστόσο, δεν έχω ιδέα για το ποια θα θεωρούνταν βέλτιστη πρακτική.