Sejak memutakhirkan ke RC untuk WebAPI, saya mengalami masalah aneh saat memanggil POST di WebAPI saya. Saya bahkan sudah kembali ke versi dasar yang dihasilkan pada proyek baru. Begitu:
public void Post(string value)
{
}
dan menelepon dari Fiddler:
Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29
Body:
{
"value": "test"
}
Saat saya debug, string "nilai" tidak pernah ditugaskan. Itu selalu NULL. Adakah yang mengalami masalah ini?
(Saya pertama kali melihat masalah dengan jenis yang lebih kompleks)
Masalahnya tidak hanya terikat pada ASP.NET MVC 4, masalah yang sama terjadi untuk proyek ASP.NET MVC 3 baru setelah instalasi RC
c#
.net
asp.net-web-api
asp.net-web-api-routing
tulang ianrath
sumber
sumber
Jawaban:
Karena Anda hanya memiliki satu parameter, Anda dapat mencoba mendekorasi dengan
[FromBody]
atribut, atau mengubah metode untuk menerima DTO dengan nilai sebagai properti, seperti yang saya sarankan di sini: MVC4 RC WebApi mengikat parameterUPDATE: Situs resmi ASP.NET diperbarui hari ini dengan penjelasan yang sangat baik: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 1
Singkatnya, saat mengirim satu tipe sederhana dalam isi, kirimkan nilai yang diawali dengan tanda sama dengan (=), mis. Isi:
=test
sumber
=
di depan tidak pernah bekerja untuk saya, sampai saya mengikuti saran Jim dalam komentarnya (bukan sebagai objek JSON) dan berhasil. Ini kuncinya! Saya benar-benar tidak suka pilih-pilih WebAPI.:(
). Anda harus benar-benar menambahkan dukungan untuk format yang diharapkan orang untuk menerima.Saya telah menggaruk kepala saya hari ini.
Solusi saya adalah mengubah
[FromBody]
ke aHttpRequestMessage
, pada dasarnya bergerak naik tumpukan HTTP.Dalam kasus saya, saya mengirim data melalui kawat yang zip json yang kemudian base64. Semua ini dari aplikasi android.
Tanda tangan asli dari titik akhir web saya terlihat seperti ini (menggunakan
[FromBody]
):Perbaikan saya untuk masalah ini adalah kembali menggunakan
HttpRequestMessage
tanda tangan titik akhir saya.Anda kemudian bisa mendapatkan akses ke data posting menggunakan baris kode ini:
Ini berfungsi dan memungkinkan Anda akses ke data kiriman mentah yang tidak tersentuh. Anda tidak perlu dipusingkan dengan fiddler menempatkan tanda = di awal string Anda atau mengubah tipe konten.
Sebagai tambahan, saya pertama kali mencoba mengikuti salah satu jawaban di atas yang mengubah tipe konten menjadi: "Tipe-Konten: application / x-www-form-urlencoded". Untuk data mentah, ini adalah saran buruk karena menghapus + karakter.
Jadi string base64 yang dimulai seperti ini: "MQ0AAB + LCAAAAAA" berakhir seperti ini "MQ0AAB LCAAAAAA"! Bukan apa yang kamu inginkan.
Manfaat lain menggunakan
HttpRequestMessage
adalah bahwa Anda mendapatkan akses ke semua header http dari dalam titik akhir Anda.sumber
HttpRequestMessage request
dalam metode tanda tangan, karena Anda sudah memiliki ini. Dalam tubuh metode itu dapat diakses padaRequest
objek. misalnyaRequest.Content.ReadAsStringAsync().Result;
Saya baru saja mengalami ini menggunakan Fiddler. Masalahnya adalah bahwa saya belum menentukan
Content-Type
.Coba sertakan tajuk untuk
Content-Type
permintaan POST Anda.Atau, sesuai komentar di bawah ini, Anda mungkin perlu menyertakan header JSON
sumber
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
, untuk contoh lengkap lihat Lengkap Cient dan ServerSaya juga mengalami masalah ini, dan inilah cara saya memecahkan masalah saya
kode webapi:
kode klien:
sumber
some value
, maka itudata
adalah nol.Saya menggunakan
Postman
dan saya melakukan kesalahan yang sama .. melewati objekvalue
sebagai json, bukan stringJelas yang di atas salah ketika parameter api bertipe string.
Jadi, cukup masukkan string dengan tanda kutip ganda di badan api:
sumber
JSON.stringify
itu menyebabkan saya[frombody]
menjadinull
. Setelah menyetel bidang data ke nilai string (yaitu string json) itu berhasil.Coba buat kelas untuk dijadikan model data, lalu kirim objek JSON dengan properti yang cocok dengan properti kelas model data Anda. (Catatan: Saya telah menguji ini dan berfungsi dengan MVC 4 RC 2012 terbaru yang baru saja saya unduh hari ini).
Objek JSON di bawah ini dikirim dalam tubuh HTTP-POST, tipe konten adalah aplikasi / json
Saya percaya alasan mengapa Anda harus membuat kelas model data adalah karena nilai-nilai sederhana diasumsikan dari parameter url, dan nilai kompleks tunggal diasumsikan berasal dari tubuh. Mereka memang memiliki atribut
[FromBody]
dan[FromUrl]
, tetapi menggunakan[FromBody] string value
masih tidak bekerja untuk saya. Sepertinya mereka masih mengerjakan banyak bug jadi saya yakin ini akan berubah di masa depan.Sunting: Punya XML untuk bekerja di dalam tubuh. Serializer XML default diubah menjadi DataContractSerializer alih-alih XmlSerializer. Menempatkan baris berikut di file Global.asax saya memperbaiki masalah ini ( referensi )
sumber
Setelah beberapa kali mencoba, saya pikir perilaku default sudah benar dan tidak ada yang perlu diretas.
Satu-satunya trik adalah: jika argumen metode posting Anda
string
seperti di bawah ini, Anda harus mengirim string polos dengan tanda kutip ganda di tubuh (ketika menggunakan ajax atau tukang pos), misalnya,Kalau tidak, jika Anda mengirim string json di badan pos tanpa tanda kutip luar ganda dan lolos dalam tanda kutip, maka itu harus dapat diuraikan ke kelas model (tipe argumen), misalnya,
{"a":1, "b":2}
sumber
Saya sedang mencari solusi untuk masalah ini selama beberapa menit sekarang, jadi saya akan membagikan solusi saya.
Jika Anda memposting model, model Anda harus memiliki konstruktor kosong / default, jika tidak, model tersebut tidak dapat dibuat. Hati-hati saat melakukan refactoring. ;)
sumber
Ini bekerja untuk saya:
Buat kelas C # DTO, dengan properti untuk setiap atribut yang ingin Anda lewati dari jQuery / Ajax
Tentukan metode api web:
Panggil api web seperti itu:
sumber
Bagi mereka yang memiliki masalah yang sama dengan Swagger atau Postman seperti yang saya lakukan, jika Anda melewatkan atribut sederhana sebagai string dalam posting, bahkan dengan "ContentType" yang ditentukan, Anda masih akan mendapatkan nilai nol.
Lulus saja:
Nilai Saya
Akan masuk controller sebagai null.
Tetapi jika Anda lulus:
"Nilai Saya"
Nilainya akan menjadi benar.
Kutipan membuat perbedaan di sini. Tentu saja, ini hanya untuk Swagger dan Postman. Misalnya, dalam aplikasi Frontend menggunakan Angular ini harus diselesaikan oleh kerangka kerja secara otomatis.
sumber
Saya memiliki masalah yang sama dan menemukan bahwa ketika mengubah Tipe Konten menjadi "application / json" tidak memperbaiki masalah. Namun "application / json; charset = utf-8" berfungsi.
sumber
Saya memiliki masalah serupa di mana objek permintaan untuk metode API Web saya selalu nol. Saya perhatikan bahwa karena nama tindakan pengontrol diawali dengan "Get", Web API memperlakukan ini sebagai GET HTTP daripada POST. Setelah mengganti nama tindakan pengontrol, sekarang berfungsi sebagaimana dimaksud.
sumber
Dengan Angular, saya dapat meneruskan data dalam format ini:
Dan di Pengontrol API Web:
Atau, saya juga bisa memposting data JSON seperti ini:
Dan, di controller, terima tipe kelas seperti ini:
Apa pun cara kerjanya, jika Anda memiliki kelas publik yang mapan di API kemudian memposting JSON, jika tidak posting '=' + JSON.stringify ({..: ..., ..: ...})
sumber
Dalam kasus saya masalahnya adalah bahwa parameternya adalah string dan bukan objek, saya mengubah parameter menjadi JObject dari Newsoft.Json dan berfungsi.
sumber
Menambahkan baris
sampai akhir fungsi
protected void Application_Start()
di Global.asax.cs memperbaiki masalah serupa untuk saya di ASP.NET MVC3.sumber
Jika Anda menggunakan DataContractSerializer untuk Xter Formatter atau JSON Formatter, Anda harus menyingkirkannya. Saya memiliki ini di file WebApiConfig saya:
Cukup saya komentari
jsonFormatter.UseDataContractJsonSerializer = true;
dan parameter input saya bukan nol lagi. Terima kasih kepada 'Despertar' karena memberi saya petunjuk.sumber
Jika Anda yakin tentang JSON yang Anda kirim maka Anda harus melacak API Anda dengan cermat:
Microsoft.AspNet.WebApi.Tracing
paketconfig.EnableSystemDiagnosticsTracing();
metodeWebApiConfig
class insideRegister
.Sekarang lihat output Debug dan Anda mungkin akan menemukan tidak valid
ModelState
entri log yang .Jika
ModelState
tidak valid Anda dapat menemukan penyebab sebenarnya diErrors
:Tidak ada yang bisa menebak pengecualian seperti ini:
sumber
Saya memiliki masalah yang sama untuk mendapatkan null sebagai parameter, tetapi itu terkait dengan objek besar. Ternyata masalah itu terkait dengan panjang max IIS. Ini dapat dikonfigurasi di web.config.
Saya bertanya-tanya mengapa Web API menekan kesalahan dan mengirim objek nol ke API saya. Saya menemukan kesalahan menggunakan Microsoft.AspNet.WebApi.Tracing.
sumber
JSON.stringify (...) menyelesaikan masalah saya
sumber
Saya tahu ini bukan jawaban untuk pertanyaan ini, tetapi saya menemukan jawabannya ketika mencari solusi untuk masalah saya.
Dalam kasus saya, tipe kompleks tidak terikat tetapi saya tidak melakukan POST, saya melakukan GET dengan parameter querystring. Solusinya adalah menambahkan [FromUri] ke arg:
sumber
Saya memiliki masalah yang sama di Fiddler. Saya sudah memiliki
Content-Type: application/json; charset=utf-8
atauContent-Type: application/json
di header permintaan.Permintaan tubuh saya juga string biasa, dan di Fiddler saya telah menulis:
{'controller':'ctrl'}
. Ini membuat parameter string dalam metode POST saya menjadinull
.Perbaiki : ingat untuk menggunakan tanda kutip, dengan demikian menunjukkan string. Yaitu, saya memperbaikinya dengan menulis
"{'controller':'ctrl'}"
. (Catatan: saat menulis JSON, pastikan untuk menggunakan tanda kutip atau luput dari tanda kutip seperti ini"{\"controller\":\"ctrl\"}"
:).sumber
Cara paling sederhana yang saya temukan untuk berurusan dengan objek JSON sederhana yang saya berikan ke MVC 6 adalah mendapatkan jenis parameter posting seperti NewtonSoft jObject:
sumber
[FromBody] object body, [FromHeader(Name="Content-Type")] string bodyMediaType
) dapat bekerja lebih baik karena memeriksabodyMediaType == "application.json"
sebelum casting body ke JObject memberikan kesempatan untuk alternatif.Solusi terbaik bagi saya adalah HTTP penuh seperti di bawah ini:
dan kemudian deserializing string ke objek yang Anda harapkan di post body. Bagi saya, WS_OpenSession adalah kelas yang berisi sessionid, pengguna, dan kunci.
Anda dapat dari sana menggunakan objek param dan mengakses propertinya.
Sangat sangat efektif.
Saya memang mengatakan bersumber dari url ini:
http://bizcoder.com/posting-raw-json-to-web-api
sumber
Untuk tipe yang kompleks, API Web mencoba membaca nilai dari badan pesan, menggunakan formatter tipe media.
Periksa apakah Anda memiliki
[Serializable]
atribut apa pun yang menghiasi kelas model Anda.Hapus atribut untuk melihat apakah itu berfungsi. Ini berhasil untuk saya.
sumber
Saya sedikit terlambat ke pesta, tetapi siapa pun yang menemukan nilai NULL yang lulus saat menggunakan pengontrol cukup menambahkan "=" ke bagian depan permintaan POST Anda.
Kontroler juga memberikan nilai NULL ketika saya menggunakan aplikasi / json Content-Type. Perhatikan Konten-Jenis "application / x-www-form-urlencoded" di bawah ini. Namun tipe pengembalian dari API adalah "application / json".
sumber
tidak masalah apa jenis nilai yang ingin Anda posting, cukup sertakan dalam tanda kutip, untuk mendapatkannya sebagai string. Bukan untuk tipe yang kompleks.
javascript:
c #:
sumber
Jika Anda menempatkan anotasi [FromBody] dan Anda memiliki objek Dto sebagai parameter untuk metode Anda dan masih tidak bisa mendapatkan data melalui, mulai mencari ke properti dan bidang DTO Anda.
Saya memiliki masalah yang sama, di mana DTO saya menjadi nol. Saya menemukan alasannya adalah bahwa salah satu properti menunjuk ke sebuah objek yang tidak dapat diserialisasi :( yang menyebabkan media-formatter gagal mem-parsing data. Dengan demikian objek itu selalu nol. Semoga ini membantu orang lain juga
sumber
Periksa kembali tipe data Anda. Pengikat model dotnet tidak akan mengkonversi float ke integer (dan saya mengasumsikan konsep terkait lainnya). Ini akan menyebabkan seluruh model ditolak.
Jika Anda memiliki json seperti ini:
tetapi model c # Anda terlihat seperti ini:
pengikat model akan menolak model dan Anda akan mendapatkan nol.
sumber
Saya sangat terlambat dalam hal ini tetapi mengalami masalah yang serupa dan setelah seharian melalui banyak jawaban di sini dan mendapatkan latar belakang, saya telah menemukan solusi termudah / ringan untuk mengembalikan satu atau lebih parameter ke Web API 2 Action. berikut:
Ini mengasumsikan bahwa Anda tahu cara menyiapkan pengontrol / tindakan Web API dengan perutean yang benar, jika tidak merujuk ke: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-web-api / tutorial-web-api-pertama Anda .
Pertama Aksi Pengendali, solusi ini juga memerlukan pustaka Newtonsoft.Json.
Sisi Klien menggunakan jQuery
Masalah utama yang saya temukan adalah memastikan Anda hanya mengirim satu parameter keseluruhan kembali ke Web API dan memastikan tidak memiliki nama hanya nilai,
{ '': dataToSend }
jika tidak, nilai Anda akan nol di sisi server.Dengan ini, Anda dapat mengirim satu atau banyak parameter ke API Web dalam struktur JSON dan Anda tidak perlu mendeklarasikan sisi server objek tambahan untuk menangani data yang kompleks. JObject juga memungkinkan Anda untuk beralih secara dinamis atas semua parameter yang diteruskan sehingga memungkinkan skalabilitas yang lebih mudah jika parameter Anda berubah seiring waktu. Semoga itu membantu seseorang yang sedang berjuang seperti saya.
sumber
Benar melewati parameter tunggal dalam tubuh ke WebAPI bekerja kode ini
$.post(url, { '': productId }
Dan menangkapnya dalam aksi
[HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)
Kuncinya adalah menggunakan kata ajaib 'nilai'. Mungkin juga int, atau tipe primitif. Tidak masalah apapun jenis konten atau koreksi tajuk Mess adalah bahwa kode ini tidak berfungsi dalam tindakan posting mvc.
sumber