Saya menyadari sesi dan REST tidak berjalan beriringan, tetapi apakah tidak mungkin untuk mengakses status sesi menggunakan Web API baru? HttpContext.Current.Session
selalu nol.
asp.net
asp.net-web-api
Menandai
sumber
sumber
[SessionState(SessionStateBehavior.Required)]
padaApiController
melakukan trik (atau.ReadOnly
jika perlu).Jawaban:
Untuk proyek MVC, lakukan perubahan berikut (WebForms dan Dot Net Core menjawab di bawah):
WebApiConfig.cs
Global.asax.cs
Solusi ini memiliki bonus tambahan yang dapat kami ambil dari URL dasar dalam javascript untuk melakukan panggilan AJAX:
_Layout.cshtml
dan kemudian dalam file / kode Javascript kami, kami dapat membuat panggilan webapi kami yang dapat mengakses sesi:
Lakukan hal di atas tetapi ubah fungsi WebApiConfig.Register untuk mengambil RouteCollection sebagai gantinya:
Dan kemudian panggil yang berikut di Application_Start:
Tambahkan paket NuGet Microsoft.AspNetCore.Session dan kemudian buat perubahan kode berikut:
Startup.cs
Panggil metode AddDistributedMemoryCache dan AddSession pada objek layanan di dalam fungsi ConfigureServices:
dan pada fungsi Konfigurasi tambahkan panggilan ke UseSession :
SessionController.cs
Di dalam controller Anda, tambahkan pernyataan menggunakan di atas:
dan kemudian gunakan objek HttpContext.Session dalam kode Anda seperti:
Anda sekarang dapat menekan:
dan kemudian pergi ke URL ini akan menariknya:
Banyak info lebih lanjut tentang mengakses data sesi dalam dot net core di sini: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state
Baca jawaban Simon Weaver di bawah ini tentang kinerja. Jika Anda mengakses data sesi di dalam proyek WebApi itu bisa memiliki konsekuensi kinerja yang sangat serius - Saya telah melihat ASP.NET memberlakukan penundaan 200 ms untuk permintaan bersamaan. Ini bisa bertambah dan menjadi bencana jika Anda memiliki banyak permintaan bersamaan.
Pastikan Anda mengunci sumber daya per pengguna - pengguna yang diautentikasi seharusnya tidak dapat mengambil data dari WebApi Anda yang tidak dapat mereka akses.
Baca artikel Microsoft tentang Otentikasi dan Otorisasi di ASP.NET Web API - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
Baca artikel Microsoft tentang menghindari serangan hack Pemalsuan Permintaan Situs Web. (Singkatnya, periksa metode AntiForgery.Validate) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
sumber
Anda dapat mengakses status sesi menggunakan RouteHandler khusus.
Ditemukan di sini: http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html
sumber
Mengapa menghindari menggunakan Sesi di WebAPI?
Kinerja, kinerja, kinerja!
Ada alasan yang sangat bagus, dan sering diabaikan mengapa Anda tidak harus menggunakan Sesi di WebAPI sama sekali.
Cara ASP.NET bekerja ketika Session sedang digunakan adalah untuk membuat cerita bersambung semua permintaan yang diterima dari satu klien . Sekarang saya tidak berbicara tentang serialisasi objek - tetapi menjalankannya dalam urutan yang diterima dan menunggu masing-masing untuk menyelesaikan sebelum menjalankan berikutnya. Ini untuk menghindari kondisi thread / ras yang tidak menyenangkan jika dua permintaan masing-masing mencoba mengakses Sesi secara bersamaan.
Jadi apa artinya ini untuk Web API? Jika Anda memiliki aplikasi yang menjalankan banyak permintaan AJAX maka hanya SATU yang akan dapat berjalan pada satu waktu. Jika Anda memiliki permintaan yang lebih lambat maka itu akan memblokir semua yang lain dari klien itu sampai selesai. Dalam beberapa aplikasi ini dapat menyebabkan kinerja yang sangat lambat.
Jadi Anda mungkin harus menggunakan pengontrol MVC jika Anda benar-benar membutuhkan sesuatu dari sesi pengguna dan menghindari hukuman kinerja yang tidak perlu untuk mengaktifkannya untuk WebApi.
Anda dapat dengan mudah menguji ini sendiri dengan hanya memasukkan
Thread.Sleep(5000)
metode WebAPI dan mengaktifkan Sesi. Jalankan 5 permintaan untuk itu dan mereka akan membutuhkan total 25 detik untuk menyelesaikannya. Tanpa Sesi mereka akan mengambil total lebih dari 5 detik.(Alasan yang sama ini berlaku untuk SignalR).
sumber
Ya, Anda benar, REST tidak memiliki kewarganegaraan. Jika Anda menggunakan sesi, pemrosesan akan menjadi stateful, permintaan berikutnya akan dapat menggunakan state (dari sesi).
Agar sesi dapat direhidrasi, Anda harus menyediakan kunci untuk mengaitkan negara. Dalam aplikasi asp.net normal, kunci tersebut disediakan dengan menggunakan cookie (sesi cookie) atau parameter url (sesi tanpa masak).
Jika Anda membutuhkan sesi, lupakan istirahat, sesi tidak relevan dalam desain berbasis REST. Jika Anda memerlukan sesi untuk validasi, gunakan token atau otorisasi berdasarkan alamat IP.
sumber
Mark, jika Anda memeriksa contoh MVC nerddinner logikanya hampir sama.
Anda hanya perlu mengambil cookie dan mengaturnya di sesi saat ini.
Global.asax.cs
Anda harus mendefinisikan kelas "SampleIdentity" Anda, yang dapat Anda pinjam dari proyek nerddinner .
sumber
Untuk memperbaiki masalah:
di Global.asax.cs
sumber
Yang terakhir tidak berfungsi sekarang, ambil yang ini, itu bekerja untuk saya.
di WebApiConfig.cs di App_Start
Global.asax
keempat di sini: http://forums.asp.net/t/1773026.aspx/1
sumber
Sebagai lanjutan dari jawaban LachlanB, jika ApiController Anda tidak berada dalam direktori tertentu (seperti / api), Anda bisa menguji permintaan menggunakan RouteTable.Routes.GetRouteData, misalnya:
sumber
Saya punya masalah yang sama di asp.net MVC, saya memperbaikinya dengan meletakkan metode ini di basis api controller saya bahwa semua pengendali api saya mewarisi dari:
Kemudian dalam panggilan api Anda bahwa Anda ingin mengakses sesi yang baru saja Anda lakukan:
Saya juga punya ini di file Global.asax.cs saya seperti orang lain telah diposting, tidak yakin apakah Anda masih membutuhkannya menggunakan metode di atas, tetapi ini dia hanya dalam kasus:
Anda juga bisa membuat atribut filter khusus yang dapat Anda tempel di panggilan api yang Anda butuhkan sesi, kemudian Anda bisa menggunakan sesi dalam panggilan api Anda seperti yang biasa Anda lakukan melalui HttpContext.Current.Session ["SomeValue"]:
Semoga ini membantu.
sumber
Saya mengikuti pendekatan @LachlanB dan memang sesi itu tersedia ketika cookie sesi hadir atas permintaan. Bagian yang hilang adalah bagaimana cookie Sesi dikirim ke klien pertama kali?
Saya membuat HttpModule yang tidak hanya mengaktifkan ketersediaan HttpSessionState tetapi juga mengirimkan cookie ke klien ketika sesi baru dibuat.
sumber
satu hal yang perlu disebutkan pada jawaban @LachlanB.
Jika Anda menghilangkan garis
if (IsWebApiRequest())
Seluruh situs akan memiliki masalah kelambatan pemuatan halaman jika situs Anda dicampur dengan halaman formulir web.
sumber
Ya, sesi tidak berjalan seiring dengan API Istirahat dan juga kita harus menghindari praktik ini. Tetapi sesuai persyaratan kita perlu mempertahankan sesi entah bagaimana sehingga dalam setiap permintaan, klien dapat bertukar atau mempertahankan status atau data. Jadi, cara terbaik untuk mencapai ini tanpa melanggar protokol REST adalah berkomunikasi melalui token seperti JWT.
https://jwt.io/
sumber
Kembali ke dasar mengapa tidak membuatnya sederhana dan menyimpan nilai Sesi dalam nilai html tersembunyi untuk diteruskan ke API Anda?
Pengendali
cshtml
Javascript
$ (dokumen) .ready (function () {
}
sumber